From 8d44e031618a956a1b31c36b4c096a3000678a6b Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 9 Sep 2022 21:18:39 +0200 Subject: [PATCH] macho: use globals free list like in COFF linker --- src/link/MachO.zig | 234 +++++++++++++++++++------------- src/link/MachO/Atom.zig | 6 +- src/link/MachO/DebugSymbols.zig | 4 +- src/link/MachO/dead_strip.zig | 4 +- 4 files changed, 150 insertions(+), 98 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 429bf64eb2..12d8326f35 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -131,17 +131,12 @@ la_symbol_ptr_section_index: ?u8 = null, data_section_index: ?u8 = null, locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, -globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{}, -// FIXME Jakub -// TODO storing index into globals might be dangerous if we delete a global -// while not having everything resolved. Actually, perhaps `unresolved` -// should not be stored at the global scope? Is this possible? -// Otherwise, audit if this can be a problem. -// An alternative, which I still need to investigate for perf reasons is to -// store all global names in an adapted with context strtab. +globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, +resolver: std.StringHashMapUnmanaged(u32) = .{}, unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, locals_free_list: std.ArrayListUnmanaged(u32) = .{}, +globals_free_list: std.ArrayListUnmanaged(u32) = .{}, dyld_stub_binder_index: ?u32 = null, dyld_private_atom: ?*Atom = null, @@ -1917,7 +1912,7 @@ fn allocateSpecialSymbols(self: *MachO) !void { "___dso_handle", "__mh_execute_header", }) |name| { - const global = self.globals.get(name) orelse continue; + const global = self.getGlobal(name) orelse continue; if (global.file != null) continue; const sym = self.getSymbolPtr(global); const seg = self.segments.items[self.text_segment_cmd_index.?]; @@ -2074,7 +2069,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { const target_sym = self.getSymbol(target); if (target_sym.undf()) { - const global = self.globals.get(self.getSymbolName(target)).?; + const global = self.getGlobal(self.getSymbolName(target)).?; try atom.bindings.append(gpa, .{ .target = global, .offset = 0, @@ -2106,7 +2101,7 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom { const target_sym = self.getSymbol(target); assert(target_sym.undf()); - const global = self.globals.get(self.getSymbolName(target)).?; + const global = self.getGlobal(self.getSymbolName(target)).?; try atom.bindings.append(gpa, .{ .target = global, .offset = 0, @@ -2376,7 +2371,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi }); try atom.rebases.append(gpa, 0); - const global = self.globals.get(self.getSymbolName(target)).?; + const global = self.getGlobal(self.getSymbolName(target)).?; try atom.lazy_bindings.append(gpa, .{ .target = global, .offset = 0, @@ -2472,7 +2467,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { fn createTentativeDefAtoms(self: *MachO) !void { const gpa = self.base.allocator; - for (self.globals.values()) |global| { + for (self.globals.items) |global| { const sym = self.getSymbolPtr(global); if (!sym.tentative()) continue; @@ -2516,25 +2511,22 @@ fn createTentativeDefAtoms(self: *MachO) !void { fn createMhExecuteHeaderSymbol(self: *MachO) !void { if (self.base.options.output_mode != .Exe) return; - if (self.globals.get("__mh_execute_header")) |global| { + if (self.getGlobal("__mh_execute_header")) |global| { const sym = self.getSymbol(global); if (!sym.undf() and !(sym.pext() or sym.weakDef())) return; } const gpa = self.base.allocator; - const n_strx = try self.strtab.insert(gpa, "__mh_execute_header"); - const sym_index = @intCast(u32, self.locals.items.len); - try self.locals.append(gpa, .{ - .n_strx = n_strx, + const sym_index = try self.allocateSymbol(); + self.locals.items[sym_index] = .{ + .n_strx = try self.strtab.insert(gpa, "__mh_execute_header"), .n_type = macho.N_SECT | macho.N_EXT, .n_sect = 0, .n_desc = macho.REFERENCED_DYNAMICALLY, .n_value = 0, - }); + }; - const name = try gpa.dupe(u8, "__mh_execute_header"); - const gop = try self.globals.getOrPut(gpa, name); - defer if (gop.found_existing) gpa.free(name); + const gop = try self.getOrPutGlobalPtr("__mh_execute_header"); gop.value_ptr.* = .{ .sym_index = sym_index, .file = null, @@ -2542,25 +2534,24 @@ fn createMhExecuteHeaderSymbol(self: *MachO) !void { } fn createDsoHandleSymbol(self: *MachO) !void { - const global = self.globals.getPtr("___dso_handle") orelse return; + const global = self.getGlobalPtr("___dso_handle") orelse return; const sym = self.getSymbolPtr(global.*); if (!sym.undf()) return; const gpa = self.base.allocator; - const n_strx = try self.strtab.insert(gpa, "___dso_handle"); - const sym_index = @intCast(u32, self.locals.items.len); - try self.locals.append(gpa, .{ - .n_strx = n_strx, + const sym_index = try self.allocateSymbol(); + self.locals.items[sym_index] = .{ + .n_strx = try self.strtab.insert(gpa, "___dso_handle"), .n_type = macho.N_SECT | macho.N_EXT, .n_sect = 0, .n_desc = macho.N_WEAK_DEF, .n_value = 0, - }); + }; global.* = .{ .sym_index = sym_index, .file = null, }; - _ = self.unresolved.swapRemove(@intCast(u32, self.globals.getIndex("___dso_handle").?)); + _ = self.unresolved.swapRemove(self.getGlobalIndex("___dso_handle").?); } fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { @@ -2568,19 +2559,14 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { const sym = self.getSymbol(current); const sym_name = self.getSymbolName(current); - const name = try gpa.dupe(u8, sym_name); - const global_index = @intCast(u32, self.globals.values().len); - const gop = try self.globals.getOrPut(gpa, name); - defer if (gop.found_existing) gpa.free(name); - + const gop = try self.getOrPutGlobalPtr(sym_name); if (!gop.found_existing) { gop.value_ptr.* = current; if (sym.undf() and !sym.tentative()) { - try self.unresolved.putNoClobber(gpa, global_index, false); + try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, false); } return; } - const global = gop.value_ptr.*; const global_sym = self.getSymbol(global); @@ -2619,7 +2605,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { } if (sym.undf() and !sym.tentative()) return; - _ = self.unresolved.swapRemove(@intCast(u32, self.globals.getIndex(name).?)); + _ = self.unresolved.swapRemove(self.getGlobalIndex(sym_name).?); gop.value_ptr.* = current; } @@ -2664,7 +2650,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id }; self.resolveGlobalSymbol(sym_loc) catch |err| switch (err) { error.MultipleSymbolDefinitions => { - const global = self.globals.get(sym_name).?; + const global = self.getGlobal(sym_name).?; log.err("symbol '{s}' defined multiple times", .{sym_name}); if (global.file) |file| { log.err(" first definition in '{s}'", .{self.objects.items[file].name}); @@ -2684,7 +2670,8 @@ fn resolveSymbolsInArchives(self: *MachO) !void { const cpu_arch = self.base.options.target.cpu.arch; var next_sym: usize = 0; loop: while (next_sym < self.unresolved.count()) { - const global = self.globals.values()[self.unresolved.keys()[next_sym]]; + const global_index = self.unresolved.keys()[next_sym]; + const global = self.globals.items[global_index]; const sym_name = self.getSymbolName(global); for (self.archives.items) |archive| { @@ -2710,10 +2697,11 @@ fn resolveSymbolsInArchives(self: *MachO) !void { fn resolveSymbolsInDylibs(self: *MachO) !void { if (self.dylibs.items.len == 0) return; + const gpa = self.base.allocator; var next_sym: usize = 0; loop: while (next_sym < self.unresolved.count()) { const global_index = self.unresolved.keys()[next_sym]; - const global = self.globals.values()[global_index]; + const global = self.globals.items[global_index]; const sym = self.getSymbolPtr(global); const sym_name = self.getSymbolName(global); @@ -2722,7 +2710,7 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { const dylib_id = @intCast(u16, id); if (!self.referenced_dylibs.contains(dylib_id)) { - try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {}); + try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {}); } const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; @@ -2760,7 +2748,7 @@ fn resolveSymbolsAtLoading(self: *MachO) !void { var next_sym: usize = 0; while (next_sym < self.unresolved.count()) { const global_index = self.unresolved.keys()[next_sym]; - const global = self.globals.values()[global_index]; + const global = self.globals.items[global_index]; const sym = self.getSymbolPtr(global); const sym_name = self.getSymbolName(global); @@ -2800,26 +2788,29 @@ fn resolveDyldStubBinder(self: *MachO) !void { if (self.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports const gpa = self.base.allocator; - const n_strx = try self.strtab.insert(gpa, "dyld_stub_binder"); - const sym_index = @intCast(u32, self.locals.items.len); - try self.locals.append(gpa, .{ - .n_strx = n_strx, + const sym_index = try self.allocateSymbol(); + const sym = &self.locals.items[sym_index]; + const sym_name = "dyld_stub_binder"; + sym.* = .{ + .n_strx = try self.strtab.insert(gpa, sym_name), .n_type = macho.N_UNDF, .n_sect = 0, .n_desc = 0, .n_value = 0, - }); - const sym_name = try gpa.dupe(u8, "dyld_stub_binder"); - const global = SymbolWithLoc{ .sym_index = sym_index, .file = null }; - try self.globals.putNoClobber(gpa, sym_name, global); - const sym = &self.locals.items[sym_index]; + }; + const gop = try self.getOrPutGlobalPtr(sym_name); + gop.value_ptr.* = .{ + .sym_index = sym_index, + .file = null, + }; + const global = gop.value_ptr.*; for (self.dylibs.items) |dylib, id| { if (!dylib.symbols.contains(sym_name)) continue; const dylib_id = @intCast(u16, id); if (!self.referenced_dylibs.contains(dylib_id)) { - try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {}); + try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {}); } const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; @@ -3050,14 +3041,20 @@ pub fn deinit(self: *MachO) void { self.stubs_free_list.deinit(gpa); self.stubs_table.deinit(gpa); self.strtab.deinit(gpa); + self.locals.deinit(gpa); + self.globals.deinit(gpa); self.locals_free_list.deinit(gpa); + self.globals_free_list.deinit(gpa); self.unresolved.deinit(gpa); - for (self.globals.keys()) |key| { - gpa.free(key); + { + var it = self.resolver.keyIterator(); + while (it.next()) |key_ptr| { + gpa.free(key_ptr.*); + } + self.resolver.deinit(gpa); } - self.globals.deinit(gpa); for (self.objects.items) |*object| { object.deinit(gpa); @@ -3211,6 +3208,29 @@ fn allocateSymbol(self: *MachO) !u32 { return index; } +fn allocateGlobal(self: *MachO) !u32 { + try self.globals.ensureUnusedCapacity(self.base.allocator, 1); + + const index = blk: { + if (self.globals_free_list.popOrNull()) |index| { + log.debug(" (reusing global index {d})", .{index}); + break :blk index; + } else { + log.debug(" (allocating symbol index {d})", .{self.globals.items.len}); + const index = @intCast(u32, self.globals.items.len); + _ = self.globals.addOneAssumeCapacity(); + break :blk index; + } + }; + + self.globals.items[index] = .{ + .sym_index = 0, + .file = null, + }; + + return index; +} + pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { const gpa = self.base.allocator; try self.got_entries.ensureUnusedCapacity(gpa, 1); @@ -3832,7 +3852,7 @@ pub fn updateDeclExports( self.resolveGlobalSymbol(sym_loc) catch |err| switch (err) { error.MultipleSymbolDefinitions => { - const global = self.globals.get(exp_name).?; + const global = self.getGlobal(exp_name).?; if (sym_loc.sym_index != global.sym_index and global.file != null) { _ = try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create( gpa, @@ -3869,11 +3889,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void { }; self.locals_free_list.append(gpa, sym_index) catch {}; - if (self.globals.get(sym_name)) |global| blk: { - if (global.sym_index != sym_index) break :blk; - if (global.file != null) break :blk; - const kv = self.globals.fetchSwapRemove(sym_name); - gpa.free(kv.?.key); + if (self.resolver.fetchRemove(sym_name)) |entry| { + defer gpa.free(entry.key); + self.globals_free_list.append(gpa, entry.value) catch {}; + self.globals.items[entry.value] = .{ + .sym_index = 0, + .file = null, + }; } } @@ -4864,30 +4886,23 @@ pub fn addAtomToSection(self: *MachO, atom: *Atom, sect_id: u8) !void { pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { const gpa = self.base.allocator; + const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); - const global_index = @intCast(u32, self.globals.values().len); - const gop = try self.globals.getOrPut(gpa, sym_name); - defer if (gop.found_existing) gpa.free(sym_name); + defer gpa.free(sym_name); + const gop = try self.getOrPutGlobalPtr(sym_name); if (gop.found_existing) { - // TODO audit this: can we ever reference anything from outside the Zig module? - assert(gop.value_ptr.file == null); return gop.value_ptr.sym_index; } - const sym_index = @intCast(u32, self.locals.items.len); - try self.locals.append(gpa, .{ - .n_strx = try self.strtab.insert(gpa, sym_name), - .n_type = macho.N_UNDF, - .n_sect = 0, - .n_desc = 0, - .n_value = 0, - }); - gop.value_ptr.* = .{ - .sym_index = sym_index, - .file = null, - }; - try self.unresolved.putNoClobber(gpa, global_index, true); + const sym_index = try self.allocateSymbol(); + const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; + gop.value_ptr.* = sym_loc; + + const sym = self.getSymbolPtr(sym_loc); + sym.n_strx = try self.strtab.insert(gpa, sym_name); + + try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, true); return sym_index; } @@ -5055,7 +5070,7 @@ fn writeDyldInfoData(self: *MachO, ncmds: *u32, lc_writer: anytype) !void { if (self.base.options.output_mode == .Exe) { for (&[_]SymbolWithLoc{ try self.getEntryPoint(), - self.globals.get("__mh_execute_header").?, + self.getGlobal("__mh_execute_header").?, }) |global| { const sym = self.getSymbol(global); const sym_name = self.getSymbolName(global); @@ -5068,7 +5083,7 @@ fn writeDyldInfoData(self: *MachO, ncmds: *u32, lc_writer: anytype) !void { } } else { assert(self.base.options.output_mode == .Lib); - for (self.globals.values()) |global| { + for (self.globals.items) |global| { const sym = self.getSymbol(global); if (sym.undf()) continue; @@ -5271,9 +5286,9 @@ fn writeFunctionStarts(self: *MachO, ncmds: *u32, lc_writer: anytype) !void { // We need to sort by address first var addresses = std.ArrayList(u64).init(gpa); defer addresses.deinit(); - try addresses.ensureTotalCapacityPrecise(self.globals.count()); + try addresses.ensureTotalCapacityPrecise(self.globals.items.len); - for (self.globals.values()) |global| { + for (self.globals.items) |global| { const sym = self.getSymbol(global); if (sym.undf()) continue; if (sym.n_desc == N_DESC_GCED) continue; @@ -5453,7 +5468,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx { if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip const sym_loc = SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null }; if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip - if (self.globals.contains(self.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip + if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip try locals.append(sym); } @@ -5463,7 +5478,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx { if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip const sym_loc = SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = @intCast(u32, object_id) }; if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip - if (self.globals.contains(self.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip + if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip var out_sym = sym; out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(sym_loc)); try locals.append(out_sym); @@ -5477,7 +5492,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx { var exports = std.ArrayList(macho.nlist_64).init(gpa); defer exports.deinit(); - for (self.globals.values()) |global| { + for (self.globals.items) |global| { const sym = self.getSymbol(global); if (sym.undf()) continue; // import, skip if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip @@ -5491,7 +5506,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx { var imports_table = std.AutoHashMap(SymbolWithLoc, u32).init(gpa); - for (self.globals.values()) |global| { + for (self.globals.items) |global| { const sym = self.getSymbol(global); if (sym.n_strx == 0) continue; // no name, skip if (!sym.undf()) continue; // not an import, skip @@ -5798,6 +5813,43 @@ pub fn getSymbolName(self: *MachO, sym_with_loc: SymbolWithLoc) []const u8 { } } +/// Returns pointer to the global entry for `name` if one exists. +pub fn getGlobalPtr(self: *MachO, name: []const u8) ?*SymbolWithLoc { + const global_index = self.resolver.get(name) orelse return null; + return &self.globals.items[global_index]; +} + +/// Returns the global entry for `name` if one exists. +pub fn getGlobal(self: *const MachO, name: []const u8) ?SymbolWithLoc { + const global_index = self.resolver.get(name) orelse return null; + return self.globals.items[global_index]; +} + +/// Returns the index of the global entry for `name` if one exists. +pub fn getGlobalIndex(self: *const MachO, name: []const u8) ?u32 { + return self.resolver.get(name); +} + +const GetOrPutGlobalPtrResult = struct { + found_existing: bool, + value_ptr: *SymbolWithLoc, +}; + +/// Return pointer to the global entry for `name` if one exists. +/// Puts a new global entry for `name` if one doesn't exist, and +/// returns a pointer to it. +pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResult { + if (self.getGlobalPtr(name)) |ptr| { + return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr }; + } + const gpa = self.base.allocator; + const global_index = try self.allocateGlobal(); + const global_name = try gpa.dupe(u8, name); + _ = try self.resolver.put(gpa, global_name, global_index); + const ptr = &self.globals.items[global_index]; + return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; +} + /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. /// Returns null on failure. pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { @@ -5834,7 +5886,7 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom /// Asserts output mode is executable. pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { const entry_name = self.base.options.entry orelse "_main"; - const global = self.globals.get(entry_name) orelse { + const global = self.getGlobal(entry_name) orelse { log.err("entrypoint '{s}' not found", .{entry_name}); return error.MissingMainEntrypoint; }; @@ -6342,9 +6394,9 @@ fn logSymtab(self: *MachO) void { } log.debug("globals table:", .{}); - for (self.globals.keys()) |name, id| { - const value = self.globals.values()[id]; - log.debug(" {s} => %{d} in object({?d})", .{ name, value.sym_index, value.file }); + for (self.globals.items) |global| { + const name = self.getSymbolName(global); + log.debug(" {s} => %{d} in object({?d})", .{ name, global.sym_index, global.file }); } log.debug("GOT entries:", .{}); diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index dd818ea936..5b242a2013 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -272,7 +272,7 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info, subtractor = sym_loc; } else { const sym_name = context.macho_file.getSymbolName(sym_loc); - subtractor = context.macho_file.globals.get(sym_name).?; + subtractor = context.macho_file.getGlobal(sym_name).?; } // Verify that *_SUBTRACTOR is followed by *_UNSIGNED. if (relocs.len <= i + 1) { @@ -339,7 +339,7 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info, break :target sym_loc; } else { const sym_name = context.macho_file.getSymbolName(sym_loc); - break :target context.macho_file.globals.get(sym_name).?; + break :target context.macho_file.getGlobal(sym_name).?; } }; const offset = @intCast(u32, rel.r_address - context.base_offset); @@ -579,7 +579,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { // If there is no atom for target, we still need to check for special, atom-less // symbols such as `___dso_handle`. const target_name = macho_file.getSymbolName(rel.target); - assert(macho_file.globals.contains(target_name)); + assert(macho_file.getGlobal(target_name) != null); const atomless_sym = macho_file.getSymbol(rel.target); log.debug(" | atomless target '{s}'", .{target_name}); break :blk atomless_sym.n_value; diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig index ffff0fe5f8..a991ba8882 100644 --- a/src/link/MachO/DebugSymbols.zig +++ b/src/link/MachO/DebugSymbols.zig @@ -480,7 +480,7 @@ fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void { if (sym.n_desc == MachO.N_DESC_GCED) continue; // GCed, skip const sym_loc = MachO.SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null }; if (self.base.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip - if (self.base.globals.contains(self.base.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip + if (self.base.getGlobal(self.base.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip var out_sym = sym; out_sym.n_strx = try self.strtab.insert(gpa, self.base.getSymbolName(sym_loc)); try locals.append(out_sym); @@ -489,7 +489,7 @@ fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void { var exports = std.ArrayList(macho.nlist_64).init(gpa); defer exports.deinit(); - for (self.base.globals.values()) |global| { + for (self.base.globals.items) |global| { const sym = self.base.getSymbol(global); if (sym.undf()) continue; // import, skip if (sym.n_desc == MachO.N_DESC_GCED) continue; // GCed, skip diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index eb2be6e5fe..c8c4950730 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -62,7 +62,7 @@ fn collectRoots(roots: *std.AutoHashMap(*Atom, void), macho_file: *MachO) !void else => |other| { assert(other == .Lib); // Add exports as GC roots - for (macho_file.globals.values()) |global| { + for (macho_file.globals.items) |global| { const sym = macho_file.getSymbol(global); if (!sym.sect()) continue; const atom = macho_file.getAtomForSymbol(global) orelse { @@ -77,7 +77,7 @@ fn collectRoots(roots: *std.AutoHashMap(*Atom, void), macho_file: *MachO) !void } // TODO just a temp until we learn how to parse unwind records - if (macho_file.globals.get("___gxx_personality_v0")) |global| { + if (macho_file.getGlobal("___gxx_personality_v0")) |global| { if (macho_file.getAtomForSymbol(global)) |atom| { _ = try roots.getOrPut(atom); log.debug("adding root", .{});