diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-07-16 16:31:07 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-07-19 17:22:46 +0200 |
| commit | 376e1b4603e70f1407862fde0180cfe45ca56e73 (patch) | |
| tree | a10cd86492b027721f23c1d27d13d432dde11fe5 /src | |
| parent | 388589987c104354c072d04128327e9823c87497 (diff) | |
| download | zig-376e1b4603e70f1407862fde0180cfe45ca56e73.tar.gz zig-376e1b4603e70f1407862fde0180cfe45ca56e73.zip | |
wasm-linker: implement TLS relocations
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Wasm.zig | 9 | ||||
| -rw-r--r-- | src/link/Wasm/Atom.zig | 13 |
2 files changed, 15 insertions, 7 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 3b019e166f..f53c7bb287 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2153,7 +2153,14 @@ fn allocateVirtualAddresses(wasm: *Wasm) void { const segment_name = segment_info[symbol.index].outputName(merge_segment); const segment_index = wasm.data_segments.get(segment_name).?; const segment = wasm.segments.items[segment_index]; - symbol.virtual_address = atom.offset + segment.offset; + + // TLS symbols have their virtual address set relative to their own TLS segment, + // rather than the entire Data section. + if (symbol.hasFlag(.WASM_SYM_TLS)) { + symbol.virtual_address = atom.offset; + } else { + symbol.virtual_address = atom.offset + segment.offset; + } } } diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index 64e9ebaaa1..8987893ed7 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -174,14 +174,14 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa return 0; } const va = @as(i64, @intCast(symbol.virtual_address)); - return @as(u32, @intCast(va + relocation.addend)); + return @intCast(va + relocation.addend); }, .R_WASM_EVENT_INDEX_LEB => return symbol.index, .R_WASM_SECTION_OFFSET_I32 => { const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; const target_atom = wasm_bin.getAtom(target_atom_index); - const rel_value = @as(i32, @intCast(target_atom.offset)) + relocation.addend; - return @as(u32, @intCast(rel_value)); + const rel_value: i32 = @intCast(target_atom.offset); + return @intCast(rel_value + relocation.addend); }, .R_WASM_FUNCTION_OFFSET_I32 => { const target_atom_index = wasm_bin.symbol_atom.get(target_loc) orelse { @@ -189,13 +189,14 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa }; const target_atom = wasm_bin.getAtom(target_atom_index); const offset: u32 = 11 + Wasm.getULEB128Size(target_atom.size); // Header (11 bytes fixed-size) + body size (leb-encoded) - const rel_value = @as(i32, @intCast(target_atom.offset + offset)) + relocation.addend; - return @as(u32, @intCast(rel_value)); + const rel_value: i32 = @intCast(target_atom.offset + offset); + return @intCast(rel_value + relocation.addend); }, .R_WASM_MEMORY_ADDR_TLS_SLEB, .R_WASM_MEMORY_ADDR_TLS_SLEB64, => { - @panic("TODO: Implement TLS relocations"); + const va: i32 = @intCast(symbol.virtual_address); + return @intCast(va + relocation.addend); }, } } |
