diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index 632bba12e6..2c775824c5 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -61,6 +61,10 @@ pub const Regular = struct { size: u64, } = null, + /// True if symbol was already committed into the final + /// symbol table. + visited: bool = false, + pub const base_type: Symbol.Type = .regular; pub const Linkage = enum { diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 191f63fe52..d248d283b6 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -1194,6 +1194,10 @@ fn allocateTentativeSymbols(self: *Zld) !void { .section = section, .weak_ref = false, .file = tent.file, + .stab = .{ + .kind = .global, + .size = 0, + }, }; try self.globals.putNoClobber(self.allocator, reg.base.name, ®.base); @@ -2772,8 +2776,17 @@ fn writeDebugInfo(self: *Zld) !void { }); for (object.symbols.items) |sym| { - if (sym.@"type" != .regular) continue; - const reg = sym.cast(Symbol.Regular) orelse unreachable; + const reg = reg: { + switch (sym.@"type") { + .regular => break :reg sym.cast(Symbol.Regular) orelse unreachable, + .tentative => { + const final = sym.getTopmostAlias().cast(Symbol.Regular) orelse unreachable; + if (object != final.file) continue; + break :reg final; + }, + else => continue, + } + }; if (reg.isTemp() or reg.stab == null) continue; const stab = reg.stab orelse unreachable; @@ -2877,6 +2890,7 @@ fn writeSymbolTable(self: *Zld) !void { const reg = final.cast(Symbol.Regular) orelse unreachable; if (reg.isTemp()) continue; + if (reg.visited) continue; switch (reg.linkage) { .translation_unit => { @@ -2898,6 +2912,8 @@ fn writeSymbolTable(self: *Zld) !void { }); }, } + + reg.visited = true; } }