| ... | @@ -5,7 +5,6 @@ const build_options = @import("build_options"); | ... | @@ -5,7 +5,6 @@ const build_options = @import("build_options"); |
| 5 | const builtin = @import("builtin"); | 5 | const builtin = @import("builtin"); |
| 6 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 7 | const dwarf = std.dwarf; | 7 | const dwarf = std.dwarf; |
| 8 | const fmt = std.fmt; | | |
| 9 | const fs = std.fs; | 8 | const fs = std.fs; |
| 10 | const log = std.log.scoped(.link); | 9 | const log = std.log.scoped(.link); |
| 11 | const macho = std.macho; | 10 | const 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, |
| 155 | | 154 | |
| 156 | strtab: StringTable(.strtab) = .{}, | 155 | strtab: StringTable(.strtab) = .{}, |
| 157 | | 156 | |
| 158 | got_entries: std.ArrayListUnmanaged(Entry) = .{}, | 157 | got_table: SectionTable = .{}, |
| 159 | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, | 158 | stubs_table: SectionTable = .{}, |
| 160 | got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 159 | tlvp_table: SectionTable = .{}, |
| 161 | | | |
| 162 | stubs: std.ArrayListUnmanaged(Entry) = .{}, | | |
| 163 | stubs_free_list: std.ArrayListUnmanaged(u32) = .{}, | | |
| 164 | stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | | |
| 165 | | 160 | |
| 166 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 161 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 167 | | 162 | |
| ... | @@ -270,26 +265,120 @@ const DeclMetadata = struct { | ... | @@ -270,26 +265,120 @@ const DeclMetadata = struct { |
| 270 | } | 265 | } |
| 271 | }; | 266 | }; |
| 272 | | 267 | |
| 273 | const Entry = struct { | 268 | const 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 | } |
| 277 | | 296 | |
| 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 | } |
| 281 | | 306 | |
| 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 | } |
| 285 | | 343 | |
| 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 | } |
| 289 | | 351 | |
| 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 | }; |
| 294 | | 383 | |
| 295 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); | 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,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}); |
| 401 | | 490 | |
| 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 | // } |
| 619 | | 708 | |
| 620 | try self.createMhExecuteHeaderSymbol(); | 709 | try self.createMhExecuteHeaderSymbol(); |
| 621 | | 710 | |
| ... | @@ -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 | } |
| 1759 | | 1848 | |
| 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); |
| 1767 | | 1853 | |
| 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 {}; |
| 1896 | | 1982 | |
| 1897 | // Try freeing GOT atom if this decl had one | 1983 | // 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 | } | | |
| 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 | 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 | } |
| 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 | fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { | 2062 | fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2009 | if (self.got_entries_table.contains(target)) return; | 2063 | if (self.got_table.lookup.contains(target)) return; |
| 2010 | | 2064 | 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 | } |
| 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 | fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { | 2071 | fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2040 | if (self.stubs_table.contains(target)) return; | 2072 | if (self.stubs_table.lookup.contains(target)) return; |
| 2041 | | 2073 | 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 | } |
| 2052 | | 2083 | |
| ... | @@ -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 { |
| 3481 | | 3512 | |
| 3482 | fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { | 3513 | fn 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 | } |
| 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 | /// 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. |
| 3893 | pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { | 3910 | pub 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 | } |
| 4235 | | 4252 | |
| 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 | } | | |
| 4256 | | 4255 | |
| 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 | } |
| 4269 | | 4259 | |
| 4270 | pub fn logAtoms(self: *MachO) void { | 4260 | pub fn logAtoms(self: *MachO) void { |