| ... | @@ -171,17 +171,19 @@ stub_helper_preamble_atom: ?*Atom = null, | ... | @@ -171,17 +171,19 @@ stub_helper_preamble_atom: ?*Atom = null, |
| 171 | | 171 | |
| 172 | strtab: StringTable(.strtab) = .{}, | 172 | strtab: StringTable(.strtab) = .{}, |
| 173 | | 173 | |
| | 174 | // TODO I think synthetic tables are a perfect match for some generic refactoring, |
| | 175 | // and probably reusable between linker backends too. |
| 174 | tlv_ptr_entries: std.ArrayListUnmanaged(Entry) = .{}, | 176 | tlv_ptr_entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 175 | tlv_ptr_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, | 177 | tlv_ptr_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 176 | tlv_ptr_entries_table: std.AutoArrayHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 178 | tlv_ptr_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 177 | | 179 | |
| 178 | got_entries: std.ArrayListUnmanaged(Entry) = .{}, | 180 | got_entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 179 | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, | 181 | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 180 | got_entries_table: std.AutoArrayHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 182 | got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 181 | | 183 | |
| 182 | stubs: std.ArrayListUnmanaged(Entry) = .{}, | 184 | stubs: std.ArrayListUnmanaged(Entry) = .{}, |
| 183 | stubs_free_list: std.ArrayListUnmanaged(u32) = .{}, | 185 | stubs_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 184 | stubs_table: std.AutoArrayHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 186 | stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 185 | | 187 | |
| 186 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 188 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 187 | | 189 | |
| ... | @@ -251,7 +253,24 @@ decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, | ... | @@ -251,7 +253,24 @@ decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, |
| 251 | | 253 | |
| 252 | const Entry = struct { | 254 | const Entry = struct { |
| 253 | target: SymbolWithLoc, | 255 | target: SymbolWithLoc, |
| 254 | atom: *Atom, | 256 | // Index into the synthetic symbol table (i.e., file == null). |
| | 257 | sym_index: u32, |
| | 258 | |
| | 259 | pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 { |
| | 260 | return macho_file.getSymbol(.{ .sym_index = entry.sym_index, .file = null }); |
| | 261 | } |
| | 262 | |
| | 263 | pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 { |
| | 264 | return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null }); |
| | 265 | } |
| | 266 | |
| | 267 | pub fn getAtom(entry: Entry, macho_file: *MachO) *Atom { |
| | 268 | return macho_file.getAtomForSymbol(.{ .sym_index = entry.sym_index, .file = null }).?; |
| | 269 | } |
| | 270 | |
| | 271 | pub fn getName(entry: Entry, macho_file: *MachO) []const u8 { |
| | 272 | return macho_file.getSymbolName(.{ .sym_index = entry.sym_index, .file = null }); |
| | 273 | } |
| 255 | }; | 274 | }; |
| 256 | | 275 | |
| 257 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); | 276 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); |
| ... | @@ -1652,6 +1671,15 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any | ... | @@ -1652,6 +1671,15 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any |
| 1652 | pub const MatchingSection = struct { | 1671 | pub const MatchingSection = struct { |
| 1653 | seg: u16, | 1672 | seg: u16, |
| 1654 | sect: u16, | 1673 | sect: u16, |
| | 1674 | |
| | 1675 | pub fn eql(this: MatchingSection, other: struct { |
| | 1676 | seg: ?u16, |
| | 1677 | sect: ?u16, |
| | 1678 | }) bool { |
| | 1679 | const seg = other.seg orelse return false; |
| | 1680 | const sect = other.sect orelse return false; |
| | 1681 | return this.seg == seg and this.sect == sect; |
| | 1682 | } |
| 1655 | }; | 1683 | }; |
| 1656 | | 1684 | |
| 1657 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { | 1685 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { |
| ... | @@ -3153,8 +3181,7 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { | ... | @@ -3153,8 +3181,7 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 3153 | const stub_helper_atom = try self.createStubHelperAtom(); | 3181 | const stub_helper_atom = try self.createStubHelperAtom(); |
| 3154 | const laptr_atom = try self.createLazyPointerAtom(stub_helper_atom.sym_index, global); | 3182 | const laptr_atom = try self.createLazyPointerAtom(stub_helper_atom.sym_index, global); |
| 3155 | const stub_atom = try self.createStubAtom(laptr_atom.sym_index); | 3183 | const stub_atom = try self.createStubAtom(laptr_atom.sym_index); |
| 3156 | | 3184 | self.stubs.items[stub_index].sym_index = stub_atom.sym_index; |
| 3157 | self.stubs.items[stub_index].atom = stub_atom; | | |
| 3158 | } | 3185 | } |
| 3159 | | 3186 | |
| 3160 | continue :loop; | 3187 | continue :loop; |
| ... | @@ -3251,7 +3278,7 @@ fn resolveDyldStubBinder(self: *MachO) !void { | ... | @@ -3251,7 +3278,7 @@ fn resolveDyldStubBinder(self: *MachO) !void { |
| 3251 | // Add dyld_stub_binder as the final GOT entry. | 3278 | // Add dyld_stub_binder as the final GOT entry. |
| 3252 | const got_index = try self.allocateGotEntry(global); | 3279 | const got_index = try self.allocateGotEntry(global); |
| 3253 | const got_atom = try self.createGotAtom(global); | 3280 | const got_atom = try self.createGotAtom(global); |
| 3254 | self.got_entries.items[got_index].atom = got_atom; | 3281 | self.got_entries.items[got_index].sym_index = got_atom.sym_index; |
| 3255 | } | 3282 | } |
| 3256 | | 3283 | |
| 3257 | fn addLoadDylibLC(self: *MachO, id: u16) !void { | 3284 | fn addLoadDylibLC(self: *MachO, id: u16) !void { |
| ... | @@ -3288,11 +3315,7 @@ fn setEntryPoint(self: *MachO) !void { | ... | @@ -3288,11 +3315,7 @@ fn setEntryPoint(self: *MachO) !void { |
| 3288 | if (self.base.options.output_mode != .Exe) return; | 3315 | if (self.base.options.output_mode != .Exe) return; |
| 3289 | | 3316 | |
| 3290 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment; | 3317 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment; |
| 3291 | const global = self.getEntryPoint() orelse { | 3318 | const global = try self.getEntryPoint(); |
| 3292 | const name = self.base.options.entry orelse "_main"; | | |
| 3293 | log.err("entrypoint '{s}' not found", .{name}); | | |
| 3294 | return error.MissingMainEntrypoint; | | |
| 3295 | }; | | |
| 3296 | const sym = self.getSymbol(global); | 3319 | const sym = self.getSymbol(global); |
| 3297 | const ec = &self.load_commands.items[self.main_cmd_index.?].main; | 3320 | const ec = &self.load_commands.items[self.main_cmd_index.?].main; |
| 3298 | ec.entryoff = @intCast(u32, sym.n_value - seg.inner.vmaddr); | 3321 | ec.entryoff = @intCast(u32, sym.n_value - seg.inner.vmaddr); |
| ... | @@ -3508,7 +3531,8 @@ fn allocateSymbol(self: *MachO) !u32 { | ... | @@ -3508,7 +3531,8 @@ fn allocateSymbol(self: *MachO) !u32 { |
| 3508 | } | 3531 | } |
| 3509 | | 3532 | |
| 3510 | pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { | 3533 | pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 3511 | try self.got_entries.ensureUnusedCapacity(self.base.allocator, 1); | 3534 | const gpa = self.base.allocator; |
| | 3535 | try self.got_entries.ensureUnusedCapacity(gpa, 1); |
| 3512 | | 3536 | |
| 3513 | const index = blk: { | 3537 | const index = blk: { |
| 3514 | if (self.got_entries_free_list.popOrNull()) |index| { | 3538 | if (self.got_entries_free_list.popOrNull()) |index| { |
| ... | @@ -3522,8 +3546,8 @@ pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { | ... | @@ -3522,8 +3546,8 @@ pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 3522 | } | 3546 | } |
| 3523 | }; | 3547 | }; |
| 3524 | | 3548 | |
| 3525 | self.got_entries.items[index] = .{ .target = target, .atom = undefined }; | 3549 | self.got_entries.items[index] = .{ .target = target, .sym_index = 0 }; |
| 3526 | try self.got_entries_table.putNoClobber(self.base.allocator, target, index); | 3550 | try self.got_entries_table.putNoClobber(gpa, target, index); |
| 3527 | | 3551 | |
| 3528 | return index; | 3552 | return index; |
| 3529 | } | 3553 | } |
| ... | @@ -3543,7 +3567,7 @@ pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { | ... | @@ -3543,7 +3567,7 @@ pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 3543 | } | 3567 | } |
| 3544 | }; | 3568 | }; |
| 3545 | | 3569 | |
| 3546 | self.stubs.items[index] = .{ .target = target, .atom = undefined }; | 3570 | self.stubs.items[index] = .{ .target = target, .sym_index = 0 }; |
| 3547 | try self.stubs_table.putNoClobber(self.base.allocator, target, index); | 3571 | try self.stubs_table.putNoClobber(self.base.allocator, target, index); |
| 3548 | | 3572 | |
| 3549 | return index; | 3573 | return index; |
| ... | @@ -3564,7 +3588,7 @@ pub fn allocateTlvPtrEntry(self: *MachO, target: SymbolWithLoc) !u32 { | ... | @@ -3564,7 +3588,7 @@ pub fn allocateTlvPtrEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 3564 | } | 3588 | } |
| 3565 | }; | 3589 | }; |
| 3566 | | 3590 | |
| 3567 | self.tlv_ptr_entries.items[index] = .{ .target = target, .atom = undefined }; | 3591 | self.tlv_ptr_entries.items[index] = .{ .target = target, .sym_index = 0 }; |
| 3568 | try self.tlv_ptr_entries_table.putNoClobber(self.base.allocator, target, index); | 3592 | try self.tlv_ptr_entries_table.putNoClobber(self.base.allocator, target, index); |
| 3569 | | 3593 | |
| 3570 | return index; | 3594 | return index; |
| ... | @@ -4029,7 +4053,7 @@ fn placeDecl(self: *MachO, decl_index: Module.Decl.Index, code_len: usize) !*mac | ... | @@ -4029,7 +4053,7 @@ fn placeDecl(self: *MachO, decl_index: Module.Decl.Index, code_len: usize) !*mac |
| 4029 | const got_target = SymbolWithLoc{ .sym_index = decl.link.macho.sym_index, .file = null }; | 4053 | const got_target = SymbolWithLoc{ .sym_index = decl.link.macho.sym_index, .file = null }; |
| 4030 | const got_index = try self.allocateGotEntry(got_target); | 4054 | const got_index = try self.allocateGotEntry(got_target); |
| 4031 | const got_atom = try self.createGotAtom(got_target); | 4055 | const got_atom = try self.createGotAtom(got_target); |
| 4032 | self.got_entries.items[got_index].atom = got_atom; | 4056 | self.got_entries.items[got_index].sym_index = got_atom.sym_index; |
| 4033 | } | 4057 | } |
| 4034 | | 4058 | |
| 4035 | return symbol; | 4059 | return symbol; |
| ... | @@ -4219,9 +4243,9 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void { | ... | @@ -4219,9 +4243,9 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void { |
| 4219 | self.got_entries_free_list.append(self.base.allocator, @intCast(u32, got_index)) catch {}; | 4243 | self.got_entries_free_list.append(self.base.allocator, @intCast(u32, got_index)) catch {}; |
| 4220 | self.got_entries.items[got_index] = .{ | 4244 | self.got_entries.items[got_index] = .{ |
| 4221 | .target = .{ .sym_index = 0, .file = null }, | 4245 | .target = .{ .sym_index = 0, .file = null }, |
| 4222 | .atom = undefined, | 4246 | .sym_index = 0, |
| 4223 | }; | 4247 | }; |
| 4224 | _ = self.got_entries_table.swapRemove(got_target); | 4248 | _ = self.got_entries_table.remove(got_target); |
| 4225 | | 4249 | |
| 4226 | if (self.d_sym) |*d_sym| { | 4250 | if (self.d_sym) |*d_sym| { |
| 4227 | d_sym.swapRemoveRelocs(decl.link.macho.sym_index); | 4251 | d_sym.swapRemoveRelocs(decl.link.macho.sym_index); |
| ... | @@ -5493,46 +5517,26 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { | ... | @@ -5493,46 +5517,26 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { |
| 5493 | | 5517 | |
| 5494 | if (self.base.options.output_mode == .Exe) { | 5518 | if (self.base.options.output_mode == .Exe) { |
| 5495 | // Add entrypoint as GC root | 5519 | // Add entrypoint as GC root |
| 5496 | if (self.getEntryPoint()) |global| { | 5520 | const global = try self.getEntryPoint(); |
| 5497 | if (self.getAtomForSymbol(global)) |gc_root| { | 5521 | const atom = self.getAtomForSymbol(global).?; // panic here means fatal error |
| 5498 | _ = try gc_roots.getOrPut(gc_root); | 5522 | _ = try gc_roots.getOrPut(atom); |
| 5499 | } else { | | |
| 5500 | log.debug("skipping {s}", .{self.getSymbolName(global)}); | | |
| 5501 | } | | |
| 5502 | } | | |
| 5503 | } else { | 5523 | } else { |
| 5504 | assert(self.base.options.output_mode == .Lib); | 5524 | assert(self.base.options.output_mode == .Lib); |
| 5505 | // Add exports as GC roots | 5525 | // Add exports as GC roots |
| 5506 | for (self.globals.values()) |global| { | 5526 | for (self.globals.values()) |global| { |
| 5507 | const sym = self.getSymbol(global); | 5527 | const sym = self.getSymbol(global); |
| 5508 | if (!sym.sect()) continue; | 5528 | if (!sym.sect()) continue; |
| 5509 | const gc_root = self.getAtomForSymbol(global) orelse { | 5529 | const atom = self.getAtomForSymbol(global) orelse { |
| 5510 | log.debug("skipping {s}", .{self.getSymbolName(global)}); | 5530 | log.debug("skipping {s}", .{self.getSymbolName(global)}); |
| 5511 | continue; | 5531 | continue; |
| 5512 | }; | 5532 | }; |
| 5513 | _ = try gc_roots.getOrPut(gc_root); | 5533 | _ = try gc_roots.getOrPut(atom); |
| 5514 | } | 5534 | } |
| 5515 | } | 5535 | } |
| 5516 | | 5536 | // TODO just a temp until we learn how to parse unwind records |
| 5517 | // Add any atom targeting an import as GC root | 5537 | if (self.globals.get("___gxx_personality_v0")) |global| { |
| 5518 | var atoms_it = self.atoms.iterator(); | 5538 | if (self.getAtomForSymbol(global)) |atom| { |
| 5519 | while (atoms_it.next()) |entry| { | 5539 | _ = try gc_roots.getOrPut(atom); |
| 5520 | var atom = entry.value_ptr.*; | | |
| 5521 | | | |
| 5522 | while (true) { | | |
| 5523 | for (atom.relocs.items) |rel| { | | |
| 5524 | if ((try rel.getTargetAtom(self)) == null) { | | |
| 5525 | const target_sym = self.getSymbol(rel.target); | | |
| 5526 | if (target_sym.undf()) { | | |
| 5527 | _ = try gc_roots.getOrPut(atom); | | |
| 5528 | break; | | |
| 5529 | } | | |
| 5530 | } | | |
| 5531 | } | | |
| 5532 | | | |
| 5533 | if (atom.prev) |prev| { | | |
| 5534 | atom = prev; | | |
| 5535 | } else break; | | |
| 5536 | } | 5540 | } |
| 5537 | } | 5541 | } |
| 5538 | | 5542 | |
| ... | @@ -5540,80 +5544,80 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { | ... | @@ -5540,80 +5544,80 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { |
| 5540 | defer stack.deinit(); | 5544 | defer stack.deinit(); |
| 5541 | try stack.ensureUnusedCapacity(gc_roots.count()); | 5545 | try stack.ensureUnusedCapacity(gc_roots.count()); |
| 5542 | | 5546 | |
| 5543 | var retained = std.AutoHashMap(*Atom, void).init(gpa); | 5547 | var alive = std.AutoHashMap(*Atom, void).init(gpa); |
| 5544 | defer retained.deinit(); | 5548 | defer alive.deinit(); |
| 5545 | try retained.ensureUnusedCapacity(gc_roots.count()); | 5549 | try alive.ensureUnusedCapacity(gc_roots.count()); |
| 5546 | | 5550 | |
| 5547 | log.debug("GC roots:", .{}); | 5551 | log.debug("GC roots:", .{}); |
| 5548 | var gc_roots_it = gc_roots.keyIterator(); | 5552 | var gc_roots_it = gc_roots.keyIterator(); |
| 5549 | while (gc_roots_it.next()) |gc_root| { | 5553 | while (gc_roots_it.next()) |gc_root| { |
| 5550 | self.logAtom(gc_root.*); | 5554 | self.logAtom(gc_root.*); |
| 5551 | | | |
| 5552 | stack.appendAssumeCapacity(gc_root.*); | 5555 | stack.appendAssumeCapacity(gc_root.*); |
| 5553 | retained.putAssumeCapacityNoClobber(gc_root.*, {}); | 5556 | alive.putAssumeCapacity(gc_root.*, {}); |
| 5554 | } | 5557 | } |
| 5555 | | 5558 | |
| 5556 | log.debug("walking tree...", .{}); | | |
| 5557 | while (stack.popOrNull()) |source_atom| { | 5559 | while (stack.popOrNull()) |source_atom| { |
| 5558 | for (source_atom.relocs.items) |rel| { | 5560 | for (source_atom.relocs.items) |rel| { |
| 5559 | if (try rel.getTargetAtom(self)) |target_atom| { | 5561 | if (rel.getTargetAtom(self)) |target_atom| { |
| 5560 | const gop = try retained.getOrPut(target_atom); | 5562 | const gop = try alive.getOrPut(target_atom); |
| 5561 | if (!gop.found_existing) { | 5563 | if (!gop.found_existing) { |
| 5562 | log.debug(" RETAINED ATOM(%{d}) -> ATOM(%{d})", .{ | 5564 | log.debug(" retained ATOM(%{d}, '{s}') in object({d})", .{ |
| 5563 | source_atom.sym_index, | | |
| 5564 | target_atom.sym_index, | 5565 | target_atom.sym_index, |
| | 5566 | target_atom.getName(self), |
| | 5567 | target_atom.file, |
| | 5568 | }); |
| | 5569 | log.debug(" referenced by ATOM(%{d}, '{s}') in object({d})", .{ |
| | 5570 | source_atom.sym_index, |
| | 5571 | source_atom.getName(self), |
| | 5572 | source_atom.file, |
| 5565 | }); | 5573 | }); |
| 5566 | try stack.append(target_atom); | 5574 | try stack.append(target_atom); |
| 5567 | } | 5575 | } |
| 5568 | } | 5576 | } |
| 5569 | } | 5577 | } |
| 5570 | } | 5578 | } |
| | 5579 | // TODO live support |
| 5571 | | 5580 | |
| 5572 | // Any section that ends up here will be updated, that is, | 5581 | // Any section that ends up here will be updated, that is, |
| 5573 | // its size and alignment recalculated. | 5582 | // its size and alignment recalculated. |
| 5574 | var gc_sections = std.AutoHashMap(MatchingSection, void).init(gpa); | 5583 | var gc_sections = std.AutoHashMap(MatchingSection, void).init(gpa); |
| 5575 | defer gc_sections.deinit(); | 5584 | defer gc_sections.deinit(); |
| 5576 | | 5585 | |
| 5577 | atoms_it = self.atoms.iterator(); | 5586 | var loop: bool = true; |
| 5578 | while (atoms_it.next()) |entry| { | 5587 | while (loop) { |
| 5579 | const match = entry.key_ptr.*; | 5588 | loop = false; |
| 5580 | | | |
| 5581 | if (self.text_segment_cmd_index) |seg| { | | |
| 5582 | if (seg == match.seg) { | | |
| 5583 | if (self.eh_frame_section_index) |sect| { | | |
| 5584 | if (sect == match.sect) continue; | | |
| 5585 | } | | |
| 5586 | } | | |
| 5587 | } | | |
| 5588 | | 5589 | |
| 5589 | if (self.data_segment_cmd_index) |seg| { | 5590 | for (self.objects.items) |object| { |
| 5590 | if (seg == match.seg) { | 5591 | for (object.getSourceSymtab()) |_, source_index| { |
| 5591 | if (self.rustc_section_index) |sect| { | 5592 | const atom = object.getAtomForSymbol(@intCast(u32, source_index)) orelse continue; |
| 5592 | if (sect == match.sect) continue; | 5593 | if (alive.contains(atom)) continue; |
| 5593 | } | | |
| 5594 | } | | |
| 5595 | } | | |
| 5596 | | 5594 | |
| 5597 | const sect = self.getSectionPtr(match); | 5595 | const global = atom.getSymbolWithLoc(); |
| 5598 | var atom = entry.value_ptr.*; | 5596 | const sym = atom.getSymbolPtr(self); |
| 5599 | | 5597 | |
| 5600 | log.debug("GCing atoms in {s},{s}", .{ sect.segName(), sect.sectName() }); | 5598 | if (sym.n_desc == N_DESC_GCED) continue; |
| | 5599 | if (!sym.ext()) { |
| | 5600 | for (atom.relocs.items) |rel| { |
| | 5601 | if (rel.getTargetAtom(self)) |target_atom| { |
| | 5602 | const target_sym = target_atom.getSymbol(self); |
| | 5603 | if (target_sym.n_desc == N_DESC_GCED) break; |
| | 5604 | } |
| | 5605 | } else continue; |
| | 5606 | } |
| 5601 | | 5607 | |
| 5602 | while (true) { | 5608 | loop = true; |
| 5603 | const orig_prev = atom.prev; | 5609 | const match = self.getMatchingSectionFromOrdinal(sym.n_sect); |
| 5604 | | 5610 | |
| 5605 | if (!retained.contains(atom)) { | 5611 | // TODO don't dedup eh_frame info yet until we actually implement parsing unwind records |
| 5606 | // Dead atom; remove. | 5612 | if (match.eql(.{ |
| 5607 | log.debug(" DEAD ATOM(%{d})", .{atom.sym_index}); | 5613 | .seg = self.text_segment_cmd_index, |
| | 5614 | .sect = self.eh_frame_section_index, |
| | 5615 | })) continue; |
| 5608 | | 5616 | |
| 5609 | const sym = atom.getSymbolPtr(self); | 5617 | self.logAtom(atom); |
| 5610 | sym.n_desc = N_DESC_GCED; | 5618 | sym.n_desc = N_DESC_GCED; |
| 5611 | | 5619 | self.removeAtomFromSection(atom, match); |
| 5612 | // TODO add full bookkeeping here | 5620 | _ = try gc_sections.put(match, {}); |
| 5613 | const global = SymbolWithLoc{ .sym_index = atom.sym_index, .file = atom.file }; | | |
| 5614 | _ = self.got_entries_table.swapRemove(global); | | |
| 5615 | _ = self.stubs_table.swapRemove(global); | | |
| 5616 | _ = self.tlv_ptr_entries_table.swapRemove(global); | | |
| 5617 | | 5621 | |
| 5618 | for (atom.contained.items) |sym_off| { | 5622 | for (atom.contained.items) |sym_off| { |
| 5619 | const inner = self.getSymbolPtr(.{ | 5623 | const inner = self.getSymbolPtr(.{ |
| ... | @@ -5622,34 +5626,64 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { | ... | @@ -5622,34 +5626,64 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { |
| 5622 | }); | 5626 | }); |
| 5623 | inner.n_desc = N_DESC_GCED; | 5627 | inner.n_desc = N_DESC_GCED; |
| 5624 | } | 5628 | } |
| 5625 | // If we want to enable GC for incremental codepath, we need to take into | | |
| 5626 | // account any padding that might have been left here. | | |
| 5627 | sect.size -= atom.size; | | |
| 5628 | | 5629 | |
| 5629 | _ = try gc_sections.put(match, {}); | 5630 | if (self.got_entries_table.contains(global)) { |
| | 5631 | const got_atom = self.getGotAtomForSymbol(global).?; |
| | 5632 | const got_sym = got_atom.getSymbolPtr(self); |
| | 5633 | got_sym.n_desc = N_DESC_GCED; |
| | 5634 | } |
| 5630 | | 5635 | |
| 5631 | if (atom.prev) |prev| { | 5636 | if (self.stubs_table.contains(global)) { |
| 5632 | prev.next = atom.next; | 5637 | const stubs_atom = self.getStubsAtomForSymbol(global).?; |
| | 5638 | const stubs_sym = stubs_atom.getSymbolPtr(self); |
| | 5639 | stubs_sym.n_desc = N_DESC_GCED; |
| 5633 | } | 5640 | } |
| 5634 | if (atom.next) |next| { | 5641 | |
| 5635 | next.prev = atom.prev; | 5642 | if (self.tlv_ptr_entries_table.contains(global)) { |
| 5636 | } else { | 5643 | const tlv_ptr_atom = self.getTlvPtrAtomForSymbol(global).?; |
| 5637 | if (atom.prev) |prev| { | 5644 | const tlv_ptr_sym = tlv_ptr_atom.getSymbolPtr(self); |
| 5638 | entry.value_ptr.* = prev; | 5645 | tlv_ptr_sym.n_desc = N_DESC_GCED; |
| 5639 | } else { | | |
| 5640 | // The section will be GCed in the next step. | | |
| 5641 | entry.value_ptr.* = undefined; | | |
| 5642 | sect.size = 0; | | |
| 5643 | } | | |
| 5644 | } | 5646 | } |
| 5645 | } | 5647 | } |
| 5646 | | | |
| 5647 | if (orig_prev) |prev| { | | |
| 5648 | atom = prev; | | |
| 5649 | } else break; | | |
| 5650 | } | 5648 | } |
| 5651 | } | 5649 | } |
| 5652 | | 5650 | |
| | 5651 | for (self.got_entries.items) |entry| { |
| | 5652 | const sym = entry.getSymbol(self); |
| | 5653 | if (sym.n_desc != N_DESC_GCED) continue; |
| | 5654 | |
| | 5655 | // TODO tombstone |
| | 5656 | const atom = entry.getAtom(self); |
| | 5657 | const match = self.getMatchingSectionFromOrdinal(sym.n_sect); |
| | 5658 | self.removeAtomFromSection(atom, match); |
| | 5659 | _ = try gc_sections.put(match, {}); |
| | 5660 | _ = self.got_entries_table.remove(entry.target); |
| | 5661 | } |
| | 5662 | |
| | 5663 | for (self.stubs.items) |entry| { |
| | 5664 | const sym = entry.getSymbol(self); |
| | 5665 | if (sym.n_desc != N_DESC_GCED) continue; |
| | 5666 | |
| | 5667 | // TODO tombstone |
| | 5668 | const atom = entry.getAtom(self); |
| | 5669 | const match = self.getMatchingSectionFromOrdinal(sym.n_sect); |
| | 5670 | self.removeAtomFromSection(atom, match); |
| | 5671 | _ = try gc_sections.put(match, {}); |
| | 5672 | _ = self.stubs_table.remove(entry.target); |
| | 5673 | } |
| | 5674 | |
| | 5675 | for (self.tlv_ptr_entries.items) |entry| { |
| | 5676 | const sym = entry.getSymbol(self); |
| | 5677 | if (sym.n_desc != N_DESC_GCED) continue; |
| | 5678 | |
| | 5679 | // TODO tombstone |
| | 5680 | const atom = entry.getAtom(self); |
| | 5681 | const match = self.getMatchingSectionFromOrdinal(sym.n_sect); |
| | 5682 | self.removeAtomFromSection(atom, match); |
| | 5683 | _ = try gc_sections.put(match, {}); |
| | 5684 | _ = self.tlv_ptr_entries_table.remove(entry.target); |
| | 5685 | } |
| | 5686 | |
| 5653 | var gc_sections_it = gc_sections.iterator(); | 5687 | var gc_sections_it = gc_sections.iterator(); |
| 5654 | while (gc_sections_it.next()) |entry| { | 5688 | while (gc_sections_it.next()) |entry| { |
| 5655 | const match = entry.key_ptr.*; | 5689 | const match = entry.key_ptr.*; |
| ... | @@ -5679,6 +5713,30 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { | ... | @@ -5679,6 +5713,30 @@ fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { |
| 5679 | } | 5713 | } |
| 5680 | } | 5714 | } |
| 5681 | | 5715 | |
| | 5716 | fn removeAtomFromSection(self: *MachO, atom: *Atom, match: MatchingSection) void { |
| | 5717 | const sect = self.getSectionPtr(match); |
| | 5718 | |
| | 5719 | // If we want to enable GC for incremental codepath, we need to take into |
| | 5720 | // account any padding that might have been left here. |
| | 5721 | sect.size -= atom.size; |
| | 5722 | |
| | 5723 | if (atom.prev) |prev| { |
| | 5724 | prev.next = atom.next; |
| | 5725 | } |
| | 5726 | if (atom.next) |next| { |
| | 5727 | next.prev = atom.prev; |
| | 5728 | } else { |
| | 5729 | const last = self.atoms.getPtr(match).?; |
| | 5730 | if (atom.prev) |prev| { |
| | 5731 | last.* = prev; |
| | 5732 | } else { |
| | 5733 | // The section will be GCed in the next step. |
| | 5734 | last.* = undefined; |
| | 5735 | sect.size = 0; |
| | 5736 | } |
| | 5737 | } |
| | 5738 | } |
| | 5739 | |
| 5682 | fn updateSectionOrdinals(self: *MachO) !void { | 5740 | fn updateSectionOrdinals(self: *MachO) !void { |
| 5683 | if (!self.sections_order_dirty) return; | 5741 | if (!self.sections_order_dirty) return; |
| 5684 | | 5742 | |
| ... | @@ -5849,7 +5907,7 @@ fn writeDyldInfoData(self: *MachO) !void { | ... | @@ -5849,7 +5907,7 @@ fn writeDyldInfoData(self: *MachO) !void { |
| 5849 | | 5907 | |
| 5850 | if (self.base.options.output_mode == .Exe) { | 5908 | if (self.base.options.output_mode == .Exe) { |
| 5851 | for (&[_]SymbolWithLoc{ | 5909 | for (&[_]SymbolWithLoc{ |
| 5852 | self.getEntryPoint().?, // We would already errored out if no entrypoint was found. | 5910 | try self.getEntryPoint(), |
| 5853 | self.globals.get("__mh_execute_header").?, | 5911 | self.globals.get("__mh_execute_header").?, |
| 5854 | }) |global| { | 5912 | }) |global| { |
| 5855 | const sym = self.getSymbol(global); | 5913 | const sym = self.getSymbol(global); |
| ... | @@ -6337,10 +6395,13 @@ fn writeSymtab(self: *MachO) !void { | ... | @@ -6337,10 +6395,13 @@ fn writeSymtab(self: *MachO) !void { |
| 6337 | .sect = stubs_section_index, | 6395 | .sect = stubs_section_index, |
| 6338 | }); | 6396 | }); |
| 6339 | stubs.reserved1 = 0; | 6397 | stubs.reserved1 = 0; |
| 6340 | for (self.stubs_table.keys()) |target| { | 6398 | for (self.stubs.items) |entry| { |
| 6341 | const sym = self.getSymbol(target); | 6399 | if (entry.sym_index == 0) continue; |
| 6342 | assert(sym.undf()); | 6400 | const atom_sym = entry.getSymbol(self); |
| 6343 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(target).?); | 6401 | if (atom_sym.n_desc == N_DESC_GCED) continue; |
| | 6402 | const target_sym = self.getSymbol(entry.target); |
| | 6403 | assert(target_sym.undf()); |
| | 6404 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(entry.target).?); |
| 6344 | } | 6405 | } |
| 6345 | } | 6406 | } |
| 6346 | | 6407 | |
| ... | @@ -6351,10 +6412,13 @@ fn writeSymtab(self: *MachO) !void { | ... | @@ -6351,10 +6412,13 @@ fn writeSymtab(self: *MachO) !void { |
| 6351 | .sect = got_section_index, | 6412 | .sect = got_section_index, |
| 6352 | }); | 6413 | }); |
| 6353 | got.reserved1 = nstubs; | 6414 | got.reserved1 = nstubs; |
| 6354 | for (self.got_entries_table.keys()) |target| { | 6415 | for (self.got_entries.items) |entry| { |
| 6355 | const sym = self.getSymbol(target); | 6416 | if (entry.sym_index == 0) continue; |
| 6356 | if (sym.undf()) { | 6417 | const atom_sym = entry.getSymbol(self); |
| 6357 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(target).?); | 6418 | if (atom_sym.n_desc == N_DESC_GCED) continue; |
| | 6419 | const target_sym = self.getSymbol(entry.target); |
| | 6420 | if (target_sym.undf()) { |
| | 6421 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(entry.target).?); |
| 6358 | } else { | 6422 | } else { |
| 6359 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); | 6423 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); |
| 6360 | } | 6424 | } |
| ... | @@ -6368,10 +6432,13 @@ fn writeSymtab(self: *MachO) !void { | ... | @@ -6368,10 +6432,13 @@ fn writeSymtab(self: *MachO) !void { |
| 6368 | .sect = la_symbol_ptr_section_index, | 6432 | .sect = la_symbol_ptr_section_index, |
| 6369 | }); | 6433 | }); |
| 6370 | la_symbol_ptr.reserved1 = nstubs + ngot_entries; | 6434 | la_symbol_ptr.reserved1 = nstubs + ngot_entries; |
| 6371 | for (self.stubs_table.keys()) |target| { | 6435 | for (self.stubs.items) |entry| { |
| 6372 | const sym = self.getSymbol(target); | 6436 | if (entry.sym_index == 0) continue; |
| 6373 | assert(sym.undf()); | 6437 | const atom_sym = entry.getSymbol(self); |
| 6374 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(target).?); | 6438 | if (atom_sym.n_desc == N_DESC_GCED) continue; |
| | 6439 | const target_sym = self.getSymbol(entry.target); |
| | 6440 | assert(target_sym.undf()); |
| | 6441 | try writer.writeIntLittle(u32, dysymtab.iundefsym + imports_table.get(entry.target).?); |
| 6375 | } | 6442 | } |
| 6376 | } | 6443 | } |
| 6377 | | 6444 | |
| ... | @@ -6623,7 +6690,7 @@ pub fn getSymbolName(self: *MachO, sym_with_loc: SymbolWithLoc) []const u8 { | ... | @@ -6623,7 +6690,7 @@ pub fn getSymbolName(self: *MachO, sym_with_loc: SymbolWithLoc) []const u8 { |
| 6623 | pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 6690 | pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { |
| 6624 | if (sym_with_loc.file) |file| { | 6691 | if (sym_with_loc.file) |file| { |
| 6625 | const object = self.objects.items[file]; | 6692 | const object = self.objects.items[file]; |
| 6626 | return object.atom_by_index_table.get(sym_with_loc.sym_index); | 6693 | return object.getAtomForSymbol(sym_with_loc.sym_index); |
| 6627 | } else { | 6694 | } else { |
| 6628 | return self.atom_by_index_table.get(sym_with_loc.sym_index); | 6695 | return self.atom_by_index_table.get(sym_with_loc.sym_index); |
| 6629 | } | 6696 | } |
| ... | @@ -6633,28 +6700,32 @@ pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | ... | @@ -6633,28 +6700,32 @@ pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { |
| 6633 | /// Returns null otherwise. | 6700 | /// Returns null otherwise. |
| 6634 | pub fn getGotAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 6701 | pub fn getGotAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { |
| 6635 | const got_index = self.got_entries_table.get(sym_with_loc) orelse return null; | 6702 | const got_index = self.got_entries_table.get(sym_with_loc) orelse return null; |
| 6636 | return self.got_entries.items[got_index].atom; | 6703 | return self.got_entries.items[got_index].getAtom(self); |
| 6637 | } | 6704 | } |
| 6638 | | 6705 | |
| 6639 | /// Returns stubs atom that references `sym_with_loc` if one exists. | 6706 | /// Returns stubs atom that references `sym_with_loc` if one exists. |
| 6640 | /// Returns null otherwise. | 6707 | /// Returns null otherwise. |
| 6641 | pub fn getStubsAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 6708 | pub fn getStubsAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { |
| 6642 | const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null; | 6709 | const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null; |
| 6643 | return self.stubs.items[stubs_index].atom; | 6710 | return self.stubs.items[stubs_index].getAtom(self); |
| 6644 | } | 6711 | } |
| 6645 | | 6712 | |
| 6646 | /// Returns TLV pointer atom that references `sym_with_loc` if one exists. | 6713 | /// Returns TLV pointer atom that references `sym_with_loc` if one exists. |
| 6647 | /// Returns null otherwise. | 6714 | /// Returns null otherwise. |
| 6648 | pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 6715 | pub fn getTlvPtrAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { |
| 6649 | const tlv_ptr_index = self.tlv_ptr_entries_table.get(sym_with_loc) orelse return null; | 6716 | const tlv_ptr_index = self.tlv_ptr_entries_table.get(sym_with_loc) orelse return null; |
| 6650 | return self.tlv_ptr_entries.items[tlv_ptr_index].atom; | 6717 | return self.tlv_ptr_entries.items[tlv_ptr_index].getAtom(self); |
| 6651 | } | 6718 | } |
| 6652 | | 6719 | |
| 6653 | /// Returns symbol location corresponding to the set entrypoint. | 6720 | /// Returns symbol location corresponding to the set entrypoint. |
| 6654 | /// Asserts output mode is executable. | 6721 | /// Asserts output mode is executable. |
| 6655 | pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { | 6722 | pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { |
| 6656 | const entry_name = self.base.options.entry orelse "_main"; | 6723 | const entry_name = self.base.options.entry orelse "_main"; |
| 6657 | return self.globals.get(entry_name); | 6724 | const global = self.globals.get(entry_name) orelse { |
| | 6725 | log.err("entrypoint '{s}' not found", .{entry_name}); |
| | 6726 | return error.MissingMainEntrypoint; |
| | 6727 | }; |
| | 6728 | return global; |
| 6658 | } | 6729 | } |
| 6659 | | 6730 | |
| 6660 | pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize { | 6731 | pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize { |
| ... | @@ -6986,7 +7057,7 @@ fn snapshotState(self: *MachO) !void { | ... | @@ -6986,7 +7057,7 @@ fn snapshotState(self: *MachO) !void { |
| 6986 | break :blk source_sym.n_value + rel.offset; | 7057 | break :blk source_sym.n_value + rel.offset; |
| 6987 | }; | 7058 | }; |
| 6988 | const target_addr = blk: { | 7059 | const target_addr = blk: { |
| 6989 | const target_atom = (try rel.getTargetAtom(self)) orelse { | 7060 | const target_atom = rel.getTargetAtom(self) orelse { |
| 6990 | // If there is no atom for target, we still need to check for special, atom-less | 7061 | // If there is no atom for target, we still need to check for special, atom-less |
| 6991 | // symbols such as `___dso_handle`. | 7062 | // symbols such as `___dso_handle`. |
| 6992 | const target_name = self.getSymbolName(rel.target); | 7063 | const target_name = self.getSymbolName(rel.target); |
| ... | @@ -7119,8 +7190,9 @@ fn snapshotState(self: *MachO) !void { | ... | @@ -7119,8 +7190,9 @@ fn snapshotState(self: *MachO) !void { |
| 7119 | try writer.writeByte(']'); | 7190 | try writer.writeByte(']'); |
| 7120 | } | 7191 | } |
| 7121 | | 7192 | |
| 7122 | pub fn logSymAttributes(sym: macho.nlist_64, buf: *[4]u8) []const u8 { | 7193 | fn logSymAttributes(sym: macho.nlist_64, buf: *[9]u8) []const u8 { |
| 7123 | mem.set(u8, buf, '_'); | 7194 | mem.set(u8, buf[0..4], '_'); |
| | 7195 | mem.set(u8, buf[4..], ' '); |
| 7124 | if (sym.sect()) { | 7196 | if (sym.sect()) { |
| 7125 | buf[0] = 's'; | 7197 | buf[0] = 's'; |
| 7126 | } | 7198 | } |
| ... | @@ -7137,11 +7209,14 @@ pub fn logSymAttributes(sym: macho.nlist_64, buf: *[4]u8) []const u8 { | ... | @@ -7137,11 +7209,14 @@ pub fn logSymAttributes(sym: macho.nlist_64, buf: *[4]u8) []const u8 { |
| 7137 | if (sym.undf()) { | 7209 | if (sym.undf()) { |
| 7138 | buf[3] = 'u'; | 7210 | buf[3] = 'u'; |
| 7139 | } | 7211 | } |
| | 7212 | if (sym.n_desc == N_DESC_GCED) { |
| | 7213 | mem.copy(u8, buf[5..], "DEAD"); |
| | 7214 | } |
| 7140 | return buf[0..]; | 7215 | return buf[0..]; |
| 7141 | } | 7216 | } |
| 7142 | | 7217 | |
| 7143 | fn logSymtab(self: *MachO) void { | 7218 | fn logSymtab(self: *MachO) void { |
| 7144 | var buf: [4]u8 = undefined; | 7219 | var buf: [9]u8 = undefined; |
| 7145 | | 7220 | |
| 7146 | log.debug("symtab:", .{}); | 7221 | log.debug("symtab:", .{}); |
| 7147 | for (self.objects.items) |object, id| { | 7222 | for (self.objects.items) |object, id| { |
| ... | @@ -7186,42 +7261,50 @@ fn logSymtab(self: *MachO) void { | ... | @@ -7186,42 +7261,50 @@ fn logSymtab(self: *MachO) void { |
| 7186 | } | 7261 | } |
| 7187 | | 7262 | |
| 7188 | log.debug("GOT entries:", .{}); | 7263 | log.debug("GOT entries:", .{}); |
| 7189 | for (self.got_entries_table.values()) |value| { | 7264 | for (self.got_entries.items) |entry, i| { |
| 7190 | const target = self.got_entries.items[value].target; | 7265 | const atom_sym = entry.getSymbol(self); |
| 7191 | const target_sym = self.getSymbol(target); | 7266 | if (atom_sym.n_desc == N_DESC_GCED) continue; |
| 7192 | const atom = self.got_entries.items[value].atom; | 7267 | const target_sym = self.getSymbol(entry.target); |
| 7193 | const atom_sym = atom.getSymbol(self); | | |
| 7194 | | | |
| 7195 | if (target_sym.undf()) { | 7268 | if (target_sym.undf()) { |
| 7196 | log.debug(" {d}@{x} => import('{s}')", .{ value, atom_sym.n_value, self.getSymbolName(target) }); | 7269 | log.debug(" {d}@{x} => import('{s}')", .{ |
| | 7270 | i, |
| | 7271 | atom_sym.n_value, |
| | 7272 | self.getSymbolName(entry.target), |
| | 7273 | }); |
| 7197 | } else { | 7274 | } else { |
| 7198 | log.debug(" {d}@{x} => local(%{d}) in object({d})", .{ | 7275 | log.debug(" {d}@{x} => local(%{d}) in object({d}) {s}", .{ |
| 7199 | value, | 7276 | i, |
| 7200 | atom_sym.n_value, | 7277 | atom_sym.n_value, |
| 7201 | target.sym_index, | 7278 | entry.target.sym_index, |
| 7202 | target.file, | 7279 | entry.target.file, |
| | 7280 | logSymAttributes(target_sym, &buf), |
| 7203 | }); | 7281 | }); |
| 7204 | } | 7282 | } |
| 7205 | } | 7283 | } |
| 7206 | | 7284 | |
| 7207 | log.debug("__thread_ptrs entries:", .{}); | 7285 | log.debug("__thread_ptrs entries:", .{}); |
| 7208 | for (self.tlv_ptr_entries_table.values()) |value| { | 7286 | for (self.tlv_ptr_entries.items) |entry, i| { |
| 7209 | const target = self.tlv_ptr_entries.items[value].target; | 7287 | const atom_sym = entry.getSymbol(self); |
| 7210 | const target_sym = self.getSymbol(target); | 7288 | if (atom_sym.n_desc == N_DESC_GCED) continue; |
| 7211 | const atom = self.tlv_ptr_entries.items[value].atom; | 7289 | const target_sym = self.getSymbol(entry.target); |
| 7212 | const atom_sym = atom.getSymbol(self); | | |
| 7213 | assert(target_sym.undf()); | 7290 | assert(target_sym.undf()); |
| 7214 | log.debug(" {d}@{x} => import('{s}')", .{ value, atom_sym.n_value, self.getSymbolName(target) }); | 7291 | log.debug(" {d}@{x} => import('{s}')", .{ |
| | 7292 | i, |
| | 7293 | atom_sym.n_value, |
| | 7294 | self.getSymbolName(entry.target), |
| | 7295 | }); |
| 7215 | } | 7296 | } |
| 7216 | | 7297 | |
| 7217 | log.debug("stubs entries:", .{}); | 7298 | log.debug("stubs entries:", .{}); |
| 7218 | for (self.stubs_table.values()) |value| { | 7299 | for (self.stubs.items) |entry, i| { |
| 7219 | const target = self.stubs.items[value].target; | 7300 | const target_sym = self.getSymbol(entry.target); |
| 7220 | const target_sym = self.getSymbol(target); | 7301 | const atom_sym = entry.getSymbol(self); |
| 7221 | const atom = self.stubs.items[value].atom; | | |
| 7222 | const atom_sym = atom.getSymbol(self); | | |
| 7223 | assert(target_sym.undf()); | 7302 | assert(target_sym.undf()); |
| 7224 | log.debug(" {d}@{x} => import('{s}')", .{ value, atom_sym.n_value, self.getSymbolName(target) }); | 7303 | log.debug(" {d}@{x} => import('{s}')", .{ |
| | 7304 | i, |
| | 7305 | atom_sym.n_value, |
| | 7306 | self.getSymbolName(entry.target), |
| | 7307 | }); |
| 7225 | } | 7308 | } |
| 7226 | } | 7309 | } |
| 7227 | | 7310 | |
| ... | @@ -7248,7 +7331,6 @@ fn logAtoms(self: *MachO) void { | ... | @@ -7248,7 +7331,6 @@ fn logAtoms(self: *MachO) void { |
| 7248 | | 7331 | |
| 7249 | while (true) { | 7332 | while (true) { |
| 7250 | self.logAtom(atom); | 7333 | self.logAtom(atom); |
| 7251 | | | |
| 7252 | if (atom.next) |next| { | 7334 | if (atom.next) |next| { |
| 7253 | atom = next; | 7335 | atom = next; |
| 7254 | } else break; | 7336 | } else break; |
| ... | @@ -7256,14 +7338,17 @@ fn logAtoms(self: *MachO) void { | ... | @@ -7256,14 +7338,17 @@ fn logAtoms(self: *MachO) void { |
| 7256 | } | 7338 | } |
| 7257 | } | 7339 | } |
| 7258 | | 7340 | |
| 7259 | pub fn logAtom(self: *MachO, atom: *const Atom) void { | 7341 | fn logAtom(self: *MachO, atom: *const Atom) void { |
| 7260 | const sym = atom.getSymbol(self); | 7342 | const sym = atom.getSymbol(self); |
| 7261 | const sym_name = atom.getName(self); | 7343 | const sym_name = atom.getName(self); |
| 7262 | log.debug(" ATOM(%{d}, '{s}') @ {x} in object({d})", .{ | 7344 | log.debug(" ATOM(%{d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({d}) in sect({d})", .{ |
| 7263 | atom.sym_index, | 7345 | atom.sym_index, |
| 7264 | sym_name, | 7346 | sym_name, |
| 7265 | sym.n_value, | 7347 | sym.n_value, |
| | 7348 | atom.size, |
| | 7349 | atom.alignment, |
| 7266 | atom.file, | 7350 | atom.file, |
| | 7351 | sym.n_sect, |
| 7267 | }); | 7352 | }); |
| 7268 | | 7353 | |
| 7269 | for (atom.contained.items) |sym_off| { | 7354 | for (atom.contained.items) |sym_off| { |
| ... | @@ -7271,13 +7356,15 @@ pub fn logAtom(self: *MachO, atom: *const Atom) void { | ... | @@ -7271,13 +7356,15 @@ pub fn logAtom(self: *MachO, atom: *const Atom) void { |
| 7271 | .sym_index = sym_off.sym_index, | 7356 | .sym_index = sym_off.sym_index, |
| 7272 | .file = atom.file, | 7357 | .file = atom.file, |
| 7273 | }); | 7358 | }); |
| 7274 | const inner_sym_name = self.getSymbolName(.{ .sym_index = sym_off.sym_index, .file = atom.file }); | 7359 | const inner_sym_name = self.getSymbolName(.{ |
| 7275 | log.debug(" (%{d}, '{s}') @ {x} ({x}) in object({d})", .{ | 7360 | .sym_index = sym_off.sym_index, |
| | 7361 | .file = atom.file, |
| | 7362 | }); |
| | 7363 | log.debug(" (%{d}, '{s}') @ {x} ({x})", .{ |
| 7276 | sym_off.sym_index, | 7364 | sym_off.sym_index, |
| 7277 | inner_sym_name, | 7365 | inner_sym_name, |
| 7278 | inner_sym.n_value, | 7366 | inner_sym.n_value, |
| 7279 | sym_off.offset, | 7367 | sym_off.offset, |
| 7280 | atom.file, | | |
| 7281 | }); | 7368 | }); |
| 7282 | } | 7369 | } |
| 7283 | } | 7370 | } |