authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-05 12:43:31+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-13 11:47:51+02:00
logef645ab1754d6117d06cf2296de689605546f5f7
treebd78f226f49a7c9dd07e0b1464431f180f7d237a
parent38ecaf3ab6c71aae213edbd38b8f661a03035b3a

macho: refactor common logic between synthetic tables


3 files changed, 147 insertions(+), 161 deletions(-)

src/link/MachO.zig+132-142
...@@ -5,7 +5,6 @@ const build_options = @import("build_options");...@@ -5,7 +5,6 @@ const build_options = @import("build_options");
5const builtin = @import("builtin");5const builtin = @import("builtin");
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const dwarf = std.dwarf;7const dwarf = std.dwarf;
8const fmt = std.fmt;
9const fs = std.fs;8const fs = std.fs;
10const log = std.log.scoped(.link);9const log = std.log.scoped(.link);
11const macho = std.macho;10const macho = std.macho;
...@@ -155,13 +154,9 @@ stub_helper_preamble_atom_index: ?Atom.Index = null,...@@ -155,13 +154,9 @@ stub_helper_preamble_atom_index: ?Atom.Index = null,
155154
156strtab: StringTable(.strtab) = .{},155strtab: StringTable(.strtab) = .{},
157156
158got_entries: std.ArrayListUnmanaged(Entry) = .{},157got_table: SectionTable = .{},
159got_entries_free_list: std.ArrayListUnmanaged(u32) = .{},158stubs_table: SectionTable = .{},
160got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},159tlvp_table: SectionTable = .{},
161
162stubs: std.ArrayListUnmanaged(Entry) = .{},
163stubs_free_list: std.ArrayListUnmanaged(u32) = .{},
164stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
165160
166error_flags: File.ErrorFlags = File.ErrorFlags{},161error_flags: File.ErrorFlags = File.ErrorFlags{},
167162
...@@ -270,26 +265,120 @@ const DeclMetadata = struct {...@@ -270,26 +265,120 @@ const DeclMetadata = struct {
270 }265 }
271};266};
272267
273const Entry = struct {268const SectionTable = struct {
274 target: SymbolWithLoc,269 entries: std.ArrayListUnmanaged(Entry) = .{},
275 // Index into the synthetic symbol table (i.e., file == null).270 free_list: std.ArrayListUnmanaged(u32) = .{},
276 sym_index: u32,271 lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
272
273 pub fn deinit(st: *ST, allocator: Allocator) void {
274 st.entries.deinit(allocator);
275 st.free_list.deinit(allocator);
276 st.lookup.deinit(allocator);
277 }
278
279 pub fn allocateEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) !u32 {
280 try st.entries.ensureUnusedCapacity(allocator, 1);
281 const index = blk: {
282 if (st.free_list.popOrNull()) |index| {
283 log.debug(" (reusing entry index {d})", .{index});
284 break :blk index;
285 } else {
286 log.debug(" (allocating entry at index {d})", .{st.entries.items.len});
287 const index = @intCast(u32, st.entries.items.len);
288 _ = st.entries.addOneAssumeCapacity();
289 break :blk index;
290 }
291 };
292 st.entries.items[index] = .{ .target = target, .sym_index = 0 };
293 try st.lookup.putNoClobber(allocator, target, index);
294 return index;
295 }
277296
278 pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 {297 pub fn freeEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) void {
279 return macho_file.getSymbol(.{ .sym_index = entry.sym_index, .file = null });298 const index = st.lookup.get(target) orelse return;
299 st.free_list.append(allocator, index) catch {};
300 st.entries.items[index] = .{
301 .target = .{ .sym_index = 0 },
302 .sym_index = 0,
303 };
304 _ = st.lookup.remove(target);
280 }305 }
281306
282 pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 {307 pub fn getAtomIndex(st: *const ST, macho_file: *MachO, target: SymbolWithLoc) ?Atom.Index {
283 return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null });308 const index = st.lookup.get(target) orelse return null;
309 return st.entries.items[index].getAtomIndex(macho_file);
310 }
311
312 const FormatContext = struct {
313 macho_file: *MachO,
314 st: *const ST,
315 };
316
317 fn fmt(
318 ctx: FormatContext,
319 comptime unused_format_string: []const u8,
320 options: std.fmt.FormatOptions,
321 writer: anytype,
322 ) @TypeOf(writer).Error!void {
323 _ = options;
324 comptime assert(unused_format_string.len == 0);
325 try writer.writeAll("SectionTable:\n");
326 for (ctx.st.entries.items, 0..) |entry, i| {
327 const atom_sym = entry.getSymbol(ctx.macho_file);
328 const target_sym = ctx.macho_file.getSymbol(entry.target);
329 try writer.print(" {d}@{x} => ", .{ i, atom_sym.n_value });
330 if (target_sym.undf()) {
331 try writer.print("import('{s}')", .{
332 ctx.macho_file.getSymbolName(entry.target),
333 });
334 } else {
335 try writer.print("local(%{d}) in object({?d})", .{
336 entry.target.sym_index,
337 entry.target.file,
338 });
339 }
340 try writer.writeByte('\n');
341 }
284 }342 }
285343
286 pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index {344 fn format(st: *const ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
287 return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index, .file = null });345 _ = st;
346 _ = unused_format_string;
347 _ = options;
348 _ = writer;
349 @compileError("do not format SectionTable directly; use st.fmtDebug()");
288 }350 }
289351
290 pub fn getName(entry: Entry, macho_file: *MachO) []const u8 {352 pub fn fmtDebug(st: *const ST, macho_file: *MachO) std.fmt.Formatter(fmt) {
291 return macho_file.getSymbolName(.{ .sym_index = entry.sym_index, .file = null });353 return .{ .data = .{
354 .macho_file = macho_file,
355 .st = st,
356 } };
292 }357 }
358
359 const ST = @This();
360
361 const Entry = struct {
362 target: SymbolWithLoc,
363 // Index into the synthetic symbol table (i.e., file == null).
364 sym_index: u32,
365
366 pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 {
367 return macho_file.getSymbol(.{ .sym_index = entry.sym_index });
368 }
369
370 pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 {
371 return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index });
372 }
373
374 pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index {
375 return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index });
376 }
377
378 pub fn getName(entry: Entry, macho_file: *MachO) []const u8 {
379 return macho_file.getSymbolName(.{ .sym_index = entry.sym_index });
380 }
381 };
293};382};
294383
295const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding));384const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding));
...@@ -399,7 +488,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -399,7 +488,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
399 // Create dSYM bundle.488 // Create dSYM bundle.
400 log.debug("creating {s}.dSYM bundle", .{sub_path});489 log.debug("creating {s}.dSYM bundle", .{sub_path});
401490
402 const d_sym_path = try fmt.allocPrint(491 const d_sym_path = try std.fmt.allocPrint(
403 allocator,492 allocator,
404 "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",493 "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
405 .{sub_path},494 .{sub_path},
...@@ -613,9 +702,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -613,9 +702,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
613 if (self.dyld_stub_binder_index == null) {702 if (self.dyld_stub_binder_index == null) {
614 self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got);703 self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got);
615 }704 }
616 if (!self.base.options.single_threaded) {705 // if (!self.base.options.single_threaded) {
617 _ = try self.addUndefined("_tlv_bootstrap", .none);706 // _ = try self.addUndefined("_tlv_bootstrap", .none);
618 }707 // }
619708
620 try self.createMhExecuteHeaderSymbol();709 try self.createMhExecuteHeaderSymbol();
621710
...@@ -1757,12 +1846,9 @@ pub fn deinit(self: *MachO) void {...@@ -1757,12 +1846,9 @@ pub fn deinit(self: *MachO) void {
1757 d_sym.deinit();1846 d_sym.deinit();
1758 }1847 }
17591848
1760 self.got_entries.deinit(gpa);1849 self.got_table.deinit(gpa);
1761 self.got_entries_free_list.deinit(gpa);
1762 self.got_entries_table.deinit(gpa);
1763 self.stubs.deinit(gpa);
1764 self.stubs_free_list.deinit(gpa);
1765 self.stubs_table.deinit(gpa);1850 self.stubs_table.deinit(gpa);
1851 self.tlvp_table.deinit(gpa);
1766 self.strtab.deinit(gpa);1852 self.strtab.deinit(gpa);
17671853
1768 self.locals.deinit(gpa);1854 self.locals.deinit(gpa);
...@@ -1895,20 +1981,10 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void {...@@ -1895,20 +1981,10 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
1895 self.locals_free_list.append(gpa, sym_index) catch {};1981 self.locals_free_list.append(gpa, sym_index) catch {};
18961982
1897 // Try freeing GOT atom if this decl had one1983 // Try freeing GOT atom if this decl had one
1898 const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };1984 self.got_table.freeEntry(gpa, .{ .sym_index = sym_index });
1899 if (self.got_entries_table.get(got_target)) |got_index| {
1900 self.got_entries_free_list.append(gpa, @intCast(u32, got_index)) catch {};
1901 self.got_entries.items[got_index] = .{
1902 .target = .{ .sym_index = 0, .file = null },
1903 .sym_index = 0,
1904 };
1905 _ = self.got_entries_table.remove(got_target);
1906
1907 if (self.d_sym) |*d_sym| {
1908 d_sym.swapRemoveRelocs(sym_index);
1909 }
19101985
1911 log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index });1986 if (self.d_sym) |*d_sym| {
1987 d_sym.swapRemoveRelocs(sym_index);
1912 }1988 }
19131989
1914 self.locals.items[sym_index].n_type = 0;1990 self.locals.items[sym_index].n_type = 0;
...@@ -1983,70 +2059,25 @@ fn allocateGlobal(self: *MachO) !u32 {...@@ -1983,70 +2059,25 @@ fn allocateGlobal(self: *MachO) !u32 {
1983 return index;2059 return index;
1984}2060}
19852061
1986fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 {
1987 const gpa = self.base.allocator;
1988 try self.got_entries.ensureUnusedCapacity(gpa, 1);
1989
1990 const index = blk: {
1991 if (self.got_entries_free_list.popOrNull()) |index| {
1992 log.debug(" (reusing GOT entry index {d})", .{index});
1993 break :blk index;
1994 } else {
1995 log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.items.len});
1996 const index = @intCast(u32, self.got_entries.items.len);
1997 _ = self.got_entries.addOneAssumeCapacity();
1998 break :blk index;
1999 }
2000 };
2001
2002 self.got_entries.items[index] = .{ .target = target, .sym_index = 0 };
2003 try self.got_entries_table.putNoClobber(gpa, target, index);
2004
2005 return index;
2006}
2007
2008fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {2062fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
2009 if (self.got_entries_table.contains(target)) return;2063 if (self.got_table.lookup.contains(target)) return;
20102064 const got_index = try self.got_table.allocateEntry(self.base.allocator, target);
2011 const got_index = try self.allocateGotEntry(target);
2012 const got_atom_index = try self.createGotAtom(target);2065 const got_atom_index = try self.createGotAtom(target);
2013 const got_atom = self.getAtom(got_atom_index);2066 const got_atom = self.getAtom(got_atom_index);
2014 self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;2067 self.got_table.entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
2015 try self.writePtrWidthAtom(got_atom_index);2068 try self.writePtrWidthAtom(got_atom_index);
2016}2069}
20172070
2018fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 {
2019 try self.stubs.ensureUnusedCapacity(self.base.allocator, 1);
2020
2021 const index = blk: {
2022 if (self.stubs_free_list.popOrNull()) |index| {
2023 log.debug(" (reusing stub entry index {d})", .{index});
2024 break :blk index;
2025 } else {
2026 log.debug(" (allocating stub entry at index {d})", .{self.stubs.items.len});
2027 const index = @intCast(u32, self.stubs.items.len);
2028 _ = self.stubs.addOneAssumeCapacity();
2029 break :blk index;
2030 }
2031 };
2032
2033 self.stubs.items[index] = .{ .target = target, .sym_index = 0 };
2034 try self.stubs_table.putNoClobber(self.base.allocator, target, index);
2035
2036 return index;
2037}
2038
2039fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {2071fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
2040 if (self.stubs_table.contains(target)) return;2072 if (self.stubs_table.lookup.contains(target)) return;
20412073 const stub_index = try self.stubs_table.allocateEntry(self.base.allocator, target);
2042 const stub_index = try self.allocateStubEntry(target);
2043 const stub_helper_atom_index = try self.createStubHelperAtom();2074 const stub_helper_atom_index = try self.createStubHelperAtom();
2044 const stub_helper_atom = self.getAtom(stub_helper_atom_index);2075 const stub_helper_atom = self.getAtom(stub_helper_atom_index);
2045 const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target);2076 const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target);
2046 const laptr_atom = self.getAtom(laptr_atom_index);2077 const laptr_atom = self.getAtom(laptr_atom_index);
2047 const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?);2078 const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?);
2048 const stub_atom = self.getAtom(stub_atom_index);2079 const stub_atom = self.getAtom(stub_atom_index);
2049 self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?;2080 self.stubs_table.entries.items[stub_index].sym_index = stub_atom.getSymbolIndex().?;
2050 self.markRelocsDirtyByTarget(target);2081 self.markRelocsDirtyByTarget(target);
2051}2082}
20522083
...@@ -2431,7 +2462,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2431,7 +2462,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
2431 sym.n_value = vaddr;2462 sym.n_value = vaddr;
2432 log.debug(" (updating GOT entry)", .{});2463 log.debug(" (updating GOT entry)", .{});
2433 const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };2464 const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
2434 const got_atom_index = self.getGotAtomIndexForSymbol(got_target).?;2465 const got_atom_index = self.got_table.getAtomIndex(self, got_target).?;
2435 self.markRelocsDirtyByTarget(got_target);2466 self.markRelocsDirtyByTarget(got_target);
2436 try self.writePtrWidthAtom(got_atom_index);2467 try self.writePtrWidthAtom(got_atom_index);
2437 }2468 }
...@@ -3481,8 +3512,8 @@ const SymtabCtx = struct {...@@ -3481,8 +3512,8 @@ const SymtabCtx = struct {
34813512
3482fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {3513fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
3483 const gpa = self.base.allocator;3514 const gpa = self.base.allocator;
3484 const nstubs = @intCast(u32, self.stubs_table.count());3515 const nstubs = @intCast(u32, self.stubs_table.lookup.count());
3485 const ngot_entries = @intCast(u32, self.got_entries_table.count());3516 const ngot_entries = @intCast(u32, self.got_table.lookup.count());
3486 const nindirectsyms = nstubs * 2 + ngot_entries;3517 const nindirectsyms = nstubs * 2 + ngot_entries;
3487 const iextdefsym = ctx.nlocalsym;3518 const iextdefsym = ctx.nlocalsym;
3488 const iundefsym = iextdefsym + ctx.nextdefsym;3519 const iundefsym = iextdefsym + ctx.nextdefsym;
...@@ -3504,7 +3535,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {...@@ -3504,7 +3535,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
3504 if (self.stubs_section_index) |sect_id| {3535 if (self.stubs_section_index) |sect_id| {
3505 const stubs = &self.sections.items(.header)[sect_id];3536 const stubs = &self.sections.items(.header)[sect_id];
3506 stubs.reserved1 = 0;3537 stubs.reserved1 = 0;
3507 for (self.stubs.items) |entry| {3538 for (self.stubs_table.entries.items) |entry| {
3508 if (entry.sym_index == 0) continue;3539 if (entry.sym_index == 0) continue;
3509 const target_sym = self.getSymbol(entry.target);3540 const target_sym = self.getSymbol(entry.target);
3510 assert(target_sym.undf());3541 assert(target_sym.undf());
...@@ -3515,7 +3546,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {...@@ -3515,7 +3546,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
3515 if (self.got_section_index) |sect_id| {3546 if (self.got_section_index) |sect_id| {
3516 const got = &self.sections.items(.header)[sect_id];3547 const got = &self.sections.items(.header)[sect_id];
3517 got.reserved1 = nstubs;3548 got.reserved1 = nstubs;
3518 for (self.got_entries.items) |entry| {3549 for (self.got_table.entries.items) |entry| {
3519 if (entry.sym_index == 0) continue;3550 if (entry.sym_index == 0) continue;
3520 const target_sym = self.getSymbol(entry.target);3551 const target_sym = self.getSymbol(entry.target);
3521 if (target_sym.undf()) {3552 if (target_sym.undf()) {
...@@ -3529,7 +3560,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {...@@ -3529,7 +3560,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
3529 if (self.la_symbol_ptr_section_index) |sect_id| {3560 if (self.la_symbol_ptr_section_index) |sect_id| {
3530 const la_symbol_ptr = &self.sections.items(.header)[sect_id];3561 const la_symbol_ptr = &self.sections.items(.header)[sect_id];
3531 la_symbol_ptr.reserved1 = nstubs + ngot_entries;3562 la_symbol_ptr.reserved1 = nstubs + ngot_entries;
3532 for (self.stubs.items) |entry| {3563 for (self.stubs_table.entries.items) |entry| {
3533 if (entry.sym_index == 0) continue;3564 if (entry.sym_index == 0) continue;
3534 const target_sym = self.getSymbol(entry.target);3565 const target_sym = self.getSymbol(entry.target);
3535 assert(target_sym.undf());3566 assert(target_sym.undf());
...@@ -3874,20 +3905,6 @@ pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.In...@@ -3874,20 +3905,6 @@ pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.In
3874 return self.atom_by_index_table.get(sym_with_loc.sym_index);3905 return self.atom_by_index_table.get(sym_with_loc.sym_index);
3875}3906}
38763907
3877/// Returns GOT atom that references `sym_with_loc` if one exists.
3878/// Returns null otherwise.
3879pub fn getGotAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index {
3880 const got_index = self.got_entries_table.get(sym_with_loc) orelse return null;
3881 return self.got_entries.items[got_index].getAtomIndex(self);
3882}
3883
3884/// Returns stubs atom that references `sym_with_loc` if one exists.
3885/// Returns null otherwise.
3886pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index {
3887 const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null;
3888 return self.stubs.items[stubs_index].getAtomIndex(self);
3889}
3890
3891/// Returns symbol location corresponding to the set entrypoint.3908/// Returns symbol location corresponding to the set entrypoint.
3892/// Asserts output mode is executable.3909/// Asserts output mode is executable.
3893pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {3910pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
...@@ -4234,37 +4251,10 @@ pub fn logSymtab(self: *MachO) void {...@@ -4234,37 +4251,10 @@ pub fn logSymtab(self: *MachO) void {
4234 }4251 }
42354252
4236 log.debug("GOT entries:", .{});4253 log.debug("GOT entries:", .{});
4237 for (self.got_entries.items, 0..) |entry, i| {4254 log.debug("{}", .{self.got_table.fmtDebug(self)});
4238 const atom_sym = entry.getSymbol(self);
4239 const target_sym = self.getSymbol(entry.target);
4240 if (target_sym.undf()) {
4241 log.debug(" {d}@{x} => import('{s}')", .{
4242 i,
4243 atom_sym.n_value,
4244 self.getSymbolName(entry.target),
4245 });
4246 } else {
4247 log.debug(" {d}@{x} => local(%{d}) in object({?d}) {s}", .{
4248 i,
4249 atom_sym.n_value,
4250 entry.target.sym_index,
4251 entry.target.file,
4252 logSymAttributes(target_sym, &buf),
4253 });
4254 }
4255 }
42564255
4257 log.debug("stubs entries:", .{});4256 log.debug("stubs entries:", .{});
4258 for (self.stubs.items, 0..) |entry, i| {4257 log.debug("{}", .{self.stubs_table.fmtDebug(self)});
4259 const target_sym = self.getSymbol(entry.target);
4260 const atom_sym = entry.getSymbol(self);
4261 assert(target_sym.undf());
4262 log.debug(" {d}@{x} => import('{s}')", .{
4263 i,
4264 atom_sym.n_value,
4265 self.getSymbolName(entry.target),
4266 });
4267 }
4268}4258}
42694259
4270pub fn logAtoms(self: *MachO) void {4260pub fn logAtoms(self: *MachO) void {
src/link/MachO/DebugSymbols.zig+6-12
...@@ -226,26 +226,20 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -226,26 +226,20 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
226226
227 for (self.relocs.items) |*reloc| {227 for (self.relocs.items) |*reloc| {
228 const sym = switch (reloc.type) {228 const sym = switch (reloc.type) {
229 .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target, .file = null }),229 .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target }),
230 .got_load => blk: {230 .got_load => blk: {
231 const got_index = macho_file.got_entries_table.get(.{231 const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
232 .sym_index = reloc.target,232 const got_entry = macho_file.got_table.entries.items[got_index];
233 .file = null,
234 }).?;
235 const got_entry = macho_file.got_entries.items[got_index];
236 break :blk got_entry.getSymbol(macho_file);233 break :blk got_entry.getSymbol(macho_file);
237 },234 },
238 };235 };
239 if (sym.n_value == reloc.prev_vaddr) continue;236 if (sym.n_value == reloc.prev_vaddr) continue;
240237
241 const sym_name = switch (reloc.type) {238 const sym_name = switch (reloc.type) {
242 .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target, .file = null }),239 .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target }),
243 .got_load => blk: {240 .got_load => blk: {
244 const got_index = macho_file.got_entries_table.get(.{241 const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
245 .sym_index = reloc.target,242 const got_entry = macho_file.got_table.entries.items[got_index];
246 .file = null,
247 }).?;
248 const got_entry = macho_file.got_entries.items[got_index];
249 break :blk got_entry.getName(macho_file);243 break :blk got_entry.getName(macho_file);
250 },244 },
251 };245 };
src/link/MachO/Relocation.zig+9-7
...@@ -46,13 +46,15 @@ pub fn isResolvable(self: Relocation, macho_file: *MachO) bool {...@@ -46,13 +46,15 @@ pub fn isResolvable(self: Relocation, macho_file: *MachO) bool {
46}46}
4747
48pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index {48pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index {
49 switch (self.type) {49 return switch (self.type) {
50 .got, .got_page, .got_pageoff => return macho_file.getGotAtomIndexForSymbol(self.target),50 .got, .got_page, .got_pageoff => macho_file.got_table.getAtomIndex(macho_file, self.target),
51 .tlv, .tlv_page, .tlv_pageoff => return macho_file.getTlvpAtomIndexForSymbol(self.target),51 .tlv, .tlv_page, .tlv_pageoff => macho_file.tlvp_table.getAtomIndex(macho_file, self.target),
52 else => {},52 .branch => if (macho_file.stubs_table.getAtomIndex(macho_file, self.target)) |index|
53 }53 index
54 if (macho_file.getStubsAtomIndexForSymbol(self.target)) |stubs_atom| return stubs_atom;54 else
55 return macho_file.getAtomIndexForSymbol(self.target);55 macho_file.getAtomIndexForSymbol(self.target),
56 else => macho_file.getAtomIndexForSymbol(self.target),
57 };
56}58}
5759
58pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {60pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {