| ... | ... | @@ -5,7 +5,6 @@ const build_options = @import("build_options"); |
| 5 | 5 | const builtin = @import("builtin"); |
| 6 | 6 | const assert = std.debug.assert; |
| 7 | 7 | const dwarf = std.dwarf; |
| 8 | | const fmt = std.fmt; |
| 9 | 8 | const fs = std.fs; |
| 10 | 9 | const log = std.log.scoped(.link); |
| 11 | 10 | const macho = std.macho; |
| ... | ... | @@ -155,13 +154,9 @@ stub_helper_preamble_atom_index: ?Atom.Index = null, |
| 155 | 154 | |
| 156 | 155 | strtab: StringTable(.strtab) = .{}, |
| 157 | 156 | |
| 158 | | got_entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 159 | | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 160 | | got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 161 | | |
| 162 | | stubs: std.ArrayListUnmanaged(Entry) = .{}, |
| 163 | | stubs_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 164 | | stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 157 | got_table: SectionTable = .{}, |
| 158 | stubs_table: SectionTable = .{}, |
| 159 | tlvp_table: SectionTable = .{}, |
| 165 | 160 | |
| 166 | 161 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 167 | 162 | |
| ... | ... | @@ -270,26 +265,120 @@ const DeclMetadata = struct { |
| 270 | 265 | } |
| 271 | 266 | }; |
| 272 | 267 | |
| 273 | | const Entry = struct { |
| 274 | | target: SymbolWithLoc, |
| 275 | | // Index into the synthetic symbol table (i.e., file == null). |
| 276 | | sym_index: u32, |
| 268 | const SectionTable = struct { |
| 269 | entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 270 | free_list: std.ArrayListUnmanaged(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 | } |
| 277 | 296 | |
| 278 | | pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 { |
| 279 | | return macho_file.getSymbol(.{ .sym_index = entry.sym_index, .file = null }); |
| 297 | pub fn freeEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) void { |
| 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 | } |
| 281 | 306 | |
| 282 | | pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 { |
| 283 | | return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null }); |
| 307 | pub fn getAtomIndex(st: *const ST, macho_file: *MachO, target: SymbolWithLoc) ?Atom.Index { |
| 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 | } |
| 285 | 343 | |
| 286 | | pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index { |
| 287 | | return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index, .file = null }); |
| 344 | fn format(st: *const ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 345 | _ = st; |
| 346 | _ = unused_format_string; |
| 347 | _ = options; |
| 348 | _ = writer; |
| 349 | @compileError("do not format SectionTable directly; use st.fmtDebug()"); |
| 288 | 350 | } |
| 289 | 351 | |
| 290 | | pub fn getName(entry: Entry, macho_file: *MachO) []const u8 { |
| 291 | | return macho_file.getSymbolName(.{ .sym_index = entry.sym_index, .file = null }); |
| 352 | pub fn fmtDebug(st: *const ST, macho_file: *MachO) std.fmt.Formatter(fmt) { |
| 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 | }; |
| 294 | 383 | |
| 295 | 384 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); |
| ... | ... | @@ -399,7 +488,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { |
| 399 | 488 | // Create dSYM bundle. |
| 400 | 489 | log.debug("creating {s}.dSYM bundle", .{sub_path}); |
| 401 | 490 | |
| 402 | | const d_sym_path = try fmt.allocPrint( |
| 491 | const d_sym_path = try std.fmt.allocPrint( |
| 403 | 492 | allocator, |
| 404 | 493 | "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", |
| 405 | 494 | .{sub_path}, |
| ... | ... | @@ -613,9 +702,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 613 | 702 | if (self.dyld_stub_binder_index == null) { |
| 614 | 703 | self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got); |
| 615 | 704 | } |
| 616 | | if (!self.base.options.single_threaded) { |
| 617 | | _ = try self.addUndefined("_tlv_bootstrap", .none); |
| 618 | | } |
| 705 | // if (!self.base.options.single_threaded) { |
| 706 | // _ = try self.addUndefined("_tlv_bootstrap", .none); |
| 707 | // } |
| 619 | 708 | |
| 620 | 709 | try self.createMhExecuteHeaderSymbol(); |
| 621 | 710 | |
| ... | ... | @@ -1757,12 +1846,9 @@ pub fn deinit(self: *MachO) void { |
| 1757 | 1846 | d_sym.deinit(); |
| 1758 | 1847 | } |
| 1759 | 1848 | |
| 1760 | | self.got_entries.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); |
| 1849 | self.got_table.deinit(gpa); |
| 1765 | 1850 | self.stubs_table.deinit(gpa); |
| 1851 | self.tlvp_table.deinit(gpa); |
| 1766 | 1852 | self.strtab.deinit(gpa); |
| 1767 | 1853 | |
| 1768 | 1854 | self.locals.deinit(gpa); |
| ... | ... | @@ -1895,20 +1981,10 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void { |
| 1895 | 1981 | self.locals_free_list.append(gpa, sym_index) catch {}; |
| 1896 | 1982 | |
| 1897 | 1983 | // Try freeing GOT atom if this decl had one |
| 1898 | | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 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 | | } |
| 1984 | self.got_table.freeEntry(gpa, .{ .sym_index = sym_index }); |
| 1910 | 1985 | |
| 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 | } |
| 1913 | 1989 | |
| 1914 | 1990 | self.locals.items[sym_index].n_type = 0; |
| ... | ... | @@ -1983,70 +2059,25 @@ fn allocateGlobal(self: *MachO) !u32 { |
| 1983 | 2059 | return index; |
| 1984 | 2060 | } |
| 1985 | 2061 | |
| 1986 | | fn 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 | | |
| 2008 | 2062 | fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2009 | | if (self.got_entries_table.contains(target)) return; |
| 2010 | | |
| 2011 | | const got_index = try self.allocateGotEntry(target); |
| 2063 | if (self.got_table.lookup.contains(target)) return; |
| 2064 | const got_index = try self.got_table.allocateEntry(self.base.allocator, target); |
| 2012 | 2065 | const got_atom_index = try self.createGotAtom(target); |
| 2013 | 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 | 2068 | try self.writePtrWidthAtom(got_atom_index); |
| 2016 | 2069 | } |
| 2017 | 2070 | |
| 2018 | | fn 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 | | |
| 2039 | 2071 | fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2040 | | if (self.stubs_table.contains(target)) return; |
| 2041 | | |
| 2042 | | const stub_index = try self.allocateStubEntry(target); |
| 2072 | if (self.stubs_table.lookup.contains(target)) return; |
| 2073 | const stub_index = try self.stubs_table.allocateEntry(self.base.allocator, target); |
| 2043 | 2074 | const stub_helper_atom_index = try self.createStubHelperAtom(); |
| 2044 | 2075 | const stub_helper_atom = self.getAtom(stub_helper_atom_index); |
| 2045 | 2076 | const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target); |
| 2046 | 2077 | const laptr_atom = self.getAtom(laptr_atom_index); |
| 2047 | 2078 | const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); |
| 2048 | 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 | 2081 | self.markRelocsDirtyByTarget(target); |
| 2051 | 2082 | } |
| 2052 | 2083 | |
| ... | ... | @@ -2431,7 +2462,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2431 | 2462 | sym.n_value = vaddr; |
| 2432 | 2463 | log.debug(" (updating GOT entry)", .{}); |
| 2433 | 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 | 2466 | self.markRelocsDirtyByTarget(got_target); |
| 2436 | 2467 | try self.writePtrWidthAtom(got_atom_index); |
| 2437 | 2468 | } |
| ... | ... | @@ -3481,8 +3512,8 @@ const SymtabCtx = struct { |
| 3481 | 3512 | |
| 3482 | 3513 | fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { |
| 3483 | 3514 | const gpa = self.base.allocator; |
| 3484 | | const nstubs = @intCast(u32, self.stubs_table.count()); |
| 3485 | | const ngot_entries = @intCast(u32, self.got_entries_table.count()); |
| 3515 | const nstubs = @intCast(u32, self.stubs_table.lookup.count()); |
| 3516 | const ngot_entries = @intCast(u32, self.got_table.lookup.count()); |
| 3486 | 3517 | const nindirectsyms = nstubs * 2 + ngot_entries; |
| 3487 | 3518 | const iextdefsym = ctx.nlocalsym; |
| 3488 | 3519 | const iundefsym = iextdefsym + ctx.nextdefsym; |
| ... | ... | @@ -3504,7 +3535,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { |
| 3504 | 3535 | if (self.stubs_section_index) |sect_id| { |
| 3505 | 3536 | const stubs = &self.sections.items(.header)[sect_id]; |
| 3506 | 3537 | stubs.reserved1 = 0; |
| 3507 | | for (self.stubs.items) |entry| { |
| 3538 | for (self.stubs_table.entries.items) |entry| { |
| 3508 | 3539 | if (entry.sym_index == 0) continue; |
| 3509 | 3540 | const target_sym = self.getSymbol(entry.target); |
| 3510 | 3541 | assert(target_sym.undf()); |
| ... | ... | @@ -3515,7 +3546,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { |
| 3515 | 3546 | if (self.got_section_index) |sect_id| { |
| 3516 | 3547 | const got = &self.sections.items(.header)[sect_id]; |
| 3517 | 3548 | got.reserved1 = nstubs; |
| 3518 | | for (self.got_entries.items) |entry| { |
| 3549 | for (self.got_table.entries.items) |entry| { |
| 3519 | 3550 | if (entry.sym_index == 0) continue; |
| 3520 | 3551 | const target_sym = self.getSymbol(entry.target); |
| 3521 | 3552 | if (target_sym.undf()) { |
| ... | ... | @@ -3529,7 +3560,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { |
| 3529 | 3560 | if (self.la_symbol_ptr_section_index) |sect_id| { |
| 3530 | 3561 | const la_symbol_ptr = &self.sections.items(.header)[sect_id]; |
| 3531 | 3562 | la_symbol_ptr.reserved1 = nstubs + ngot_entries; |
| 3532 | | for (self.stubs.items) |entry| { |
| 3563 | for (self.stubs_table.entries.items) |entry| { |
| 3533 | 3564 | if (entry.sym_index == 0) continue; |
| 3534 | 3565 | const target_sym = self.getSymbol(entry.target); |
| 3535 | 3566 | assert(target_sym.undf()); |
| ... | ... | @@ -3874,20 +3905,6 @@ pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.In |
| 3874 | 3905 | return self.atom_by_index_table.get(sym_with_loc.sym_index); |
| 3875 | 3906 | } |
| 3876 | 3907 | |
| 3877 | | /// Returns GOT atom that references `sym_with_loc` if one exists. |
| 3878 | | /// Returns null otherwise. |
| 3879 | | pub 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. |
| 3886 | | pub 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 | 3908 | /// Returns symbol location corresponding to the set entrypoint. |
| 3892 | 3909 | /// Asserts output mode is executable. |
| 3893 | 3910 | pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { |
| ... | ... | @@ -4234,37 +4251,10 @@ pub fn logSymtab(self: *MachO) void { |
| 4234 | 4251 | } |
| 4235 | 4252 | |
| 4236 | 4253 | log.debug("GOT entries:", .{}); |
| 4237 | | for (self.got_entries.items, 0..) |entry, i| { |
| 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 | | } |
| 4254 | log.debug("{}", .{self.got_table.fmtDebug(self)}); |
| 4256 | 4255 | |
| 4257 | 4256 | log.debug("stubs entries:", .{}); |
| 4258 | | for (self.stubs.items, 0..) |entry, i| { |
| 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 | | } |
| 4257 | log.debug("{}", .{self.stubs_table.fmtDebug(self)}); |
| 4268 | 4258 | } |
| 4269 | 4259 | |
| 4270 | 4260 | pub fn logAtoms(self: *MachO) void { |