authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-21 12:06:33+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:03+01:00
log0a030d6598a42eae6f6af829e03bba053336b51c
treedc18ba8e2eebf6b1b13c5a17bf317e7aa792b928
parent94f3a18c88eaee9a36a08a1b00c9df0584a01b05
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Use `File.Index` for symbol locations

Rather than using the optional, we now directly use `File.Index` which can already represent an unknown file due to its `.null` value. This means we do not pay for the memory cost. This type of index is now used for: - SymbolLoc - Key of the functions map - InitFunc Now we can simply pass things like atom.file, object.file, loc.file etc whenever we need to access its representing object file which makes it a lot easier.

4 files changed, 49 insertions(+), 84 deletions(-)

src/link/Wasm.zig+38-63
...@@ -125,7 +125,10 @@ func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},...@@ -125,7 +125,10 @@ func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},
125/// Output function section where the key is the original125/// Output function section where the key is the original
126/// function index and the value is function.126/// function index and the value is function.
127/// This allows us to map multiple symbols to the same function.127/// This allows us to map multiple symbols to the same function.
128functions: std.AutoArrayHashMapUnmanaged(struct { file: ?u16, index: u32 }, struct { func: std.wasm.Func, sym_index: u32 }) = .{},128functions: std.AutoArrayHashMapUnmanaged(
129 struct { file: File.Index, index: u32 },
130 struct { func: std.wasm.Func, sym_index: u32 },
131) = .{},
129/// Output global section132/// Output global section
130wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{},133wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{},
131/// Memory section134/// Memory section
...@@ -217,16 +220,14 @@ pub const SymbolLoc = struct {...@@ -217,16 +220,14 @@ pub const SymbolLoc = struct {
217 /// The index of the symbol within the specified file220 /// The index of the symbol within the specified file
218 index: u32,221 index: u32,
219 /// The index of the object file where the symbol resides.222 /// The index of the object file where the symbol resides.
220 /// When this is `null` the symbol comes from a non-object file.223 file: File.Index,
221 file: ?u16,
222224
223 /// From a given location, returns the corresponding symbol in the wasm binary225 /// From a given location, returns the corresponding symbol in the wasm binary
224 pub fn getSymbol(loc: SymbolLoc, wasm_file: *const Wasm) *Symbol {226 pub fn getSymbol(loc: SymbolLoc, wasm_file: *const Wasm) *Symbol {
225 if (wasm_file.discarded.get(loc)) |new_loc| {227 if (wasm_file.discarded.get(loc)) |new_loc| {
226 return new_loc.getSymbol(wasm_file);228 return new_loc.getSymbol(wasm_file);
227 }229 }
228 if (loc.file) |object_index| {230 if (wasm_file.file(loc.file)) |obj_file| {
229 const obj_file = wasm_file.file(@enumFromInt(object_index)).?;
230 return obj_file.symbol(loc.index);231 return obj_file.symbol(loc.index);
231 }232 }
232 return &wasm_file.synthetic_symbols.items[loc.index];233 return &wasm_file.synthetic_symbols.items[loc.index];
...@@ -237,8 +238,7 @@ pub const SymbolLoc = struct {...@@ -237,8 +238,7 @@ pub const SymbolLoc = struct {
237 if (wasm_file.discarded.get(loc)) |new_loc| {238 if (wasm_file.discarded.get(loc)) |new_loc| {
238 return new_loc.getName(wasm_file);239 return new_loc.getName(wasm_file);
239 }240 }
240 if (loc.file) |object_index| {241 if (wasm_file.file(loc.file)) |obj_file| {
241 const obj_file = wasm_file.file(@enumFromInt(object_index)).?;
242 return obj_file.symbolName(loc.index);242 return obj_file.symbolName(loc.index);
243 }243 }
244 return wasm_file.string_table.get(wasm_file.synthetic_symbols.items[loc.index].name);244 return wasm_file.string_table.get(wasm_file.synthetic_symbols.items[loc.index].name);
...@@ -263,7 +263,7 @@ pub const InitFuncLoc = struct {...@@ -263,7 +263,7 @@ pub const InitFuncLoc = struct {
263 /// object file index in the list of objects.263 /// object file index in the list of objects.
264 /// Unlike `SymbolLoc` this cannot be `null` as we never define264 /// Unlike `SymbolLoc` this cannot be `null` as we never define
265 /// our own ctors.265 /// our own ctors.
266 file: u16,266 file: File.Index,
267 /// Symbol index within the corresponding object file.267 /// Symbol index within the corresponding object file.
268 index: u32,268 index: u32,
269 /// The priority in which the constructor must be called.269 /// The priority in which the constructor must be called.
...@@ -633,7 +633,7 @@ fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !Symbol...@@ -633,7 +633,7 @@ fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !Symbol
633633
634fn createSyntheticSymbolOffset(wasm: *Wasm, name_offset: u32, tag: Symbol.Tag) !SymbolLoc {634fn createSyntheticSymbolOffset(wasm: *Wasm, name_offset: u32, tag: Symbol.Tag) !SymbolLoc {
635 const sym_index = @as(u32, @intCast(wasm.synthetic_symbols.items.len));635 const sym_index = @as(u32, @intCast(wasm.synthetic_symbols.items.len));
636 const loc: SymbolLoc = .{ .index = sym_index, .file = null };636 const loc: SymbolLoc = .{ .index = sym_index, .file = .null };
637 const gpa = wasm.base.comp.gpa;637 const gpa = wasm.base.comp.gpa;
638 try wasm.synthetic_symbols.append(gpa, .{638 try wasm.synthetic_symbols.append(gpa, .{
639 .name = name_offset,639 .name = name_offset,
...@@ -680,7 +680,7 @@ pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Ind...@@ -680,7 +680,7 @@ pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Ind
680 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);680 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
681 const atom = try wasm.managed_atoms.addOne(gpa);681 const atom = try wasm.managed_atoms.addOne(gpa);
682 atom.* = .{ .file = file_index, .sym_index = sym_index };682 atom.* = .{ .file = file_index, .sym_index = sym_index };
683 try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = sym_index }, index);683 try wasm.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), index);
684684
685 return index;685 return index;
686}686}
...@@ -763,10 +763,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {...@@ -763,10 +763,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {
763763
764 for (obj_file.symbols(), 0..) |symbol, i| {764 for (obj_file.symbols(), 0..) |symbol, i| {
765 const sym_index: u32 = @intCast(i);765 const sym_index: u32 = @intCast(i);
766 const location: SymbolLoc = .{766 const location: SymbolLoc = .{ .file = file_index, .index = sym_index };
767 .file = @intFromEnum(file_index),
768 .index = sym_index,
769 };
770 const sym_name = obj_file.string(symbol.name);767 const sym_name = obj_file.string(symbol.name);
771 if (mem.eql(u8, sym_name, "__indirect_function_table")) {768 if (mem.eql(u8, sym_name, "__indirect_function_table")) {
772 continue;769 continue;
...@@ -796,9 +793,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {...@@ -796,9 +793,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {
796793
797 const existing_loc = maybe_existing.value_ptr.*;794 const existing_loc = maybe_existing.value_ptr.*;
798 const existing_sym: *Symbol = existing_loc.getSymbol(wasm);795 const existing_sym: *Symbol = existing_loc.getSymbol(wasm);
796 const existing_file = wasm.file(existing_loc.file);
799797
800 const existing_file_path = if (existing_loc.file) |existing_file_index|798 const existing_file_path = if (existing_file) |existing_obj_file|
801 wasm.file(@enumFromInt(existing_file_index)).?.path()799 existing_obj_file.path()
802 else800 else
803 wasm.name;801 wasm.name;
804802
...@@ -831,8 +829,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {...@@ -831,8 +829,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {
831 if (existing_sym.isUndefined() and symbol.isUndefined()) {829 if (existing_sym.isUndefined() and symbol.isUndefined()) {
832 // only verify module/import name for function symbols830 // only verify module/import name for function symbols
833 if (symbol.tag == .function) {831 if (symbol.tag == .function) {
834 const existing_name = if (existing_loc.file) |existing_file_index| blk: {832 const existing_name = if (existing_file) |existing_obj| blk: {
835 const existing_obj = wasm.file(@enumFromInt(existing_file_index)).?;
836 const imp = existing_obj.import(existing_loc.index);833 const imp = existing_obj.import(existing_loc.index);
837 break :blk existing_obj.string(imp.module_name);834 break :blk existing_obj.string(imp.module_name);
838 } else blk: {835 } else blk: {
...@@ -1363,8 +1360,8 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void {...@@ -1363,8 +1360,8 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void {
1363 const symbol = undef.getSymbol(wasm);1360 const symbol = undef.getSymbol(wasm);
1364 if (symbol.tag == .data) {1361 if (symbol.tag == .data) {
1365 found_undefined_symbols = true;1362 found_undefined_symbols = true;
1366 const file_name = if (undef.file) |file_index|1363 const file_name = if (wasm.file(undef.file)) |obj_file|
1367 wasm.file(@enumFromInt(file_index)).?.path()1364 obj_file.path()
1368 else1365 else
1369 wasm.name;1366 wasm.name;
1370 const symbol_name = undef.getName(wasm);1367 const symbol_name = undef.getName(wasm);
...@@ -1461,8 +1458,7 @@ fn getGlobalType(wasm: *const Wasm, loc: SymbolLoc) std.wasm.GlobalType {...@@ -1461,8 +1458,7 @@ fn getGlobalType(wasm: *const Wasm, loc: SymbolLoc) std.wasm.GlobalType {
1461 const symbol = loc.getSymbol(wasm);1458 const symbol = loc.getSymbol(wasm);
1462 assert(symbol.tag == .global);1459 assert(symbol.tag == .global);
1463 const is_undefined = symbol.isUndefined();1460 const is_undefined = symbol.isUndefined();
1464 if (loc.file) |file_index| {1461 if (wasm.file(loc.file)) |obj_file| {
1465 const obj_file = wasm.file(@enumFromInt(file_index)).?;
1466 if (is_undefined) {1462 if (is_undefined) {
1467 return obj_file.import(loc.index).kind.global;1463 return obj_file.import(loc.index).kind.global;
1468 }1464 }
...@@ -1480,8 +1476,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1480,8 +1476,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1480 const symbol = loc.getSymbol(wasm);1476 const symbol = loc.getSymbol(wasm);
1481 assert(symbol.tag == .function);1477 assert(symbol.tag == .function);
1482 const is_undefined = symbol.isUndefined();1478 const is_undefined = symbol.isUndefined();
1483 if (loc.file) |file_index| {1479 if (wasm.file(loc.file)) |obj_file| {
1484 const obj_file = wasm.file(@enumFromInt(file_index)).?;
1485 if (is_undefined) {1480 if (is_undefined) {
1486 const ty_index = obj_file.import(loc.index).kind.function;1481 const ty_index = obj_file.import(loc.index).kind.function;
1487 return obj_file.funcTypes()[ty_index];1482 return obj_file.funcTypes()[ty_index];
...@@ -1625,8 +1620,8 @@ fn allocateAtoms(wasm: *Wasm) !void {...@@ -1625,8 +1620,8 @@ fn allocateAtoms(wasm: *Wasm) !void {
1625 // Ensure we get the original symbol, so we verify the correct symbol on whether1620 // Ensure we get the original symbol, so we verify the correct symbol on whether
1626 // it is dead or not and ensure an atom is removed when dead.1621 // it is dead or not and ensure an atom is removed when dead.
1627 // This is required as we may have parsed aliases into atoms.1622 // This is required as we may have parsed aliases into atoms.
1628 const sym = if (symbol_loc.file) |file_index|1623 const sym = if (wasm.file(symbol_loc.file)) |obj_file|
1629 wasm.file(@enumFromInt(file_index)).?.symbol(symbol_loc.index).*1624 obj_file.symbol(symbol_loc.index).*
1630 else1625 else
1631 wasm.synthetic_symbols.items[symbol_loc.index];1626 wasm.synthetic_symbols.items[symbol_loc.index];
16321627
...@@ -1754,10 +1749,10 @@ fn setupInitFunctions(wasm: *Wasm) !void {...@@ -1754,10 +1749,10 @@ fn setupInitFunctions(wasm: *Wasm) !void {
1754 log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)});1749 log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)});
1755 wasm.init_funcs.appendAssumeCapacity(.{1750 wasm.init_funcs.appendAssumeCapacity(.{
1756 .index = init_func.symbol_index,1751 .index = init_func.symbol_index,
1757 .file = @intFromEnum(file_index),1752 .file = file_index,
1758 .priority = init_func.priority,1753 .priority = init_func.priority,
1759 });1754 });
1760 try wasm.mark(.{ .index = init_func.symbol_index, .file = @intFromEnum(file_index) });1755 try wasm.mark(.{ .index = init_func.symbol_index, .file = file_index });
1761 }1756 }
1762 }1757 }
17631758
...@@ -1841,7 +1836,7 @@ fn createSyntheticFunction(...@@ -1841,7 +1836,7 @@ fn createSyntheticFunction(
1841 const func_index = wasm.imported_functions_count + @as(u32, @intCast(wasm.functions.count()));1836 const func_index = wasm.imported_functions_count + @as(u32, @intCast(wasm.functions.count()));
1842 try wasm.functions.putNoClobber(1837 try wasm.functions.putNoClobber(
1843 gpa,1838 gpa,
1844 .{ .file = null, .index = func_index },1839 .{ .file = .null, .index = func_index },
1845 .{ .func = .{ .type_index = ty_index }, .sym_index = loc.index },1840 .{ .func = .{ .type_index = ty_index }, .sym_index = loc.index },
1846 );1841 );
1847 symbol.index = func_index;1842 symbol.index = func_index;
...@@ -1849,8 +1844,8 @@ fn createSyntheticFunction(...@@ -1849,8 +1844,8 @@ fn createSyntheticFunction(
1849 // create the atom that will be output into the final binary1844 // create the atom that will be output into the final binary
1850 const atom_index = try wasm.createAtom(loc.index, .null);1845 const atom_index = try wasm.createAtom(loc.index, .null);
1851 const atom = wasm.getAtomPtr(atom_index);1846 const atom = wasm.getAtomPtr(atom_index);
1852 atom.code = function_body.moveToUnmanaged();
1853 atom.size = @intCast(function_body.items.len);1847 atom.size = @intCast(function_body.items.len);
1848 atom.code = function_body.moveToUnmanaged();
1854 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);1849 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);
1855}1850}
18561851
...@@ -1969,20 +1964,8 @@ fn initializeTLSFunction(wasm: *Wasm) !void {...@@ -1969,20 +1964,8 @@ fn initializeTLSFunction(wasm: *Wasm) !void {
1969fn setupImports(wasm: *Wasm) !void {1964fn setupImports(wasm: *Wasm) !void {
1970 const gpa = wasm.base.comp.gpa;1965 const gpa = wasm.base.comp.gpa;
1971 log.debug("Merging imports", .{});1966 log.debug("Merging imports", .{});
1972 var discarded_it = wasm.discarded.keyIterator();
1973 while (discarded_it.next()) |discarded| {
1974 if (discarded.file == null) {
1975 // remove an import if it was resolved
1976 if (wasm.imports.remove(discarded.*)) {
1977 log.debug("Removed symbol '{s}' as an import", .{
1978 discarded.getName(wasm),
1979 });
1980 }
1981 }
1982 }
1983
1984 for (wasm.resolved_symbols.keys()) |symbol_loc| {1967 for (wasm.resolved_symbols.keys()) |symbol_loc| {
1985 const file_index = symbol_loc.file orelse {1968 const obj_file = wasm.file(symbol_loc.file) orelse {
1986 // Synthetic symbols will already exist in the `import` section1969 // Synthetic symbols will already exist in the `import` section
1987 continue;1970 continue;
1988 };1971 };
...@@ -1996,7 +1979,6 @@ fn setupImports(wasm: *Wasm) !void {...@@ -1996,7 +1979,6 @@ fn setupImports(wasm: *Wasm) !void {
1996 }1979 }
19971980
1998 log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)});1981 log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)});
1999 const obj_file = wasm.file(@enumFromInt(file_index)).?;
2000 const import = obj_file.import(symbol_loc.index);1982 const import = obj_file.import(symbol_loc.index);
20011983
2002 // We copy the import to a new import to ensure the names contain references1984 // We copy the import to a new import to ensure the names contain references
...@@ -2054,15 +2036,13 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2054,15 +2036,13 @@ fn mergeSections(wasm: *Wasm) !void {
2054 defer removed_duplicates.deinit();2036 defer removed_duplicates.deinit();
20552037
2056 for (wasm.resolved_symbols.keys()) |sym_loc| {2038 for (wasm.resolved_symbols.keys()) |sym_loc| {
2057 const file_index = sym_loc.file orelse {2039 const obj_file = wasm.file(sym_loc.file) orelse {
2058 // Zig code-generated symbols are already within the sections and do not2040 // Zig code-generated symbols are already within the sections and do not
2059 // require to be merged2041 // require to be merged
2060 continue;2042 continue;
2061 };2043 };
20622044
2063 const obj_file = wasm.file(@enumFromInt(file_index)).?;
2064 const symbol = obj_file.symbol(sym_loc.index);2045 const symbol = obj_file.symbol(sym_loc.index);
2065
2066 if (symbol.isDead() or symbol.isUndefined()) {2046 if (symbol.isDead() or symbol.isUndefined()) {
2067 // Skip undefined symbols as they go in the `import` section2047 // Skip undefined symbols as they go in the `import` section
2068 continue;2048 continue;
...@@ -2105,7 +2085,7 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2105,7 +2085,7 @@ fn mergeSections(wasm: *Wasm) !void {
2105 symbol.index = @as(u32, @intCast(wasm.tables.items.len)) + wasm.imported_tables_count;2085 symbol.index = @as(u32, @intCast(wasm.tables.items.len)) + wasm.imported_tables_count;
2106 try wasm.tables.append(gpa, original_table);2086 try wasm.tables.append(gpa, original_table);
2107 },2087 },
2108 else => continue,2088 else => {},
2109 }2089 }
2110 }2090 }
21112091
...@@ -2132,12 +2112,11 @@ fn mergeTypes(wasm: *Wasm) !void {...@@ -2132,12 +2112,11 @@ fn mergeTypes(wasm: *Wasm) !void {
2132 defer dirty.deinit();2112 defer dirty.deinit();
21332113
2134 for (wasm.resolved_symbols.keys()) |sym_loc| {2114 for (wasm.resolved_symbols.keys()) |sym_loc| {
2135 const file_index = sym_loc.file orelse {2115 const obj_file = wasm.file(sym_loc.file) orelse {
2136 // zig code-generated symbols are already present in final type section2116 // zig code-generated symbols are already present in final type section
2137 continue;2117 continue;
2138 };2118 };
21392119
2140 const obj_file = wasm.file(@enumFromInt(file_index)).?;
2141 const symbol = obj_file.symbol(sym_loc.index);2120 const symbol = obj_file.symbol(sym_loc.index);
2142 if (symbol.tag != .function or symbol.isDead()) {2121 if (symbol.tag != .function or symbol.isDead()) {
2143 // Only functions have types. Only retrieve the type of referenced functions.2122 // Only functions have types. Only retrieve the type of referenced functions.
...@@ -2191,7 +2170,7 @@ fn setupExports(wasm: *Wasm) !void {...@@ -2191,7 +2170,7 @@ fn setupExports(wasm: *Wasm) !void {
21912170
2192 const sym_name = sym_loc.getName(wasm);2171 const sym_name = sym_loc.getName(wasm);
2193 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {2172 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {
2194 if (sym_loc.file == null) break :blk symbol.name;2173 if (sym_loc.file == .null) break :blk symbol.name;
2195 break :blk try wasm.string_table.put(gpa, sym_name);2174 break :blk try wasm.string_table.put(gpa, sym_name);
2196 };2175 };
2197 const exp: types.Export = if (symbol.tag == .data) exp: {2176 const exp: types.Export = if (symbol.tag == .data) exp: {
...@@ -2425,7 +2404,7 @@ pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32...@@ -2425,7 +2404,7 @@ pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32
2425 break :blk index;2404 break :blk index;
2426 },2405 },
2427 .section => {2406 .section => {
2428 const section_name = obj_file.symbolName(symbol.index);2407 const section_name = obj_file.symbolName(symbol_index);
2429 if (mem.eql(u8, section_name, ".debug_info")) {2408 if (mem.eql(u8, section_name, ".debug_info")) {
2430 return wasm.debug_info_index orelse blk: {2409 return wasm.debug_info_index orelse blk: {
2431 wasm.debug_info_index = index;2410 wasm.debug_info_index = index;
...@@ -2475,7 +2454,7 @@ pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32...@@ -2475,7 +2454,7 @@ pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32
2475 break :blk index;2454 break :blk index;
2476 };2455 };
2477 } else {2456 } else {
2478 log.warn("found unknown section '{s}'", .{section_name});2457 log.err("found unknown section '{s}'", .{section_name});
2479 return error.UnexpectedValue;2458 return error.UnexpectedValue;
2480 }2459 }
2481 },2460 },
...@@ -4221,10 +4200,7 @@ fn emitDataRelocations(...@@ -4221,10 +4200,7 @@ fn emitDataRelocations(
4221 size_offset += getULEB128Size(atom.size);4200 size_offset += getULEB128Size(atom.size);
4222 for (atom.relocs.items) |relocation| {4201 for (atom.relocs.items) |relocation| {
4223 count += 1;4202 count += 1;
4224 const sym_loc: SymbolLoc = .{4203 const sym_loc: SymbolLoc = .{ .file = atom.file, .index = relocation.index };
4225 .file = atom.file,
4226 .index = relocation.index,
4227 };
4228 const symbol_index = symbol_table.get(sym_loc).?;4204 const symbol_index = symbol_table.get(sym_loc).?;
4229 try leb.writeULEB128(writer, @intFromEnum(relocation.relocation_type));4205 try leb.writeULEB128(writer, @intFromEnum(relocation.relocation_type));
4230 const offset = atom.offset + relocation.offset + size_offset;4206 const offset = atom.offset + relocation.offset + size_offset;
...@@ -4322,8 +4298,7 @@ fn markReferences(wasm: *Wasm) !void {...@@ -4322,8 +4298,7 @@ fn markReferences(wasm: *Wasm) !void {
4322 // Debug sections may require to be parsed and marked when it contains4298 // Debug sections may require to be parsed and marked when it contains
4323 // relocations to alive symbols.4299 // relocations to alive symbols.
4324 if (sym.tag == .section and comp.config.debug_format != .strip) {4300 if (sym.tag == .section and comp.config.debug_format != .strip) {
4325 const file_index = sym_loc.file orelse continue; // Incremental debug info is done independently4301 const obj_file = wasm.file(sym_loc.file) orelse continue; // Incremental debug info is done independently
4326 const obj_file = wasm.file(@enumFromInt(file_index)).?;
4327 _ = try obj_file.parseSymbolIntoAtom(wasm, sym_loc.index);4302 _ = try obj_file.parseSymbolIntoAtom(wasm, sym_loc.index);
4328 sym.mark();4303 sym.mark();
4329 }4304 }
...@@ -4347,10 +4322,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {...@@ -4347,10 +4322,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {
4347 return;4322 return;
4348 }4323 }
43494324
4350 const atom_index = if (loc.file) |file_index| idx: {4325 const atom_index = if (wasm.file(loc.file)) |obj_file|
4351 const obj_file = wasm.file(@enumFromInt(file_index)).?;4326 try obj_file.parseSymbolIntoAtom(wasm, loc.index)
4352 break :idx try obj_file.parseSymbolIntoAtom(wasm, loc.index);4327 else
4353 } else wasm.symbol_atom.get(loc) orelse return;4328 wasm.symbol_atom.get(loc) orelse return;
43544329
4355 const atom = wasm.getAtom(atom_index);4330 const atom = wasm.getAtom(atom_index);
4356 for (atom.relocs.items) |reloc| {4331 for (atom.relocs.items) |reloc| {
src/link/Wasm/Atom.zig+4-11
...@@ -59,10 +59,7 @@ pub fn format(atom: Atom, comptime fmt: []const u8, options: std.fmt.FormatOptio...@@ -59,10 +59,7 @@ pub fn format(atom: Atom, comptime fmt: []const u8, options: std.fmt.FormatOptio
5959
60/// Returns the location of the symbol that represents this `Atom`60/// Returns the location of the symbol that represents this `Atom`
61pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc {61pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc {
62 if (atom.file == .null) {62 return .{ .file = atom.file, .index = atom.sym_index };
63 return .{ .file = null, .index = atom.sym_index };
64 }
65 return .{ .file = @intFromEnum(atom.file), .index = atom.sym_index };
66}63}
6764
68pub fn getSymbolIndex(atom: Atom) ?u32 {65pub fn getSymbolIndex(atom: Atom) ?u32 {
...@@ -83,7 +80,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {...@@ -83,7 +80,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
83 for (atom.relocs.items) |reloc| {80 for (atom.relocs.items) |reloc| {
84 const value = atom.relocationValue(reloc, wasm_bin);81 const value = atom.relocationValue(reloc, wasm_bin);
85 log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{82 log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{
86 (Wasm.SymbolLoc{ .file = @intFromEnum(atom.file), .index = reloc.index }).getName(wasm_bin),83 (Wasm.SymbolLoc{ .file = atom.file, .index = reloc.index }).getName(wasm_bin),
87 symbol_name,84 symbol_name,
88 reloc.offset,85 reloc.offset,
89 value,86 value,
...@@ -122,11 +119,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {...@@ -122,11 +119,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
122/// All values will be represented as a `u64` as all values can fit within it.119/// All values will be represented as a `u64` as all values can fit within it.
123/// The final value must be casted to the correct size.120/// The final value must be casted to the correct size.
124fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {121fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
125 const target_loc = if (atom.file == .null)122 const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin);
126 (Wasm.SymbolLoc{ .file = null, .index = relocation.index }).finalLoc(wasm_bin)
127 else
128 (Wasm.SymbolLoc{ .file = @intFromEnum(atom.file), .index = relocation.index }).finalLoc(wasm_bin);
129
130 const symbol = target_loc.getSymbol(wasm_bin);123 const symbol = target_loc.getSymbol(wasm_bin);
131 if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and124 if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and
132 symbol.tag != .section and125 symbol.tag != .section and
...@@ -142,7 +135,7 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa...@@ -142,7 +135,7 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
142 .R_WASM_TABLE_INDEX_I64,135 .R_WASM_TABLE_INDEX_I64,
143 .R_WASM_TABLE_INDEX_SLEB,136 .R_WASM_TABLE_INDEX_SLEB,
144 .R_WASM_TABLE_INDEX_SLEB64,137 .R_WASM_TABLE_INDEX_SLEB64,
145 => return wasm_bin.function_table.get(.{ .file = @intFromEnum(atom.file), .index = relocation.index }) orelse 0,138 => return wasm_bin.function_table.get(.{ .file = atom.file, .index = relocation.index }) orelse 0,
146 .R_WASM_TYPE_INDEX_LEB => {139 .R_WASM_TYPE_INDEX_LEB => {
147 const obj_file = wasm_bin.file(atom.file) orelse return relocation.index;140 const obj_file = wasm_bin.file(atom.file) orelse return relocation.index;
148 const original_type = obj_file.funcTypes()[relocation.index];141 const original_type = obj_file.funcTypes()[relocation.index];
src/link/Wasm/Object.zig+2-5
...@@ -952,7 +952,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato...@@ -952,7 +952,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato
952 .R_WASM_TABLE_INDEX_SLEB64,952 .R_WASM_TABLE_INDEX_SLEB64,
953 => {953 => {
954 try wasm.function_table.put(gpa, .{954 try wasm.function_table.put(gpa, .{
955 .file = @intFromEnum(object.index),955 .file = object.index,
956 .index = reloc.index,956 .index = reloc.index,
957 }, 0);957 }, 0);
958 },958 },
...@@ -961,10 +961,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato...@@ -961,10 +961,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato
961 => {961 => {
962 const sym = object.symtable[reloc.index];962 const sym = object.symtable[reloc.index];
963 if (sym.tag != .global) {963 if (sym.tag != .global) {
964 try wasm.got_symbols.append(964 try wasm.got_symbols.append(gpa, .{ .file = object.index, .index = reloc.index });
965 gpa,
966 .{ .file = @intFromEnum(object.index), .index = reloc.index },
967 );
968 }965 }
969 },966 },
970 else => {},967 else => {},
src/link/Wasm/ZigObject.zig+5-5
...@@ -468,7 +468,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {...@@ -468,7 +468,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
468fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {468fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
469 const symbol_index = zig_object.error_table_symbol orelse return;469 const symbol_index = zig_object.error_table_symbol orelse return;
470 const gpa = wasm_file.base.comp.gpa;470 const gpa = wasm_file.base.comp.gpa;
471 const atom_index = wasm_file.symbol_atom.get(.{ .file = null, .index = symbol_index }).?;471 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = symbol_index }).?;
472472
473 // Rather than creating a symbol for each individual error name,473 // Rather than creating a symbol for each individual error name,
474 // we create a symbol for the entire region of error names. We then calculate474 // we create a symbol for the entire region of error names. We then calculate
...@@ -633,7 +633,7 @@ pub fn getDeclVAddr(...@@ -633,7 +633,7 @@ pub fn getDeclVAddr(
633 const target_symbol_index = wasm_file.getAtom(target_atom_index).sym_index;633 const target_symbol_index = wasm_file.getAtom(target_atom_index).sym_index;
634634
635 std.debug.assert(reloc_info.parent_atom_index != 0);635 std.debug.assert(reloc_info.parent_atom_index != 0);
636 const atom_index = wasm_file.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;636 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = reloc_info.parent_atom_index }).?;
637 const atom = wasm_file.getAtomPtr(atom_index);637 const atom = wasm_file.getAtomPtr(atom_index);
638 const is_wasm32 = target.cpu.arch == .wasm32;638 const is_wasm32 = target.cpu.arch == .wasm32;
639 if (decl.ty.zigTypeTag(mod) == .Fn) {639 if (decl.ty.zigTypeTag(mod) == .Fn) {
...@@ -670,7 +670,7 @@ pub fn getAnonDeclVAddr(...@@ -670,7 +670,7 @@ pub fn getAnonDeclVAddr(
670 const atom_index = zig_object.anon_decls.get(decl_val).?;670 const atom_index = zig_object.anon_decls.get(decl_val).?;
671 const target_symbol_index = wasm_file.getAtom(atom_index).getSymbolIndex().?;671 const target_symbol_index = wasm_file.getAtom(atom_index).getSymbolIndex().?;
672672
673 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;673 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = reloc_info.parent_atom_index }).?;
674 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);674 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);
675 const is_wasm32 = target.cpu.arch == .wasm32;675 const is_wasm32 = target.cpu.arch == .wasm32;
676 const mod = wasm_file.base.comp.module.?;676 const mod = wasm_file.base.comp.module.?;
...@@ -705,7 +705,7 @@ pub fn deleteDeclExport(...@@ -705,7 +705,7 @@ pub fn deleteDeclExport(
705) void {705) void {
706 const atom_index = zig_object.decls.get(decl_index) orelse return;706 const atom_index = zig_object.decls.get(decl_index) orelse return;
707 const sym_index = wasm_file.getAtom(atom_index).sym_index;707 const sym_index = wasm_file.getAtom(atom_index).sym_index;
708 const loc: Wasm.SymbolLoc = .{ .file = null, .index = sym_index };708 const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = sym_index };
709 const sym = loc.getSymbol(wasm_file);709 const sym = loc.getSymbol(wasm_file);
710 std.debug.assert(zig_object.global_syms.remove(sym.name));710 std.debug.assert(zig_object.global_syms.remove(sym.name));
711}711}
...@@ -1161,7 +1161,7 @@ pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index:...@@ -1161,7 +1161,7 @@ pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index:
1161/// its relocations and create any GOT symbols or function table indexes it may require.1161/// its relocations and create any GOT symbols or function table indexes it may require.
1162pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) !Atom.Index {1162pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) !Atom.Index {
1163 const gpa = wasm_file.base.comp.gpa;1163 const gpa = wasm_file.base.comp.gpa;
1164 const loc: Wasm.SymbolLoc = .{ .file = @intFromEnum(zig_object.index), .index = index };1164 const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = index };
1165 const final_index = try wasm_file.getMatchingSegment(zig_object.index, index);1165 const final_index = try wasm_file.getMatchingSegment(zig_object.index, index);
1166 const atom_index = wasm_file.symbol_atom.get(loc).?;1166 const atom_index = wasm_file.symbol_atom.get(loc).?;
1167 try wasm_file.appendAtomAtIndex(final_index, atom_index);1167 try wasm_file.appendAtomAtIndex(final_index, atom_index);