authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-09 21:18:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-09 22:10:27+02:00
log8d44e031618a956a1b31c36b4c096a3000678a6b
treec19a3285f655e1130735f97f3ebc70e1bc675a9c
parent56b96cd61b0bdb7f5b11a5283fe6dd5b585ef10e

macho: use globals free list like in COFF linker


4 files changed, 150 insertions(+), 98 deletions(-)

src/link/MachO.zig+143-91
......@@ -131,17 +131,12 @@ la_symbol_ptr_section_index: ?u8 = null,
131131data_section_index: ?u8 = null,
132132
133133locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
134globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{},
135// FIXME Jakub
136// TODO storing index into globals might be dangerous if we delete a global
137// while not having everything resolved. Actually, perhaps `unresolved`
138// should not be stored at the global scope? Is this possible?
139// Otherwise, audit if this can be a problem.
140// An alternative, which I still need to investigate for perf reasons is to
141// store all global names in an adapted with context strtab.
134globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},
135resolver: std.StringHashMapUnmanaged(u32) = .{},
142136unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{},
143137
144138locals_free_list: std.ArrayListUnmanaged(u32) = .{},
139globals_free_list: std.ArrayListUnmanaged(u32) = .{},
145140
146141dyld_stub_binder_index: ?u32 = null,
147142dyld_private_atom: ?*Atom = null,
......@@ -1917,7 +1912,7 @@ fn allocateSpecialSymbols(self: *MachO) !void {
19171912 "___dso_handle",
19181913 "__mh_execute_header",
19191914 }) |name| {
1920 const global = self.globals.get(name) orelse continue;
1915 const global = self.getGlobal(name) orelse continue;
19211916 if (global.file != null) continue;
19221917 const sym = self.getSymbolPtr(global);
19231918 const seg = self.segments.items[self.text_segment_cmd_index.?];
......@@ -2074,7 +2069,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
20742069
20752070 const target_sym = self.getSymbol(target);
20762071 if (target_sym.undf()) {
2077 const global = self.globals.get(self.getSymbolName(target)).?;
2072 const global = self.getGlobal(self.getSymbolName(target)).?;
20782073 try atom.bindings.append(gpa, .{
20792074 .target = global,
20802075 .offset = 0,
......@@ -2106,7 +2101,7 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
21062101 const target_sym = self.getSymbol(target);
21072102 assert(target_sym.undf());
21082103
2109 const global = self.globals.get(self.getSymbolName(target)).?;
2104 const global = self.getGlobal(self.getSymbolName(target)).?;
21102105 try atom.bindings.append(gpa, .{
21112106 .target = global,
21122107 .offset = 0,
......@@ -2376,7 +2371,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi
23762371 });
23772372 try atom.rebases.append(gpa, 0);
23782373
2379 const global = self.globals.get(self.getSymbolName(target)).?;
2374 const global = self.getGlobal(self.getSymbolName(target)).?;
23802375 try atom.lazy_bindings.append(gpa, .{
23812376 .target = global,
23822377 .offset = 0,
......@@ -2472,7 +2467,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
24722467fn createTentativeDefAtoms(self: *MachO) !void {
24732468 const gpa = self.base.allocator;
24742469
2475 for (self.globals.values()) |global| {
2470 for (self.globals.items) |global| {
24762471 const sym = self.getSymbolPtr(global);
24772472 if (!sym.tentative()) continue;
24782473
......@@ -2516,25 +2511,22 @@ fn createTentativeDefAtoms(self: *MachO) !void {
25162511
25172512fn createMhExecuteHeaderSymbol(self: *MachO) !void {
25182513 if (self.base.options.output_mode != .Exe) return;
2519 if (self.globals.get("__mh_execute_header")) |global| {
2514 if (self.getGlobal("__mh_execute_header")) |global| {
25202515 const sym = self.getSymbol(global);
25212516 if (!sym.undf() and !(sym.pext() or sym.weakDef())) return;
25222517 }
25232518
25242519 const gpa = self.base.allocator;
2525 const n_strx = try self.strtab.insert(gpa, "__mh_execute_header");
2526 const sym_index = @intCast(u32, self.locals.items.len);
2527 try self.locals.append(gpa, .{
2528 .n_strx = n_strx,
2520 const sym_index = try self.allocateSymbol();
2521 self.locals.items[sym_index] = .{
2522 .n_strx = try self.strtab.insert(gpa, "__mh_execute_header"),
25292523 .n_type = macho.N_SECT | macho.N_EXT,
25302524 .n_sect = 0,
25312525 .n_desc = macho.REFERENCED_DYNAMICALLY,
25322526 .n_value = 0,
2533 });
2527 };
25342528
2535 const name = try gpa.dupe(u8, "__mh_execute_header");
2536 const gop = try self.globals.getOrPut(gpa, name);
2537 defer if (gop.found_existing) gpa.free(name);
2529 const gop = try self.getOrPutGlobalPtr("__mh_execute_header");
25382530 gop.value_ptr.* = .{
25392531 .sym_index = sym_index,
25402532 .file = null,
......@@ -2542,25 +2534,24 @@ fn createMhExecuteHeaderSymbol(self: *MachO) !void {
25422534}
25432535
25442536fn createDsoHandleSymbol(self: *MachO) !void {
2545 const global = self.globals.getPtr("___dso_handle") orelse return;
2537 const global = self.getGlobalPtr("___dso_handle") orelse return;
25462538 const sym = self.getSymbolPtr(global.*);
25472539 if (!sym.undf()) return;
25482540
25492541 const gpa = self.base.allocator;
2550 const n_strx = try self.strtab.insert(gpa, "___dso_handle");
2551 const sym_index = @intCast(u32, self.locals.items.len);
2552 try self.locals.append(gpa, .{
2553 .n_strx = n_strx,
2542 const sym_index = try self.allocateSymbol();
2543 self.locals.items[sym_index] = .{
2544 .n_strx = try self.strtab.insert(gpa, "___dso_handle"),
25542545 .n_type = macho.N_SECT | macho.N_EXT,
25552546 .n_sect = 0,
25562547 .n_desc = macho.N_WEAK_DEF,
25572548 .n_value = 0,
2558 });
2549 };
25592550 global.* = .{
25602551 .sym_index = sym_index,
25612552 .file = null,
25622553 };
2563 _ = self.unresolved.swapRemove(@intCast(u32, self.globals.getIndex("___dso_handle").?));
2554 _ = self.unresolved.swapRemove(self.getGlobalIndex("___dso_handle").?);
25642555}
25652556
25662557fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void {
......@@ -2568,19 +2559,14 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void {
25682559 const sym = self.getSymbol(current);
25692560 const sym_name = self.getSymbolName(current);
25702561
2571 const name = try gpa.dupe(u8, sym_name);
2572 const global_index = @intCast(u32, self.globals.values().len);
2573 const gop = try self.globals.getOrPut(gpa, name);
2574 defer if (gop.found_existing) gpa.free(name);
2575
2562 const gop = try self.getOrPutGlobalPtr(sym_name);
25762563 if (!gop.found_existing) {
25772564 gop.value_ptr.* = current;
25782565 if (sym.undf() and !sym.tentative()) {
2579 try self.unresolved.putNoClobber(gpa, global_index, false);
2566 try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, false);
25802567 }
25812568 return;
25822569 }
2583
25842570 const global = gop.value_ptr.*;
25852571 const global_sym = self.getSymbol(global);
25862572
......@@ -2619,7 +2605,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void {
26192605 }
26202606 if (sym.undf() and !sym.tentative()) return;
26212607
2622 _ = self.unresolved.swapRemove(@intCast(u32, self.globals.getIndex(name).?));
2608 _ = self.unresolved.swapRemove(self.getGlobalIndex(sym_name).?);
26232609
26242610 gop.value_ptr.* = current;
26252611}
......@@ -2664,7 +2650,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
26642650 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id };
26652651 self.resolveGlobalSymbol(sym_loc) catch |err| switch (err) {
26662652 error.MultipleSymbolDefinitions => {
2667 const global = self.globals.get(sym_name).?;
2653 const global = self.getGlobal(sym_name).?;
26682654 log.err("symbol '{s}' defined multiple times", .{sym_name});
26692655 if (global.file) |file| {
26702656 log.err(" first definition in '{s}'", .{self.objects.items[file].name});
......@@ -2684,7 +2670,8 @@ fn resolveSymbolsInArchives(self: *MachO) !void {
26842670 const cpu_arch = self.base.options.target.cpu.arch;
26852671 var next_sym: usize = 0;
26862672 loop: while (next_sym < self.unresolved.count()) {
2687 const global = self.globals.values()[self.unresolved.keys()[next_sym]];
2673 const global_index = self.unresolved.keys()[next_sym];
2674 const global = self.globals.items[global_index];
26882675 const sym_name = self.getSymbolName(global);
26892676
26902677 for (self.archives.items) |archive| {
......@@ -2710,10 +2697,11 @@ fn resolveSymbolsInArchives(self: *MachO) !void {
27102697fn resolveSymbolsInDylibs(self: *MachO) !void {
27112698 if (self.dylibs.items.len == 0) return;
27122699
2700 const gpa = self.base.allocator;
27132701 var next_sym: usize = 0;
27142702 loop: while (next_sym < self.unresolved.count()) {
27152703 const global_index = self.unresolved.keys()[next_sym];
2716 const global = self.globals.values()[global_index];
2704 const global = self.globals.items[global_index];
27172705 const sym = self.getSymbolPtr(global);
27182706 const sym_name = self.getSymbolName(global);
27192707
......@@ -2722,7 +2710,7 @@ fn resolveSymbolsInDylibs(self: *MachO) !void {
27222710
27232711 const dylib_id = @intCast(u16, id);
27242712 if (!self.referenced_dylibs.contains(dylib_id)) {
2725 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2713 try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {});
27262714 }
27272715
27282716 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
......@@ -2760,7 +2748,7 @@ fn resolveSymbolsAtLoading(self: *MachO) !void {
27602748 var next_sym: usize = 0;
27612749 while (next_sym < self.unresolved.count()) {
27622750 const global_index = self.unresolved.keys()[next_sym];
2763 const global = self.globals.values()[global_index];
2751 const global = self.globals.items[global_index];
27642752 const sym = self.getSymbolPtr(global);
27652753 const sym_name = self.getSymbolName(global);
27662754
......@@ -2800,26 +2788,29 @@ fn resolveDyldStubBinder(self: *MachO) !void {
28002788 if (self.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports
28012789
28022790 const gpa = self.base.allocator;
2803 const n_strx = try self.strtab.insert(gpa, "dyld_stub_binder");
2804 const sym_index = @intCast(u32, self.locals.items.len);
2805 try self.locals.append(gpa, .{
2806 .n_strx = n_strx,
2791 const sym_index = try self.allocateSymbol();
2792 const sym = &self.locals.items[sym_index];
2793 const sym_name = "dyld_stub_binder";
2794 sym.* = .{
2795 .n_strx = try self.strtab.insert(gpa, sym_name),
28072796 .n_type = macho.N_UNDF,
28082797 .n_sect = 0,
28092798 .n_desc = 0,
28102799 .n_value = 0,
2811 });
2812 const sym_name = try gpa.dupe(u8, "dyld_stub_binder");
2813 const global = SymbolWithLoc{ .sym_index = sym_index, .file = null };
2814 try self.globals.putNoClobber(gpa, sym_name, global);
2815 const sym = &self.locals.items[sym_index];
2800 };
2801 const gop = try self.getOrPutGlobalPtr(sym_name);
2802 gop.value_ptr.* = .{
2803 .sym_index = sym_index,
2804 .file = null,
2805 };
2806 const global = gop.value_ptr.*;
28162807
28172808 for (self.dylibs.items) |dylib, id| {
28182809 if (!dylib.symbols.contains(sym_name)) continue;
28192810
28202811 const dylib_id = @intCast(u16, id);
28212812 if (!self.referenced_dylibs.contains(dylib_id)) {
2822 try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
2813 try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {});
28232814 }
28242815
28252816 const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
......@@ -3050,14 +3041,20 @@ pub fn deinit(self: *MachO) void {
30503041 self.stubs_free_list.deinit(gpa);
30513042 self.stubs_table.deinit(gpa);
30523043 self.strtab.deinit(gpa);
3044
30533045 self.locals.deinit(gpa);
3046 self.globals.deinit(gpa);
30543047 self.locals_free_list.deinit(gpa);
3048 self.globals_free_list.deinit(gpa);
30553049 self.unresolved.deinit(gpa);
30563050
3057 for (self.globals.keys()) |key| {
3058 gpa.free(key);
3051 {
3052 var it = self.resolver.keyIterator();
3053 while (it.next()) |key_ptr| {
3054 gpa.free(key_ptr.*);
3055 }
3056 self.resolver.deinit(gpa);
30593057 }
3060 self.globals.deinit(gpa);
30613058
30623059 for (self.objects.items) |*object| {
30633060 object.deinit(gpa);
......@@ -3211,6 +3208,29 @@ fn allocateSymbol(self: *MachO) !u32 {
32113208 return index;
32123209}
32133210
3211fn allocateGlobal(self: *MachO) !u32 {
3212 try self.globals.ensureUnusedCapacity(self.base.allocator, 1);
3213
3214 const index = blk: {
3215 if (self.globals_free_list.popOrNull()) |index| {
3216 log.debug(" (reusing global index {d})", .{index});
3217 break :blk index;
3218 } else {
3219 log.debug(" (allocating symbol index {d})", .{self.globals.items.len});
3220 const index = @intCast(u32, self.globals.items.len);
3221 _ = self.globals.addOneAssumeCapacity();
3222 break :blk index;
3223 }
3224 };
3225
3226 self.globals.items[index] = .{
3227 .sym_index = 0,
3228 .file = null,
3229 };
3230
3231 return index;
3232}
3233
32143234pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 {
32153235 const gpa = self.base.allocator;
32163236 try self.got_entries.ensureUnusedCapacity(gpa, 1);
......@@ -3832,7 +3852,7 @@ pub fn updateDeclExports(
38323852
38333853 self.resolveGlobalSymbol(sym_loc) catch |err| switch (err) {
38343854 error.MultipleSymbolDefinitions => {
3835 const global = self.globals.get(exp_name).?;
3855 const global = self.getGlobal(exp_name).?;
38363856 if (sym_loc.sym_index != global.sym_index and global.file != null) {
38373857 _ = try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create(
38383858 gpa,
......@@ -3869,11 +3889,13 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
38693889 };
38703890 self.locals_free_list.append(gpa, sym_index) catch {};
38713891
3872 if (self.globals.get(sym_name)) |global| blk: {
3873 if (global.sym_index != sym_index) break :blk;
3874 if (global.file != null) break :blk;
3875 const kv = self.globals.fetchSwapRemove(sym_name);
3876 gpa.free(kv.?.key);
3892 if (self.resolver.fetchRemove(sym_name)) |entry| {
3893 defer gpa.free(entry.key);
3894 self.globals_free_list.append(gpa, entry.value) catch {};
3895 self.globals.items[entry.value] = .{
3896 .sym_index = 0,
3897 .file = null,
3898 };
38773899 }
38783900}
38793901
......@@ -4864,30 +4886,23 @@ pub fn addAtomToSection(self: *MachO, atom: *Atom, sect_id: u8) !void {
48644886
48654887pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 {
48664888 const gpa = self.base.allocator;
4889
48674890 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
4868 const global_index = @intCast(u32, self.globals.values().len);
4869 const gop = try self.globals.getOrPut(gpa, sym_name);
4870 defer if (gop.found_existing) gpa.free(sym_name);
4891 defer gpa.free(sym_name);
4892 const gop = try self.getOrPutGlobalPtr(sym_name);
48714893
48724894 if (gop.found_existing) {
4873 // TODO audit this: can we ever reference anything from outside the Zig module?
4874 assert(gop.value_ptr.file == null);
48754895 return gop.value_ptr.sym_index;
48764896 }
48774897
4878 const sym_index = @intCast(u32, self.locals.items.len);
4879 try self.locals.append(gpa, .{
4880 .n_strx = try self.strtab.insert(gpa, sym_name),
4881 .n_type = macho.N_UNDF,
4882 .n_sect = 0,
4883 .n_desc = 0,
4884 .n_value = 0,
4885 });
4886 gop.value_ptr.* = .{
4887 .sym_index = sym_index,
4888 .file = null,
4889 };
4890 try self.unresolved.putNoClobber(gpa, global_index, true);
4898 const sym_index = try self.allocateSymbol();
4899 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
4900 gop.value_ptr.* = sym_loc;
4901
4902 const sym = self.getSymbolPtr(sym_loc);
4903 sym.n_strx = try self.strtab.insert(gpa, sym_name);
4904
4905 try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, true);
48914906
48924907 return sym_index;
48934908}
......@@ -5055,7 +5070,7 @@ fn writeDyldInfoData(self: *MachO, ncmds: *u32, lc_writer: anytype) !void {
50555070 if (self.base.options.output_mode == .Exe) {
50565071 for (&[_]SymbolWithLoc{
50575072 try self.getEntryPoint(),
5058 self.globals.get("__mh_execute_header").?,
5073 self.getGlobal("__mh_execute_header").?,
50595074 }) |global| {
50605075 const sym = self.getSymbol(global);
50615076 const sym_name = self.getSymbolName(global);
......@@ -5068,7 +5083,7 @@ fn writeDyldInfoData(self: *MachO, ncmds: *u32, lc_writer: anytype) !void {
50685083 }
50695084 } else {
50705085 assert(self.base.options.output_mode == .Lib);
5071 for (self.globals.values()) |global| {
5086 for (self.globals.items) |global| {
50725087 const sym = self.getSymbol(global);
50735088
50745089 if (sym.undf()) continue;
......@@ -5271,9 +5286,9 @@ fn writeFunctionStarts(self: *MachO, ncmds: *u32, lc_writer: anytype) !void {
52715286 // We need to sort by address first
52725287 var addresses = std.ArrayList(u64).init(gpa);
52735288 defer addresses.deinit();
5274 try addresses.ensureTotalCapacityPrecise(self.globals.count());
5289 try addresses.ensureTotalCapacityPrecise(self.globals.items.len);
52755290
5276 for (self.globals.values()) |global| {
5291 for (self.globals.items) |global| {
52775292 const sym = self.getSymbol(global);
52785293 if (sym.undf()) continue;
52795294 if (sym.n_desc == N_DESC_GCED) continue;
......@@ -5453,7 +5468,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx {
54535468 if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip
54545469 const sym_loc = SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null };
54555470 if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip
5456 if (self.globals.contains(self.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip
5471 if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip
54575472 try locals.append(sym);
54585473 }
54595474
......@@ -5463,7 +5478,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx {
54635478 if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip
54645479 const sym_loc = SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = @intCast(u32, object_id) };
54655480 if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip
5466 if (self.globals.contains(self.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip
5481 if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip
54675482 var out_sym = sym;
54685483 out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(sym_loc));
54695484 try locals.append(out_sym);
......@@ -5477,7 +5492,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx {
54775492 var exports = std.ArrayList(macho.nlist_64).init(gpa);
54785493 defer exports.deinit();
54795494
5480 for (self.globals.values()) |global| {
5495 for (self.globals.items) |global| {
54815496 const sym = self.getSymbol(global);
54825497 if (sym.undf()) continue; // import, skip
54835498 if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip
......@@ -5491,7 +5506,7 @@ fn writeSymtab(self: *MachO, lc: *macho.symtab_command) !SymtabCtx {
54915506
54925507 var imports_table = std.AutoHashMap(SymbolWithLoc, u32).init(gpa);
54935508
5494 for (self.globals.values()) |global| {
5509 for (self.globals.items) |global| {
54955510 const sym = self.getSymbol(global);
54965511 if (sym.n_strx == 0) continue; // no name, skip
54975512 if (!sym.undf()) continue; // not an import, skip
......@@ -5798,6 +5813,43 @@ pub fn getSymbolName(self: *MachO, sym_with_loc: SymbolWithLoc) []const u8 {
57985813 }
57995814}
58005815
5816/// Returns pointer to the global entry for `name` if one exists.
5817pub fn getGlobalPtr(self: *MachO, name: []const u8) ?*SymbolWithLoc {
5818 const global_index = self.resolver.get(name) orelse return null;
5819 return &self.globals.items[global_index];
5820}
5821
5822/// Returns the global entry for `name` if one exists.
5823pub fn getGlobal(self: *const MachO, name: []const u8) ?SymbolWithLoc {
5824 const global_index = self.resolver.get(name) orelse return null;
5825 return self.globals.items[global_index];
5826}
5827
5828/// Returns the index of the global entry for `name` if one exists.
5829pub fn getGlobalIndex(self: *const MachO, name: []const u8) ?u32 {
5830 return self.resolver.get(name);
5831}
5832
5833const GetOrPutGlobalPtrResult = struct {
5834 found_existing: bool,
5835 value_ptr: *SymbolWithLoc,
5836};
5837
5838/// Return pointer to the global entry for `name` if one exists.
5839/// Puts a new global entry for `name` if one doesn't exist, and
5840/// returns a pointer to it.
5841pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResult {
5842 if (self.getGlobalPtr(name)) |ptr| {
5843 return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr };
5844 }
5845 const gpa = self.base.allocator;
5846 const global_index = try self.allocateGlobal();
5847 const global_name = try gpa.dupe(u8, name);
5848 _ = try self.resolver.put(gpa, global_name, global_index);
5849 const ptr = &self.globals.items[global_index];
5850 return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr };
5851}
5852
58015853/// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor.
58025854/// Returns null on failure.
58035855pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom {
......@@ -5834,7 +5886,7 @@ pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom
58345886/// Asserts output mode is executable.
58355887pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
58365888 const entry_name = self.base.options.entry orelse "_main";
5837 const global = self.globals.get(entry_name) orelse {
5889 const global = self.getGlobal(entry_name) orelse {
58385890 log.err("entrypoint '{s}' not found", .{entry_name});
58395891 return error.MissingMainEntrypoint;
58405892 };
......@@ -6342,9 +6394,9 @@ fn logSymtab(self: *MachO) void {
63426394 }
63436395
63446396 log.debug("globals table:", .{});
6345 for (self.globals.keys()) |name, id| {
6346 const value = self.globals.values()[id];
6347 log.debug(" {s} => %{d} in object({?d})", .{ name, value.sym_index, value.file });
6397 for (self.globals.items) |global| {
6398 const name = self.getSymbolName(global);
6399 log.debug(" {s} => %{d} in object({?d})", .{ name, global.sym_index, global.file });
63486400 }
63496401
63506402 log.debug("GOT entries:", .{});
src/link/MachO/Atom.zig+3-3
......@@ -272,7 +272,7 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info,
272272 subtractor = sym_loc;
273273 } else {
274274 const sym_name = context.macho_file.getSymbolName(sym_loc);
275 subtractor = context.macho_file.globals.get(sym_name).?;
275 subtractor = context.macho_file.getGlobal(sym_name).?;
276276 }
277277 // Verify that *_SUBTRACTOR is followed by *_UNSIGNED.
278278 if (relocs.len <= i + 1) {
......@@ -339,7 +339,7 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info,
339339 break :target sym_loc;
340340 } else {
341341 const sym_name = context.macho_file.getSymbolName(sym_loc);
342 break :target context.macho_file.globals.get(sym_name).?;
342 break :target context.macho_file.getGlobal(sym_name).?;
343343 }
344344 };
345345 const offset = @intCast(u32, rel.r_address - context.base_offset);
......@@ -579,7 +579,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
579579 // If there is no atom for target, we still need to check for special, atom-less
580580 // symbols such as `___dso_handle`.
581581 const target_name = macho_file.getSymbolName(rel.target);
582 assert(macho_file.globals.contains(target_name));
582 assert(macho_file.getGlobal(target_name) != null);
583583 const atomless_sym = macho_file.getSymbol(rel.target);
584584 log.debug(" | atomless target '{s}'", .{target_name});
585585 break :blk atomless_sym.n_value;
src/link/MachO/DebugSymbols.zig+2-2
......@@ -480,7 +480,7 @@ fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {
480480 if (sym.n_desc == MachO.N_DESC_GCED) continue; // GCed, skip
481481 const sym_loc = MachO.SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null };
482482 if (self.base.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip
483 if (self.base.globals.contains(self.base.getSymbolName(sym_loc))) continue; // global symbol is either an export or import, skip
483 if (self.base.getGlobal(self.base.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip
484484 var out_sym = sym;
485485 out_sym.n_strx = try self.strtab.insert(gpa, self.base.getSymbolName(sym_loc));
486486 try locals.append(out_sym);
......@@ -489,7 +489,7 @@ fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {
489489 var exports = std.ArrayList(macho.nlist_64).init(gpa);
490490 defer exports.deinit();
491491
492 for (self.base.globals.values()) |global| {
492 for (self.base.globals.items) |global| {
493493 const sym = self.base.getSymbol(global);
494494 if (sym.undf()) continue; // import, skip
495495 if (sym.n_desc == MachO.N_DESC_GCED) continue; // GCed, skip
src/link/MachO/dead_strip.zig+2-2
......@@ -62,7 +62,7 @@ fn collectRoots(roots: *std.AutoHashMap(*Atom, void), macho_file: *MachO) !void
6262 else => |other| {
6363 assert(other == .Lib);
6464 // Add exports as GC roots
65 for (macho_file.globals.values()) |global| {
65 for (macho_file.globals.items) |global| {
6666 const sym = macho_file.getSymbol(global);
6767 if (!sym.sect()) continue;
6868 const atom = macho_file.getAtomForSymbol(global) orelse {
......@@ -77,7 +77,7 @@ fn collectRoots(roots: *std.AutoHashMap(*Atom, void), macho_file: *MachO) !void
7777 }
7878
7979 // TODO just a temp until we learn how to parse unwind records
80 if (macho_file.globals.get("___gxx_personality_v0")) |global| {
80 if (macho_file.getGlobal("___gxx_personality_v0")) |global| {
8181 if (macho_file.getAtomForSymbol(global)) |atom| {
8282 _ = try roots.getOrPut(atom);
8383 log.debug("adding root", .{});