diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-02-21 21:43:38 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-02-23 16:07:36 +0100 |
| commit | acec06cfaf9a82ec8037a23993ff36fa72eb6e82 (patch) | |
| tree | 6fbabbcf1bedaf2b46ee42c170f187c2a34648f5 /src/arch | |
| parent | 0a48a763fd3548a7b8609555cecbafc21ebe1fc3 (diff) | |
| download | zig-acec06cfaf9a82ec8037a23993ff36fa72eb6e82.tar.gz zig-acec06cfaf9a82ec8037a23993ff36fa72eb6e82.zip | |
wasm-linker: Implement `updateDeclExports`
We now correctly implement exporting decls. This means it is possible to export
a decl with a different name than the decl that is doing the export.
This also sets the symbols with the correct flags, so when we emit a relocatable
object file, a linker can correctly resolve symbols and/or export the symbol to the host environment.
This commit also includes fixes to ensure relocations have the correct offset to how other
linkers will expect the offset, rather than what we use internally.
Other linkers accept the offset, relative to the section.
Internally we use an offset relative to the atom.
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 20 | ||||
| -rw-r--r-- | src/arch/wasm/Emit.zig | 39 |
2 files changed, 35 insertions, 24 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index b776f30346..1fb7fc0e2f 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1320,14 +1320,18 @@ pub const DeclGen = struct { } decl.markAlive(); - try writer.writeIntLittle(u32, try self.bin_file.getDeclVAddr( - self.decl, // The decl containing the source symbol index - decl.ty, // type we generate the address of - self.symbol_index, // source symbol index - decl.link.wasm.sym_index, // target symbol index - @intCast(u32, self.code.items.len), // offset - @intCast(u32, offset), // addend - )); + if (decl.link.wasm.sym_index == 0) { + try writer.writeIntLittle(u32, 0); + } else { + try writer.writeIntLittle(u32, try self.bin_file.getDeclVAddr( + self.decl, // The decl containing the source symbol index + decl.ty, // type we generate the address of + self.symbol_index, // source symbol index + decl.link.wasm.sym_index, // target symbol index + @intCast(u32, self.code.items.len), // offset + @intCast(u32, offset), // addend + )); + } return Result{ .appended = {} }; } }; diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 8cae78caf1..d787c46774 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -242,6 +242,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { const global_offset = emit.offset(); try emit.code.appendSlice(&buf); + // globals can have index 0 as it represents the stack pointer try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ .index = label, .offset = global_offset, @@ -294,11 +295,13 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { leb128.writeUnsignedFixed(5, &buf, label); try emit.code.appendSlice(&buf); - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ - .offset = call_offset, - .index = label, - .relocation_type = .R_WASM_FUNCTION_INDEX_LEB, - }); + if (label != 0) { + try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + .offset = call_offset, + .index = label, + .relocation_type = .R_WASM_FUNCTION_INDEX_LEB, + }); + } } fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void { @@ -318,11 +321,13 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { leb128.writeUnsignedFixed(5, &buf, symbol_index); try emit.code.appendSlice(&buf); - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ - .offset = index_offset, - .index = symbol_index, - .relocation_type = .R_WASM_TABLE_INDEX_SLEB, - }); + if (symbol_index != 0) { + try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + .offset = index_offset, + .index = symbol_index, + .relocation_type = .R_WASM_TABLE_INDEX_SLEB, + }); + } } fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { @@ -342,12 +347,14 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { try emit.code.appendSlice(&buf); } - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ - .offset = mem_offset, - .index = mem.pointer, - .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64, - .addend = mem.offset, - }); + if (mem.pointer != 0) { + try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + .offset = mem_offset, + .index = mem.pointer, + .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64, + .addend = mem.offset, + }); + } } fn emitExtended(emit: *Emit, inst: Mir.Inst.Index) !void { |
