aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-02-21 21:43:38 +0100
committerLuuk de Gram <luuk@degram.dev>2022-02-23 16:07:36 +0100
commitacec06cfaf9a82ec8037a23993ff36fa72eb6e82 (patch)
tree6fbabbcf1bedaf2b46ee42c170f187c2a34648f5 /src/arch
parent0a48a763fd3548a7b8609555cecbafc21ebe1fc3 (diff)
downloadzig-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.zig20
-rw-r--r--src/arch/wasm/Emit.zig39
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 {