| ... | ... | @@ -3439,12 +3439,13 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3439 | 3439 | |
| 3440 | 3440 | try wasm.setupInitFunctions(); |
| 3441 | 3441 | try wasm.setupStart(); |
| 3442 | | try wasm.setupImports(); |
| 3443 | 3442 | |
| 3444 | 3443 | for (wasm.objects.items, 0..) |*object, object_index| { |
| 3445 | 3444 | try object.parseIntoAtoms(gpa, @as(u16, @intCast(object_index)), wasm); |
| 3446 | 3445 | } |
| 3447 | 3446 | |
| 3447 | wasm.markReferences(); |
| 3448 | try wasm.setupImports(); |
| 3448 | 3449 | try wasm.allocateAtoms(); |
| 3449 | 3450 | try wasm.setupMemory(); |
| 3450 | 3451 | wasm.allocateVirtualAddresses(); |
| ... | ... | @@ -3529,6 +3530,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3529 | 3530 | try wasm.setupInitFunctions(); |
| 3530 | 3531 | try wasm.setupErrorsLen(); |
| 3531 | 3532 | try wasm.setupStart(); |
| 3533 | wasm.markReferences(); |
| 3532 | 3534 | try wasm.setupImports(); |
| 3533 | 3535 | if (wasm.base.options.module) |mod| { |
| 3534 | 3536 | var decl_it = wasm.decls.iterator(); |
| ... | ... | @@ -5026,3 +5028,38 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s |
| 5026 | 5028 | try wasm.atom_types.put(wasm.base.allocator, atom_index, index); |
| 5027 | 5029 | return index; |
| 5028 | 5030 | } |
| 5031 | |
| 5032 | /// Verifies all resolved symbols and checks whether itself needs to be marked alive, |
| 5033 | /// as well as any of its references. |
| 5034 | fn markReferences(wasm: *Wasm) void { |
| 5035 | const tracy = trace(@src()); |
| 5036 | defer tracy.end(); |
| 5037 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 5038 | const sym = sym_loc.getSymbol(wasm); |
| 5039 | if (sym.isExported(wasm.base.options.rdynamic) or sym.isNoStrip()) { |
| 5040 | wasm.mark(sym_loc); |
| 5041 | } |
| 5042 | } |
| 5043 | } |
| 5044 | |
| 5045 | /// Marks a symbol as 'alive' recursively so itself and any references it contains to |
| 5046 | /// other symbols will not be omit from the binary. |
| 5047 | fn mark(wasm: *Wasm, loc: SymbolLoc) void { |
| 5048 | const symbol = loc.getSymbol(wasm); |
| 5049 | if (symbol.isAlive()) { |
| 5050 | // Symbol is already marked alive, including its references. |
| 5051 | // This means we can skip it so we don't end up marking the same symbols |
| 5052 | // multiple times. |
| 5053 | return; |
| 5054 | } |
| 5055 | symbol.mark(); |
| 5056 | |
| 5057 | if (wasm.symbol_atom.get(loc)) |atom_index| { |
| 5058 | const atom = wasm.getAtom(atom_index); |
| 5059 | const relocations: []const types.Relocation = atom.relocs.items; |
| 5060 | for (relocations) |reloc| { |
| 5061 | const target_loc: SymbolLoc = .{ .index = reloc.index, .file = loc.file }; |
| 5062 | wasm.mark(target_loc.finalLoc(wasm)); |
| 5063 | } |
| 5064 | } |
| 5065 | } |