mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
wasm linker: fix relocation parsing
This commit is contained in:
parent
9cd7cad42e
commit
4b9dc2922f
@ -1955,6 +1955,8 @@ pub const ObjectRelocation = struct {
|
||||
symbol_name: String,
|
||||
type_index: FunctionType.Index,
|
||||
section: ObjectSectionIndex,
|
||||
data_segment: ObjectDataSegmentIndex,
|
||||
function: Wasm.ObjectFunctionIndex,
|
||||
};
|
||||
|
||||
pub const Slice = extern struct {
|
||||
@ -1968,14 +1970,17 @@ pub const ObjectRelocation = struct {
|
||||
};
|
||||
|
||||
pub const Tag = enum(u8) {
|
||||
/// Uses `symbol_name`.
|
||||
/// Uses `function`.
|
||||
FUNCTION_INDEX_LEB = 0,
|
||||
/// Uses `table_index`.
|
||||
TABLE_INDEX_SLEB = 1,
|
||||
/// Uses `table_index`.
|
||||
TABLE_INDEX_I32 = 2,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_LEB = 3,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_SLEB = 4,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_I32 = 5,
|
||||
/// Uses `type_index`.
|
||||
TYPE_INDEX_LEB = 6,
|
||||
@ -1984,23 +1989,31 @@ pub const ObjectRelocation = struct {
|
||||
FUNCTION_OFFSET_I32 = 8,
|
||||
SECTION_OFFSET_I32 = 9,
|
||||
TAG_INDEX_LEB = 10,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_REL_SLEB = 11,
|
||||
TABLE_INDEX_REL_SLEB = 12,
|
||||
/// Uses `symbol_name`.
|
||||
GLOBAL_INDEX_I32 = 13,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_LEB64 = 14,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_SLEB64 = 15,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_I64 = 16,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_REL_SLEB64 = 17,
|
||||
/// Uses `table_index`.
|
||||
TABLE_INDEX_SLEB64 = 18,
|
||||
/// Uses `table_index`.
|
||||
TABLE_INDEX_I64 = 19,
|
||||
TABLE_NUMBER_LEB = 20,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_TLS_SLEB = 21,
|
||||
FUNCTION_OFFSET_I64 = 22,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_LOCREL_I32 = 23,
|
||||
TABLE_INDEX_REL_SLEB64 = 24,
|
||||
/// Uses `data_segment`.
|
||||
MEMORY_ADDR_TLS_SLEB64 = 25,
|
||||
/// Uses `symbol_name`.
|
||||
FUNCTION_INDEX_I32 = 26,
|
||||
@ -2282,6 +2295,7 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void {
|
||||
}
|
||||
|
||||
fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void {
|
||||
log.debug("parseObject {}", .{obj.path});
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
const gc_sections = wasm.base.gc_sections;
|
||||
|
||||
@ -2305,6 +2319,7 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void {
|
||||
}
|
||||
|
||||
fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void {
|
||||
log.debug("parseArchive {}", .{obj.path});
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
const gc_sections = wasm.base.gc_sections;
|
||||
|
||||
@ -2567,7 +2582,9 @@ pub fn loadInput(wasm: *Wasm, input: link.Input) !void {
|
||||
.res => unreachable,
|
||||
.dso_exact => unreachable,
|
||||
.dso => unreachable,
|
||||
.object, .archive => |obj| try argv.append(gpa, try obj.path.toString(comp.arena)),
|
||||
.object, .archive => |obj| {
|
||||
try argv.append(gpa, try obj.path.toString(comp.arena));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ pub const ScratchSpace = struct {
|
||||
const FuncImportIndex = enum(u32) {
|
||||
_,
|
||||
|
||||
fn ptr(index: FunctionImport, ss: *const ScratchSpace) *FunctionImport {
|
||||
fn ptr(index: FuncImportIndex, ss: *const ScratchSpace) *FunctionImport {
|
||||
return &ss.func_imports.items[@intFromEnum(index)];
|
||||
}
|
||||
};
|
||||
@ -351,10 +351,13 @@ pub fn parse(
|
||||
.function => {
|
||||
const local_index, pos = readLeb(u32, bytes, pos);
|
||||
if (symbol.flags.undefined) {
|
||||
symbol.pointee = .{ .function_import = @enumFromInt(local_index) };
|
||||
const function_import: ScratchSpace.FuncImportIndex = @enumFromInt(local_index);
|
||||
symbol.pointee = .{ .function_import = function_import };
|
||||
if (symbol.flags.explicit_name) {
|
||||
const name, pos = readBytes(bytes, pos);
|
||||
symbol.name = (try wasm.internString(name)).toOptional();
|
||||
} else {
|
||||
symbol.name = function_import.ptr(ss).name.toOptional();
|
||||
}
|
||||
} else {
|
||||
symbol.pointee = .{ .function = @enumFromInt(functions_start + local_index) };
|
||||
@ -365,10 +368,13 @@ pub fn parse(
|
||||
.global => {
|
||||
const local_index, pos = readLeb(u32, bytes, pos);
|
||||
if (symbol.flags.undefined) {
|
||||
symbol.pointee = .{ .global_import = @enumFromInt(global_imports_start + local_index) };
|
||||
const global_import: Wasm.GlobalImport.Index = @enumFromInt(global_imports_start + local_index);
|
||||
symbol.pointee = .{ .global_import = global_import };
|
||||
if (symbol.flags.explicit_name) {
|
||||
const name, pos = readBytes(bytes, pos);
|
||||
symbol.name = (try wasm.internString(name)).toOptional();
|
||||
} else {
|
||||
symbol.name = global_import.key(wasm).toOptional();
|
||||
}
|
||||
} else {
|
||||
symbol.pointee = .{ .global = @enumFromInt(globals_start + local_index) };
|
||||
@ -380,10 +386,13 @@ pub fn parse(
|
||||
table_count += 1;
|
||||
const local_index, pos = readLeb(u32, bytes, pos);
|
||||
if (symbol.flags.undefined) {
|
||||
symbol.pointee = .{ .table_import = @enumFromInt(table_imports_start + local_index) };
|
||||
const table_import: Wasm.TableImport.Index = @enumFromInt(table_imports_start + local_index);
|
||||
symbol.pointee = .{ .table_import = table_import };
|
||||
if (symbol.flags.explicit_name) {
|
||||
const name, pos = readBytes(bytes, pos);
|
||||
symbol.name = (try wasm.internString(name)).toOptional();
|
||||
} else {
|
||||
symbol.name = table_import.key(wasm).toOptional();
|
||||
}
|
||||
} else {
|
||||
symbol.pointee = .{ .table = @enumFromInt(tables_start + local_index) };
|
||||
@ -439,10 +448,39 @@ pub fn parse(
|
||||
.MEMORY_ADDR_TLS_SLEB,
|
||||
.MEMORY_ADDR_LOCREL_I32,
|
||||
.MEMORY_ADDR_TLS_SLEB64,
|
||||
=> {
|
||||
const addend: i32, pos = readLeb(i32, bytes, pos);
|
||||
const sym_section = ss.symbol_table.items[index].pointee.data;
|
||||
if (sym_section.segment_offset != 0) {
|
||||
return diags.failParse(path, "data symbol {d} has nonzero offset {d}", .{
|
||||
index, sym_section.segment_offset,
|
||||
});
|
||||
}
|
||||
const seg_size = sym_section.segment_index.ptr(wasm).payload.len;
|
||||
if (sym_section.size != seg_size) {
|
||||
return diags.failParse(path, "data symbol {d} has size {d}, inequal to corresponding data segment {d} size {d}", .{
|
||||
index, sym_section.size, @intFromEnum(sym_section.segment_index), seg_size,
|
||||
});
|
||||
}
|
||||
wasm.object_relocations.appendAssumeCapacity(.{
|
||||
.tag = tag,
|
||||
.offset = offset,
|
||||
.pointee = .{ .data_segment = sym_section.segment_index },
|
||||
.addend = addend,
|
||||
});
|
||||
},
|
||||
.FUNCTION_OFFSET_I32,
|
||||
.SECTION_OFFSET_I32,
|
||||
.FUNCTION_OFFSET_I64,
|
||||
=> {
|
||||
const addend: i32, pos = readLeb(i32, bytes, pos);
|
||||
wasm.object_relocations.appendAssumeCapacity(.{
|
||||
.tag = tag,
|
||||
.offset = offset,
|
||||
.pointee = .{ .function = ss.symbol_table.items[index].pointee.function },
|
||||
.addend = addend,
|
||||
});
|
||||
},
|
||||
.SECTION_OFFSET_I32 => {
|
||||
const addend: i32, pos = readLeb(i32, bytes, pos);
|
||||
wasm.object_relocations.appendAssumeCapacity(.{
|
||||
.tag = tag,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user