| ... | @@ -3439,12 +3439,13 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3439,12 +3439,13 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3439 | | 3439 | |
| 3440 | try wasm.setupInitFunctions(); | 3440 | try wasm.setupInitFunctions(); |
| 3441 | try wasm.setupStart(); | 3441 | try wasm.setupStart(); |
| 3442 | try wasm.setupImports(); | | |
| 3443 | | 3442 | |
| 3444 | for (wasm.objects.items, 0..) |*object, object_index| { | 3443 | for (wasm.objects.items, 0..) |*object, object_index| { |
| 3445 | try object.parseIntoAtoms(gpa, @as(u16, @intCast(object_index)), wasm); | 3444 | try object.parseIntoAtoms(gpa, @as(u16, @intCast(object_index)), wasm); |
| 3446 | } | 3445 | } |
| 3447 | | 3446 | |
| | 3447 | wasm.markReferences(); |
| | 3448 | try wasm.setupImports(); |
| 3448 | try wasm.allocateAtoms(); | 3449 | try wasm.allocateAtoms(); |
| 3449 | try wasm.setupMemory(); | 3450 | try wasm.setupMemory(); |
| 3450 | wasm.allocateVirtualAddresses(); | 3451 | wasm.allocateVirtualAddresses(); |
| ... | @@ -3529,6 +3530,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3529,6 +3530,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3529 | try wasm.setupInitFunctions(); | 3530 | try wasm.setupInitFunctions(); |
| 3530 | try wasm.setupErrorsLen(); | 3531 | try wasm.setupErrorsLen(); |
| 3531 | try wasm.setupStart(); | 3532 | try wasm.setupStart(); |
| | 3533 | wasm.markReferences(); |
| 3532 | try wasm.setupImports(); | 3534 | try wasm.setupImports(); |
| 3533 | if (wasm.base.options.module) |mod| { | 3535 | if (wasm.base.options.module) |mod| { |
| 3534 | var decl_it = wasm.decls.iterator(); | 3536 | var decl_it = wasm.decls.iterator(); |
| ... | @@ -5026,3 +5028,38 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s | ... | @@ -5026,3 +5028,38 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s |
| 5026 | try wasm.atom_types.put(wasm.base.allocator, atom_index, index); | 5028 | try wasm.atom_types.put(wasm.base.allocator, atom_index, index); |
| 5027 | return index; | 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 | } |