authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-13 08:42:33+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-13 08:42:33+01:00
log4f2009de12275d1633ae514dc00b795a3fa103a5
tree4bf31be78df2ecb087b61d4824b659039010b4db
parente5dc9b1d0995fccd3ff4665a55b0994f14df75c1
parent3f22bb96f393a81a33772bdeddce5fc660e4f667
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18528 from Luukdegram/wasm-linker-fixes

wasm-linker: Fix debug info

3 files changed, 78 insertions(+), 102 deletions(-)

src/link/Wasm.zig+25-84
...@@ -2054,6 +2054,7 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {...@@ -2054,6 +2054,7 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
2054 const decl = mod.declPtr(decl_index);2054 const decl = mod.declPtr(decl_index);
2055 const atom_index = wasm.decls.get(decl_index).?;2055 const atom_index = wasm.decls.get(decl_index).?;
2056 const atom = wasm.getAtomPtr(atom_index);2056 const atom = wasm.getAtomPtr(atom_index);
2057 atom.prev = null;
2057 wasm.symbols_free_list.append(gpa, atom.sym_index) catch {};2058 wasm.symbols_free_list.append(gpa, atom.sym_index) catch {};
2058 _ = wasm.decls.remove(decl_index);2059 _ = wasm.decls.remove(decl_index);
2059 wasm.symbols.items[atom.sym_index].tag = .dead;2060 wasm.symbols.items[atom.sym_index].tag = .dead;
...@@ -2076,16 +2077,6 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {...@@ -2076,16 +2077,6 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
2076 // dwarf.freeDecl(decl_index);2077 // dwarf.freeDecl(decl_index);
2077 // }2078 // }
20782079
2079 if (atom.next) |next_atom_index| {
2080 const next_atom = wasm.getAtomPtr(next_atom_index);
2081 next_atom.prev = atom.prev;
2082 atom.next = null;
2083 }
2084 if (atom.prev) |prev_index| {
2085 const prev_atom = wasm.getAtomPtr(prev_index);
2086 prev_atom.next = atom.next;
2087 atom.prev = null;
2088 }
2089}2080}
20902081
2091/// Appends a new entry to the indirect function table2082/// Appends a new entry to the indirect function table
...@@ -2327,8 +2318,6 @@ pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void...@@ -2327,8 +2318,6 @@ pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void
2327 const gpa = wasm.base.comp.gpa;2318 const gpa = wasm.base.comp.gpa;
2328 const atom = wasm.getAtomPtr(atom_index);2319 const atom = wasm.getAtomPtr(atom_index);
2329 if (wasm.atoms.getPtr(index)) |last_index_ptr| {2320 if (wasm.atoms.getPtr(index)) |last_index_ptr| {
2330 const last = wasm.getAtomPtr(last_index_ptr.*);
2331 last.*.next = atom_index;
2332 atom.prev = last_index_ptr.*;2321 atom.prev = last_index_ptr.*;
2333 last_index_ptr.* = atom_index;2322 last_index_ptr.* = atom_index;
2334 } else {2323 } else {
...@@ -2375,6 +2364,11 @@ fn allocateAtoms(wasm: *Wasm) !void {...@@ -2375,6 +2364,11 @@ fn allocateAtoms(wasm: *Wasm) !void {
2375 while (it.next()) |entry| {2364 while (it.next()) |entry| {
2376 const segment = &wasm.segments.items[entry.key_ptr.*];2365 const segment = &wasm.segments.items[entry.key_ptr.*];
2377 var atom_index = entry.value_ptr.*;2366 var atom_index = entry.value_ptr.*;
2367 if (entry.key_ptr.* == wasm.code_section_index) {
2368 // Code section is allocated upon writing as they are required to be ordered
2369 // to synchronise with the function section.
2370 continue;
2371 }
2378 var offset: u32 = 0;2372 var offset: u32 = 0;
2379 while (true) {2373 while (true) {
2380 const atom = wasm.getAtomPtr(atom_index);2374 const atom = wasm.getAtomPtr(atom_index);
...@@ -2387,28 +2381,17 @@ fn allocateAtoms(wasm: *Wasm) !void {...@@ -2387,28 +2381,17 @@ fn allocateAtoms(wasm: *Wasm) !void {
2387 break :sym object.symtable[symbol_loc.index];2381 break :sym object.symtable[symbol_loc.index];
2388 } else wasm.symbols.items[symbol_loc.index];2382 } else wasm.symbols.items[symbol_loc.index];
23892383
2384 // Dead symbols must be unlinked from the linked-list to prevent them
2385 // from being emit into the binary.
2390 if (sym.isDead()) {2386 if (sym.isDead()) {
2391 // Dead symbols must be unlinked from the linked-list to prevent them2387 if (entry.value_ptr.* == atom_index and atom.prev != null) {
2392 // from being emit into the binary.
2393 if (atom.next) |next_index| {
2394 const next = wasm.getAtomPtr(next_index);
2395 next.prev = atom.prev;
2396 } else if (entry.value_ptr.* == atom_index) {
2397 // When the atom is dead and is also the first atom retrieved from wasm.atoms(index) we update2388 // When the atom is dead and is also the first atom retrieved from wasm.atoms(index) we update
2398 // the entry to point it to the previous atom to ensure we do not start with a dead symbol that2389 // the entry to point it to the previous atom to ensure we do not start with a dead symbol that
2399 // was removed and therefore do not emit any code at all.2390 // was removed and therefore do not emit any code at all.
2400 if (atom.prev) |prev| {2391 entry.value_ptr.* = atom.prev.?;
2401 entry.value_ptr.* = prev;
2402 }
2403 }2392 }
2404 atom_index = atom.prev orelse {2393 atom_index = atom.prev orelse break;
2405 atom.next = null;
2406 break;
2407 };
2408 const prev = wasm.getAtomPtr(atom_index);
2409 prev.next = atom.next;
2410 atom.prev = null;2394 atom.prev = null;
2411 atom.next = null;
2412 continue;2395 continue;
2413 }2396 }
2414 offset = @intCast(atom.alignment.forward(offset));2397 offset = @intCast(atom.alignment.forward(offset));
...@@ -2546,16 +2529,6 @@ fn setupErrorsLen(wasm: *Wasm) !void {...@@ -2546,16 +2529,6 @@ fn setupErrorsLen(wasm: *Wasm) !void {
2546 // if not, allcoate a new atom.2529 // if not, allcoate a new atom.
2547 const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {2530 const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
2548 const atom = wasm.getAtomPtr(index);2531 const atom = wasm.getAtomPtr(index);
2549 if (atom.next) |next_atom_index| {
2550 const next_atom = wasm.getAtomPtr(next_atom_index);
2551 next_atom.prev = atom.prev;
2552 atom.next = null;
2553 }
2554 if (atom.prev) |prev_index| {
2555 const prev_atom = wasm.getAtomPtr(prev_index);
2556 prev_atom.next = atom.next;
2557 atom.prev = null;
2558 }
2559 atom.deinit(gpa);2532 atom.deinit(gpa);
2560 break :blk index;2533 break :blk index;
2561 } else new_atom: {2534 } else new_atom: {
...@@ -2658,18 +2631,12 @@ fn createSyntheticFunction(...@@ -2658,18 +2631,12 @@ fn createSyntheticFunction(
2658 .sym_index = loc.index,2631 .sym_index = loc.index,
2659 .file = null,2632 .file = null,
2660 .alignment = .@"1",2633 .alignment = .@"1",
2661 .next = null,
2662 .prev = null,2634 .prev = null,
2663 .code = function_body.moveToUnmanaged(),2635 .code = function_body.moveToUnmanaged(),
2664 .original_offset = 0,2636 .original_offset = 0,
2665 };2637 };
2666 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);2638 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);
2667 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);2639 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
2668
2669 // `allocateAtoms` has already been called, set the atom's offset manually.
2670 // This is fine to do manually as we insert the atom at the very end.
2671 const prev_atom = wasm.getAtom(atom.prev.?);
2672 atom.offset = prev_atom.offset + prev_atom.size;
2673}2640}
26742641
2675/// Unlike `createSyntheticFunction` this function is to be called by2642/// Unlike `createSyntheticFunction` this function is to be called by
...@@ -2695,7 +2662,6 @@ pub fn createFunction(...@@ -2695,7 +2662,6 @@ pub fn createFunction(
2695 .sym_index = loc.index,2662 .sym_index = loc.index,
2696 .file = null,2663 .file = null,
2697 .alignment = .@"1",2664 .alignment = .@"1",
2698 .next = null,
2699 .prev = null,2665 .prev = null,
2700 .code = function_body.moveToUnmanaged(),2666 .code = function_body.moveToUnmanaged(),
2701 .relocs = relocations.moveToUnmanaged(),2667 .relocs = relocations.moveToUnmanaged(),
...@@ -3260,7 +3226,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3...@@ -3260,7 +3226,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3
3260 break :blk index;3226 break :blk index;
3261 };3227 };
3262 } else if (mem.eql(u8, section_name, ".debug_ranges")) {3228 } else if (mem.eql(u8, section_name, ".debug_ranges")) {
3263 return wasm.debug_line_index orelse blk: {3229 return wasm.debug_ranges_index orelse blk: {
3264 wasm.debug_ranges_index = index;3230 wasm.debug_ranges_index = index;
3265 try wasm.appendDummySegment();3231 try wasm.appendDummySegment();
3266 break :blk index;3232 break :blk index;
...@@ -3452,12 +3418,10 @@ fn resetState(wasm: *Wasm) void {...@@ -3452,12 +3418,10 @@ fn resetState(wasm: *Wasm) void {
3452 var atom_it = wasm.decls.valueIterator();3418 var atom_it = wasm.decls.valueIterator();
3453 while (atom_it.next()) |atom_index| {3419 while (atom_it.next()) |atom_index| {
3454 const atom = wasm.getAtomPtr(atom_index.*);3420 const atom = wasm.getAtomPtr(atom_index.*);
3455 atom.next = null;
3456 atom.prev = null;3421 atom.prev = null;
34573422
3458 for (atom.locals.items) |local_atom_index| {3423 for (atom.locals.items) |local_atom_index| {
3459 const local_atom = wasm.getAtomPtr(local_atom_index);3424 const local_atom = wasm.getAtomPtr(local_atom_index);
3460 local_atom.next = null;
3461 local_atom.prev = null;3425 local_atom.prev = null;
3462 }3426 }
3463 }3427 }
...@@ -4085,46 +4049,29 @@ fn writeToFile(...@@ -4085,46 +4049,29 @@ fn writeToFile(
4085 }4049 }
40864050
4087 // Code section4051 // Code section
4088 var code_section_size: u32 = 0;4052 if (wasm.code_section_index != null) {
4089 if (wasm.code_section_index) |code_index| {
4090 const header_offset = try reserveVecSectionHeader(&binary_bytes);4053 const header_offset = try reserveVecSectionHeader(&binary_bytes);
4091 var atom_index = wasm.atoms.get(code_index).?;4054 const start_offset = binary_bytes.items.len - 5; // minus 5 so start offset is 5 to include entry count
40924055
4093 // The code section must be sorted in line with the function order.4056 var func_it = wasm.functions.iterator();
4094 var sorted_atoms = try std.ArrayList(*const Atom).initCapacity(gpa, wasm.functions.count());4057 while (func_it.next()) |entry| {
4095 defer sorted_atoms.deinit();4058 const sym_loc: SymbolLoc = .{ .index = entry.value_ptr.sym_index, .file = entry.key_ptr.file };
40964059 const atom_index = wasm.symbol_atom.get(sym_loc).?;
4097 while (true) {
4098 const atom = wasm.getAtomPtr(atom_index);4060 const atom = wasm.getAtomPtr(atom_index);
4061
4099 if (!is_obj) {4062 if (!is_obj) {
4100 atom.resolveRelocs(wasm);4063 atom.resolveRelocs(wasm);
4101 }4064 }
4102 sorted_atoms.appendAssumeCapacity(atom); // found more code atoms than functions4065 atom.offset = @intCast(binary_bytes.items.len - start_offset);
4103 atom_index = atom.prev orelse break;4066 try leb.writeULEB128(binary_writer, atom.size);
4104 }4067 try binary_writer.writeAll(atom.code.items);
4105 assert(wasm.functions.count() == sorted_atoms.items.len);
4106
4107 const atom_sort_fn = struct {
4108 fn sort(ctx: *const Wasm, lhs: *const Atom, rhs: *const Atom) bool {
4109 const lhs_sym = lhs.symbolLoc().getSymbol(ctx);
4110 const rhs_sym = rhs.symbolLoc().getSymbol(ctx);
4111 return lhs_sym.index < rhs_sym.index;
4112 }
4113 }.sort;
4114
4115 mem.sort(*const Atom, sorted_atoms.items, wasm, atom_sort_fn);
4116
4117 for (sorted_atoms.items) |sorted_atom| {
4118 try leb.writeULEB128(binary_writer, sorted_atom.size);
4119 try binary_writer.writeAll(sorted_atom.code.items);
4120 }4068 }
41214069
4122 code_section_size = @as(u32, @intCast(binary_bytes.items.len - header_offset - header_size));
4123 try writeVecSectionHeader(4070 try writeVecSectionHeader(
4124 binary_bytes.items,4071 binary_bytes.items,
4125 header_offset,4072 header_offset,
4126 .code,4073 .code,
4127 code_section_size,4074 @intCast(binary_bytes.items.len - header_offset - header_size),
4128 @intCast(wasm.functions.count()),4075 @intCast(wasm.functions.count()),
4129 );4076 );
4130 code_section_index = section_count;4077 code_section_index = section_count;
...@@ -5301,14 +5248,8 @@ fn markReferences(wasm: *Wasm) !void {...@@ -5301,14 +5248,8 @@ fn markReferences(wasm: *Wasm) !void {
5301 const object = &wasm.objects.items[file];5248 const object = &wasm.objects.items[file];
5302 const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);5249 const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);
5303 const atom = wasm.getAtom(atom_index);5250 const atom = wasm.getAtom(atom_index);
5304 for (atom.relocs.items) |reloc| {5251 const atom_sym = atom.symbolLoc().getSymbol(wasm);
5305 const target_loc: SymbolLoc = .{ .index = reloc.index, .file = atom.file };5252 atom_sym.mark();
5306 const target_sym = target_loc.getSymbol(wasm);
5307 if (target_sym.isAlive() or !do_garbage_collect) {
5308 sym.mark();
5309 continue; // Skip all other relocations as this debug atom is already marked now
5310 }
5311 }
5312 }5253 }
5313 }5254 }
5314}5255}
src/link/Wasm/Atom.zig+30-17
...@@ -26,18 +26,12 @@ offset: u32,...@@ -26,18 +26,12 @@ offset: u32,
26/// The original offset within the object file. This value is substracted from26/// The original offset within the object file. This value is substracted from
27/// relocation offsets to determine where in the `data` to rewrite the value27/// relocation offsets to determine where in the `data` to rewrite the value
28original_offset: u32,28original_offset: u32,
29
30/// Represents the index of the file this atom was generated from.29/// Represents the index of the file this atom was generated from.
31/// This is 'null' when the atom was generated by a Decl from Zig code.30/// This is 'null' when the atom was generated by a Decl from Zig code.
32file: ?u16,31file: ?u16,
33
34/// Next atom in relation to this atom.
35/// When null, this atom is the last atom
36next: ?Atom.Index,
37/// Previous atom in relation to this atom.32/// Previous atom in relation to this atom.
38/// is null when this atom is the first in its order33/// is null when this atom is the first in its order
39prev: ?Atom.Index,34prev: ?Atom.Index,
40
41/// Contains atoms local to a decl, all managed by this `Atom`.35/// Contains atoms local to a decl, all managed by this `Atom`.
42/// When the parent atom is being freed, it will also do so for all local atoms.36/// When the parent atom is being freed, it will also do so for all local atoms.
43locals: std.ArrayListUnmanaged(Atom.Index) = .{},37locals: std.ArrayListUnmanaged(Atom.Index) = .{},
...@@ -49,7 +43,6 @@ pub const Index = u32;...@@ -49,7 +43,6 @@ pub const Index = u32;
49pub const empty: Atom = .{43pub const empty: Atom = .{
50 .alignment = .@"1",44 .alignment = .@"1",
51 .file = null,45 .file = null,
52 .next = null,
53 .offset = 0,46 .offset = 0,
54 .prev = null,47 .prev = null,
55 .size = 0,48 .size = 0,
...@@ -118,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {...@@ -118,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
118 .R_WASM_GLOBAL_INDEX_I32,111 .R_WASM_GLOBAL_INDEX_I32,
119 .R_WASM_MEMORY_ADDR_I32,112 .R_WASM_MEMORY_ADDR_I32,
120 .R_WASM_SECTION_OFFSET_I32,113 .R_WASM_SECTION_OFFSET_I32,
121 => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @intCast(value)), .little),114 => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @truncate(value)), .little),
122 .R_WASM_TABLE_INDEX_I64,115 .R_WASM_TABLE_INDEX_I64,
123 .R_WASM_MEMORY_ADDR_I64,116 .R_WASM_MEMORY_ADDR_I64,
124 => std.mem.writeInt(u64, atom.code.items[reloc.offset - atom.original_offset ..][0..8], value, .little),117 => std.mem.writeInt(u64, atom.code.items[reloc.offset - atom.original_offset ..][0..8], value, .little),
...@@ -131,7 +124,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {...@@ -131,7 +124,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
131 .R_WASM_TABLE_NUMBER_LEB,124 .R_WASM_TABLE_NUMBER_LEB,
132 .R_WASM_TYPE_INDEX_LEB,125 .R_WASM_TYPE_INDEX_LEB,
133 .R_WASM_MEMORY_ADDR_TLS_SLEB,126 .R_WASM_MEMORY_ADDR_TLS_SLEB,
134 => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @intCast(value))),127 => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @truncate(value))),
135 .R_WASM_MEMORY_ADDR_LEB64,128 .R_WASM_MEMORY_ADDR_LEB64,
136 .R_WASM_MEMORY_ADDR_SLEB64,129 .R_WASM_MEMORY_ADDR_SLEB64,
137 .R_WASM_TABLE_INDEX_SLEB64,130 .R_WASM_TABLE_INDEX_SLEB64,
...@@ -147,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {...@@ -147,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
147fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {140fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
148 const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin);141 const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin);
149 const symbol = target_loc.getSymbol(wasm_bin);142 const symbol = target_loc.getSymbol(wasm_bin);
143 if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and
144 symbol.tag != .section and
145 symbol.isDead())
146 {
147 const val = atom.thombstone(wasm_bin) orelse relocation.addend;
148 return @bitCast(val);
149 }
150 switch (relocation.relocation_type) {150 switch (relocation.relocation_type) {
151 .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,151 .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
152 .R_WASM_TABLE_NUMBER_LEB => return symbol.index,152 .R_WASM_TABLE_NUMBER_LEB => return symbol.index,
...@@ -177,30 +177,43 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa...@@ -177,30 +177,43 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
177 if (symbol.isUndefined()) {177 if (symbol.isUndefined()) {
178 return 0;178 return 0;
179 }179 }
180 const va = @as(i64, @intCast(symbol.virtual_address));180 const va: i33 = @intCast(symbol.virtual_address);
181 return @intCast(va + relocation.addend);181 return @intCast(va + relocation.addend);
182 },182 },
183 .R_WASM_EVENT_INDEX_LEB => return symbol.index,183 .R_WASM_EVENT_INDEX_LEB => return symbol.index,
184 .R_WASM_SECTION_OFFSET_I32 => {184 .R_WASM_SECTION_OFFSET_I32 => {
185 const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?;185 const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?;
186 const target_atom = wasm_bin.getAtom(target_atom_index);186 const target_atom = wasm_bin.getAtom(target_atom_index);
187 const rel_value: i32 = @intCast(target_atom.offset);187 const rel_value: i33 = @intCast(target_atom.offset);
188 return @intCast(rel_value + relocation.addend);188 return @intCast(rel_value + relocation.addend);
189 },189 },
190 .R_WASM_FUNCTION_OFFSET_I32 => {190 .R_WASM_FUNCTION_OFFSET_I32 => {
191 const target_atom_index = wasm_bin.symbol_atom.get(target_loc) orelse {191 if (symbol.isUndefined()) {
192 return @as(u32, @bitCast(@as(i32, -1)));192 const val = atom.thombstone(wasm_bin) orelse relocation.addend;
193 };193 return @bitCast(val);
194 }
195 const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?;
194 const target_atom = wasm_bin.getAtom(target_atom_index);196 const target_atom = wasm_bin.getAtom(target_atom_index);
195 const offset: u32 = 11 + Wasm.getULEB128Size(target_atom.size); // Header (11 bytes fixed-size) + body size (leb-encoded)197 const rel_value: i33 = @intCast(target_atom.offset);
196 const rel_value: i32 = @intCast(target_atom.offset + offset);
197 return @intCast(rel_value + relocation.addend);198 return @intCast(rel_value + relocation.addend);
198 },199 },
199 .R_WASM_MEMORY_ADDR_TLS_SLEB,200 .R_WASM_MEMORY_ADDR_TLS_SLEB,
200 .R_WASM_MEMORY_ADDR_TLS_SLEB64,201 .R_WASM_MEMORY_ADDR_TLS_SLEB64,
201 => {202 => {
202 const va: i32 = @intCast(symbol.virtual_address);203 const va: i33 = @intCast(symbol.virtual_address);
203 return @intCast(va + relocation.addend);204 return @intCast(va + relocation.addend);
204 },205 },
205 }206 }
206}207}
208
209// For a given `Atom` returns whether it has a thombstone value or not.
210/// This defines whether we want a specific value when a section is dead.
211fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 {
212 const atom_name = atom.symbolLoc().getName(wasm);
213 if (std.mem.eql(u8, atom_name, ".debug_ranges") or std.mem.eql(u8, atom_name, ".debug_loc")) {
214 return -2;
215 } else if (std.mem.startsWith(u8, atom_name, ".debug_")) {
216 return -1;
217 }
218 return null;
219}
src/link/Wasm/Object.zig+23-1
...@@ -80,6 +80,9 @@ const RelocatableData = struct {...@@ -80,6 +80,9 @@ const RelocatableData = struct {
80 offset: u32,80 offset: u32,
81 /// Represents the index of the section it belongs to81 /// Represents the index of the section it belongs to
82 section_index: u32,82 section_index: u32,
83 /// Whether the relocatable section is represented by a symbol or not.
84 /// Can only be `true` for custom sections.
85 represented: bool = false,
8386
84 const Tag = enum { data, code, custom };87 const Tag = enum { data, code, custom };
8588
...@@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type {...@@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type {
753 log.debug("Found legacy indirect function table. Created symbol", .{});756 log.debug("Found legacy indirect function table. Created symbol", .{});
754 }757 }
755758
759 // Not all debug sections may be represented by a symbol, for those sections
760 // we manually create a symbol.
761 if (parser.object.relocatable_data.get(.custom)) |custom_sections| {
762 for (custom_sections) |*data| {
763 if (!data.represented) {
764 try symbols.append(.{
765 .name = data.index,
766 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
767 .tag = .section,
768 .virtual_address = 0,
769 .index = data.section_index,
770 });
771 data.represented = true;
772 log.debug("Created synthetic custom section symbol for '{s}'", .{parser.object.string_table.get(data.index)});
773 }
774 }
775 }
776
756 parser.object.symtable = try symbols.toOwnedSlice();777 parser.object.symtable = try symbols.toOwnedSlice();
757 },778 },
758 }779 }
...@@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type {...@@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type {
791 .section => {812 .section => {
792 symbol.index = try leb.readULEB128(u32, reader);813 symbol.index = try leb.readULEB128(u32, reader);
793 const section_data = parser.object.relocatable_data.get(.custom).?;814 const section_data = parser.object.relocatable_data.get(.custom).?;
794 for (section_data) |data| {815 for (section_data) |*data| {
795 if (data.section_index == symbol.index) {816 if (data.section_index == symbol.index) {
796 symbol.name = data.index;817 symbol.name = data.index;
818 data.represented = true;
797 break;819 break;
798 }820 }
799 }821 }