mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 15:13:08 +00:00
wasm-linker: Fix relocations for alias'd atoms
When an atom has one or multiple aliasses, we we could not find the target atom from the alias'd symbol. This is solved by ensuring that we also insert each alias symbol in the symbol-atom map.
This commit is contained in:
parent
2a62dbda0b
commit
dd85092982
@ -1568,9 +1568,13 @@ fn allocateAtoms(wasm: *Wasm) !void {
|
||||
var atom: *Atom = entry.value_ptr.*.getFirst();
|
||||
var offset: u32 = 0;
|
||||
while (true) {
|
||||
const symbol_loc = atom.symbolLoc();
|
||||
if (!wasm.resolved_symbols.contains(symbol_loc)) {
|
||||
atom = atom.next orelse break;
|
||||
continue;
|
||||
}
|
||||
offset = std.mem.alignForwardGeneric(u32, offset, atom.alignment);
|
||||
atom.offset = offset;
|
||||
const symbol_loc = atom.symbolLoc();
|
||||
log.debug("Atom '{s}' allocated from 0x{x:0>8} to 0x{x:0>8} size={d}", .{
|
||||
symbol_loc.getName(wasm),
|
||||
offset,
|
||||
@ -1578,7 +1582,7 @@ fn allocateAtoms(wasm: *Wasm) !void {
|
||||
atom.size,
|
||||
});
|
||||
offset += atom.size;
|
||||
try wasm.symbol_atom.put(wasm.base.allocator, atom.symbolLoc(), atom); // Update atom pointers
|
||||
try wasm.symbol_atom.put(wasm.base.allocator, symbol_loc, atom); // Update atom pointers
|
||||
atom = atom.next orelse break;
|
||||
}
|
||||
segment.size = std.mem.alignForwardGeneric(u32, offset, segment.alignment);
|
||||
@ -2579,14 +2583,16 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
|
||||
var atom: *Atom = wasm.atoms.get(code_index).?.getFirst();
|
||||
|
||||
// The code section must be sorted in line with the function order.
|
||||
var sorted_atoms = try std.ArrayList(*Atom).initCapacity(wasm.base.allocator, wasm.functions.count());
|
||||
var sorted_atoms = try std.ArrayList(*Atom).initCapacity(gpa, wasm.functions.count());
|
||||
defer sorted_atoms.deinit();
|
||||
|
||||
while (true) {
|
||||
if (!is_obj) {
|
||||
atom.resolveRelocs(wasm);
|
||||
if (wasm.resolved_symbols.contains(atom.symbolLoc())) {
|
||||
if (!is_obj) {
|
||||
atom.resolveRelocs(wasm);
|
||||
}
|
||||
sorted_atoms.appendAssumeCapacity(atom);
|
||||
}
|
||||
sorted_atoms.appendAssumeCapacity(atom);
|
||||
atom = atom.next orelse break;
|
||||
}
|
||||
|
||||
@ -2641,6 +2647,10 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
|
||||
// fill in the offset table and the data segments
|
||||
var current_offset: u32 = 0;
|
||||
while (true) {
|
||||
if (!wasm.resolved_symbols.contains(atom.symbolLoc())) {
|
||||
atom = atom.next orelse break;
|
||||
continue;
|
||||
}
|
||||
if (!is_obj) {
|
||||
atom.resolveRelocs(wasm);
|
||||
}
|
||||
@ -4170,15 +4180,23 @@ fn emitDataRelocations(
|
||||
try writeCustomSectionHeader(binary_bytes.items, header_offset, size);
|
||||
}
|
||||
|
||||
/// Searches for an a matching function signature, when not found
|
||||
/// a new entry will be made. The index of the existing/new signature will be returned.
|
||||
pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
|
||||
pub fn getTypeIndex(wasm: *const Wasm, func_type: std.wasm.Type) ?u32 {
|
||||
var index: u32 = 0;
|
||||
while (index < wasm.func_types.items.len) : (index += 1) {
|
||||
if (wasm.func_types.items[index].eql(func_type)) return index;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Searches for an a matching function signature, when not found
|
||||
/// a new entry will be made. The index of the existing/new signature will be returned.
|
||||
pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
|
||||
if (wasm.getTypeIndex(func_type)) |index| {
|
||||
return index;
|
||||
}
|
||||
|
||||
// functype does not exist.
|
||||
const index = @intCast(u32, wasm.func_types.items.len);
|
||||
const params = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.params);
|
||||
errdefer wasm.base.allocator.free(params);
|
||||
const returns = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.returns);
|
||||
|
||||
@ -186,7 +186,11 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
|
||||
.R_WASM_MEMORY_ADDR_SLEB,
|
||||
.R_WASM_MEMORY_ADDR_SLEB64,
|
||||
=> {
|
||||
std.debug.assert(symbol.tag == .data and !symbol.isUndefined());
|
||||
std.debug.assert(symbol.tag == .data);
|
||||
if (symbol.isUndefined()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const merge_segment = wasm_bin.base.options.output_mode != .Obj;
|
||||
const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
|
||||
const segment_info = if (target_atom.file) |object_index| blk: {
|
||||
|
||||
@ -923,7 +923,7 @@ pub fn parseIntoAtoms(object: *Object, gpa: Allocator, object_index: u16, wasm_b
|
||||
try atom.relocs.append(gpa, reloc);
|
||||
|
||||
if (relocation.isTableIndex()) {
|
||||
try wasm_bin.function_table.putNoClobber(gpa, .{
|
||||
try wasm_bin.function_table.put(gpa, .{
|
||||
.file = object_index,
|
||||
.index = relocation.index,
|
||||
}, 0);
|
||||
@ -938,17 +938,17 @@ pub fn parseIntoAtoms(object: *Object, gpa: Allocator, object_index: u16, wasm_b
|
||||
.index = relocatable_data.getIndex(),
|
||||
})) |symbols| {
|
||||
atom.sym_index = symbols.pop();
|
||||
try wasm_bin.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom);
|
||||
|
||||
// symbols referencing the same atom will be added as alias
|
||||
// or as 'parent' when they are global.
|
||||
while (symbols.popOrNull()) |idx| {
|
||||
try wasm_bin.symbol_atom.putNoClobber(gpa, .{ .file = atom.file, .index = idx }, atom);
|
||||
const alias_symbol = object.symtable[idx];
|
||||
const symbol = object.symtable[atom.sym_index];
|
||||
if (alias_symbol.isGlobal() and symbol.isLocal()) {
|
||||
if (alias_symbol.isGlobal()) {
|
||||
atom.sym_index = idx;
|
||||
}
|
||||
}
|
||||
try wasm_bin.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom);
|
||||
}
|
||||
|
||||
const segment: *Wasm.Segment = &wasm_bin.segments.items[final_index];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user