| ... | @@ -35,6 +35,7 @@ const Section = MachO.Section; | ... | @@ -35,6 +35,7 @@ const Section = MachO.Section; |
| 35 | const StringTable = @import("../strtab.zig").StringTable; | 35 | const StringTable = @import("../strtab.zig").StringTable; |
| 36 | const SymbolWithLoc = MachO.SymbolWithLoc; | 36 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 37 | const SymbolResolver = MachO.SymbolResolver; | 37 | const SymbolResolver = MachO.SymbolResolver; |
| | 38 | const TableSection = @import("../table_section.zig").TableSection; |
| 38 | const Trie = @import("Trie.zig"); | 39 | const Trie = @import("Trie.zig"); |
| 39 | const UnwindInfo = @import("UnwindInfo.zig"); | 40 | const UnwindInfo = @import("UnwindInfo.zig"); |
| 40 | | 41 | |
| ... | @@ -66,6 +67,8 @@ pub const Zld = struct { | ... | @@ -66,6 +67,8 @@ pub const Zld = struct { |
| 66 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, | 67 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, |
| 67 | sections: std.MultiArrayList(Section) = .{}, | 68 | sections: std.MultiArrayList(Section) = .{}, |
| 68 | | 69 | |
| | 70 | got_section_index: ?u8 = null, |
| | 71 | |
| 69 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 72 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 70 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, | 73 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
| 71 | | 74 | |
| ... | @@ -81,8 +84,7 @@ pub const Zld = struct { | ... | @@ -81,8 +84,7 @@ pub const Zld = struct { |
| 81 | tlv_ptr_entries: std.ArrayListUnmanaged(IndirectPointer) = .{}, | 84 | tlv_ptr_entries: std.ArrayListUnmanaged(IndirectPointer) = .{}, |
| 82 | tlv_ptr_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 85 | tlv_ptr_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 83 | | 86 | |
| 84 | got_entries: std.ArrayListUnmanaged(IndirectPointer) = .{}, | 87 | got_table: TableSection(SymbolWithLoc) = .{}, |
| 85 | got_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | | |
| 86 | | 88 | |
| 87 | stubs: std.ArrayListUnmanaged(IndirectPointer) = .{}, | 89 | stubs: std.ArrayListUnmanaged(IndirectPointer) = .{}, |
| 88 | stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 90 | stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| ... | @@ -266,32 +268,6 @@ pub const Zld = struct { | ... | @@ -266,32 +268,6 @@ pub const Zld = struct { |
| 266 | return index; | 268 | return index; |
| 267 | } | 269 | } |
| 268 | | 270 | |
| 269 | pub fn createGotAtom(self: *Zld) !AtomIndex { | | |
| 270 | const sym_index = try self.allocateSymbol(); | | |
| 271 | const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3); | | |
| 272 | const sym = self.getSymbolPtr(.{ .sym_index = sym_index }); | | |
| 273 | sym.n_type = macho.N_SECT; | | |
| 274 | | | |
| 275 | const sect_id = self.getSectionByName("__DATA_CONST", "__got") orelse | | |
| 276 | try self.initSection("__DATA_CONST", "__got", .{ | | |
| 277 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, | | |
| 278 | }); | | |
| 279 | sym.n_sect = sect_id + 1; | | |
| 280 | | | |
| 281 | self.addAtomToSection(atom_index); | | |
| 282 | | | |
| 283 | return atom_index; | | |
| 284 | } | | |
| 285 | | | |
| 286 | fn writeGotPointer(self: *Zld, got_index: u32, writer: anytype) !void { | | |
| 287 | const target_addr = blk: { | | |
| 288 | const entry = self.got_entries.items[got_index]; | | |
| 289 | const sym = entry.getTargetSymbol(self); | | |
| 290 | break :blk sym.n_value; | | |
| 291 | }; | | |
| 292 | try writer.writeIntLittle(u64, target_addr); | | |
| 293 | } | | |
| 294 | | | |
| 295 | pub fn createTlvPtrAtom(self: *Zld) !AtomIndex { | 271 | pub fn createTlvPtrAtom(self: *Zld) !AtomIndex { |
| 296 | const sym_index = try self.allocateSymbol(); | 272 | const sym_index = try self.allocateSymbol(); |
| 297 | const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3); | 273 | const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3); |
| ... | @@ -311,16 +287,9 @@ pub const Zld = struct { | ... | @@ -311,16 +287,9 @@ pub const Zld = struct { |
| 311 | } | 287 | } |
| 312 | | 288 | |
| 313 | fn createDyldStubBinderGotAtom(self: *Zld) !void { | 289 | fn createDyldStubBinderGotAtom(self: *Zld) !void { |
| 314 | const gpa = self.gpa; | | |
| 315 | const global_index = self.dyld_stub_binder_index orelse return; | 290 | const global_index = self.dyld_stub_binder_index orelse return; |
| 316 | const target = self.globals.items[global_index]; | 291 | const target = self.globals.items[global_index]; |
| 317 | const atom_index = try self.createGotAtom(); | 292 | try self.addGotEntry(target); |
| 318 | const got_index = @as(u32, @intCast(self.got_entries.items.len)); | | |
| 319 | try self.got_entries.append(gpa, .{ | | |
| 320 | .target = target, | | |
| 321 | .atom_index = atom_index, | | |
| 322 | }); | | |
| 323 | try self.got_table.putNoClobber(gpa, target, got_index); | | |
| 324 | } | 293 | } |
| 325 | | 294 | |
| 326 | fn createDyldPrivateAtom(self: *Zld) !void { | 295 | fn createDyldPrivateAtom(self: *Zld) !void { |
| ... | @@ -381,9 +350,7 @@ pub const Zld = struct { | ... | @@ -381,9 +350,7 @@ pub const Zld = struct { |
| 381 | }; | 350 | }; |
| 382 | const dyld_stub_binder_got_addr = blk: { | 351 | const dyld_stub_binder_got_addr = blk: { |
| 383 | const sym_loc = self.globals.items[self.dyld_stub_binder_index.?]; | 352 | const sym_loc = self.globals.items[self.dyld_stub_binder_index.?]; |
| 384 | const index = self.got_table.get(sym_loc).?; | 353 | break :blk self.getGotEntryAddress(sym_loc).?; |
| 385 | const entry = self.got_entries.items[index]; | | |
| 386 | break :blk entry.getAtomSymbol(self).n_value; | | |
| 387 | }; | 354 | }; |
| 388 | try stub_helpers.writeStubHelperPreambleCode(.{ | 355 | try stub_helpers.writeStubHelperPreambleCode(.{ |
| 389 | .cpu_arch = cpu_arch, | 356 | .cpu_arch = cpu_arch, |
| ... | @@ -876,7 +843,6 @@ pub const Zld = struct { | ... | @@ -876,7 +843,6 @@ pub const Zld = struct { |
| 876 | | 843 | |
| 877 | self.tlv_ptr_entries.deinit(gpa); | 844 | self.tlv_ptr_entries.deinit(gpa); |
| 878 | self.tlv_ptr_table.deinit(gpa); | 845 | self.tlv_ptr_table.deinit(gpa); |
| 879 | self.got_entries.deinit(gpa); | | |
| 880 | self.got_table.deinit(gpa); | 846 | self.got_table.deinit(gpa); |
| 881 | self.stubs.deinit(gpa); | 847 | self.stubs.deinit(gpa); |
| 882 | self.stubs_table.deinit(gpa); | 848 | self.stubs_table.deinit(gpa); |
| ... | @@ -993,6 +959,16 @@ pub const Zld = struct { | ... | @@ -993,6 +959,16 @@ pub const Zld = struct { |
| 993 | return global_index; | 959 | return global_index; |
| 994 | } | 960 | } |
| 995 | | 961 | |
| | 962 | pub fn addGotEntry(zld: *Zld, target: SymbolWithLoc) !void { |
| | 963 | if (zld.got_table.lookup.contains(target)) return; |
| | 964 | _ = try zld.got_table.allocateEntry(zld.gpa, target); |
| | 965 | if (zld.got_section_index == null) { |
| | 966 | zld.got_section_index = try zld.initSection("__DATA_CONST", "__got", .{ |
| | 967 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| | 968 | }); |
| | 969 | } |
| | 970 | } |
| | 971 | |
| 996 | fn allocateSpecialSymbols(self: *Zld) !void { | 972 | fn allocateSpecialSymbols(self: *Zld) !void { |
| 997 | for (&[_]?u32{ | 973 | for (&[_]?u32{ |
| 998 | self.dso_handle_index, | 974 | self.dso_handle_index, |
| ... | @@ -1056,9 +1032,7 @@ pub const Zld = struct { | ... | @@ -1056,9 +1032,7 @@ pub const Zld = struct { |
| 1056 | buffer.appendSliceAssumeCapacity(&[_]u8{0} ** @sizeOf(u64)); | 1032 | buffer.appendSliceAssumeCapacity(&[_]u8{0} ** @sizeOf(u64)); |
| 1057 | } else if (atom.getFile() == null) outer: { | 1033 | } else if (atom.getFile() == null) outer: { |
| 1058 | switch (header.type()) { | 1034 | switch (header.type()) { |
| 1059 | macho.S_NON_LAZY_SYMBOL_POINTERS => { | 1035 | macho.S_NON_LAZY_SYMBOL_POINTERS => unreachable, |
| 1060 | try self.writeGotPointer(count, buffer.writer()); | | |
| 1061 | }, | | |
| 1062 | macho.S_LAZY_SYMBOL_POINTERS => { | 1036 | macho.S_LAZY_SYMBOL_POINTERS => { |
| 1063 | try self.writeLazyPointer(count, buffer.writer()); | 1037 | try self.writeLazyPointer(count, buffer.writer()); |
| 1064 | }, | 1038 | }, |
| ... | @@ -1113,41 +1087,70 @@ pub const Zld = struct { | ... | @@ -1113,41 +1087,70 @@ pub const Zld = struct { |
| 1113 | } | 1087 | } |
| 1114 | } | 1088 | } |
| 1115 | | 1089 | |
| | 1090 | fn writeGotEntries(self: *Zld) !void { |
| | 1091 | const sect_id = self.got_section_index orelse return; |
| | 1092 | const header = self.sections.items(.header)[sect_id]; |
| | 1093 | var buffer = try std.ArrayList(u8).initCapacity(self.gpa, header.size); |
| | 1094 | defer buffer.deinit(); |
| | 1095 | for (self.got_table.entries.items) |entry| { |
| | 1096 | const sym = self.getSymbol(entry); |
| | 1097 | buffer.writer().writeIntLittle(u64, sym.n_value) catch unreachable; |
| | 1098 | } |
| | 1099 | log.debug("writing .got contents at file offset 0x{x}", .{header.offset}); |
| | 1100 | try self.file.pwriteAll(buffer.items, header.offset); |
| | 1101 | } |
| | 1102 | |
| 1116 | fn pruneAndSortSections(self: *Zld) !void { | 1103 | fn pruneAndSortSections(self: *Zld) !void { |
| 1117 | const gpa = self.gpa; | 1104 | const Entry = struct { |
| | 1105 | index: u8, |
| 1118 | | 1106 | |
| 1119 | const SortSection = struct { | 1107 | pub fn lessThan(zld: *Zld, lhs: @This(), rhs: @This()) bool { |
| 1120 | pub fn lessThan(_: void, lhs: Section, rhs: Section) bool { | 1108 | const lhs_header = zld.sections.items(.header)[lhs.index]; |
| 1121 | return getSectionPrecedence(lhs.header) < getSectionPrecedence(rhs.header); | 1109 | const rhs_header = zld.sections.items(.header)[rhs.index]; |
| | 1110 | return getSectionPrecedence(lhs_header) < getSectionPrecedence(rhs_header); |
| 1122 | } | 1111 | } |
| 1123 | }; | 1112 | }; |
| 1124 | | 1113 | |
| 1125 | const slice = self.sections.slice(); | 1114 | const gpa = self.gpa; |
| 1126 | var sections = std.ArrayList(Section).init(gpa); | | |
| 1127 | defer sections.deinit(); | | |
| 1128 | try sections.ensureTotalCapacity(slice.len); | | |
| 1129 | | 1115 | |
| 1130 | { | 1116 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.sections.slice().len); |
| 1131 | var i: u8 = 0; | 1117 | defer entries.deinit(); |
| 1132 | while (i < slice.len) : (i += 1) { | 1118 | |
| 1133 | const section = self.sections.get(i); | 1119 | for (0..self.sections.slice().len) |index| { |
| 1134 | if (section.header.size == 0) { | 1120 | const section = self.sections.get(index); |
| 1135 | log.debug("pruning section {s},{s} {?d}", .{ | 1121 | if (section.header.size == 0) { |
| 1136 | section.header.segName(), | 1122 | log.debug("pruning section {s},{s} {?d}", .{ |
| 1137 | section.header.sectName(), | 1123 | section.header.segName(), |
| 1138 | section.first_atom_index, | 1124 | section.header.sectName(), |
| 1139 | }); | 1125 | section.first_atom_index, |
| 1140 | continue; | 1126 | }); |
| 1141 | } | 1127 | continue; |
| 1142 | sections.appendAssumeCapacity(section); | | |
| 1143 | } | 1128 | } |
| | 1129 | entries.appendAssumeCapacity(.{ .index = @intCast(index) }); |
| | 1130 | } |
| | 1131 | |
| | 1132 | mem.sort(Entry, entries.items, self, Entry.lessThan); |
| | 1133 | |
| | 1134 | var slice = self.sections.toOwnedSlice(); |
| | 1135 | defer slice.deinit(gpa); |
| | 1136 | |
| | 1137 | const backlinks = try gpa.alloc(u8, slice.len); |
| | 1138 | defer gpa.free(backlinks); |
| | 1139 | for (entries.items, 0..) |entry, i| { |
| | 1140 | backlinks[entry.index] = @as(u8, @intCast(i)); |
| 1144 | } | 1141 | } |
| 1145 | | 1142 | |
| 1146 | mem.sort(Section, sections.items, {}, SortSection.lessThan); | 1143 | try self.sections.ensureTotalCapacity(gpa, entries.items.len); |
| | 1144 | for (entries.items) |entry| { |
| | 1145 | self.sections.appendAssumeCapacity(slice.get(entry.index)); |
| | 1146 | } |
| 1147 | | 1147 | |
| 1148 | self.sections.shrinkRetainingCapacity(0); | 1148 | for (&[_]*?u8{ |
| 1149 | for (sections.items) |out| { | 1149 | &self.got_section_index, |
| 1150 | self.sections.appendAssumeCapacity(out); | 1150 | }) |maybe_index| { |
| | 1151 | if (maybe_index.*) |*index| { |
| | 1152 | index.* = backlinks[index.*]; |
| | 1153 | } |
| 1151 | } | 1154 | } |
| 1152 | } | 1155 | } |
| 1153 | | 1156 | |
| ... | @@ -1227,6 +1230,12 @@ pub const Zld = struct { | ... | @@ -1227,6 +1230,12 @@ pub const Zld = struct { |
| 1227 | } else break; | 1230 | } else break; |
| 1228 | } | 1231 | } |
| 1229 | } | 1232 | } |
| | 1233 | |
| | 1234 | if (self.got_section_index) |sect_id| { |
| | 1235 | const header = &self.sections.items(.header)[sect_id]; |
| | 1236 | header.size = self.got_table.count() * @sizeOf(u64); |
| | 1237 | header.@"align" = 3; |
| | 1238 | } |
| 1230 | } | 1239 | } |
| 1231 | | 1240 | |
| 1232 | fn allocateSegments(self: *Zld) !void { | 1241 | fn allocateSegments(self: *Zld) !void { |
| ... | @@ -1448,40 +1457,12 @@ pub const Zld = struct { | ... | @@ -1448,40 +1457,12 @@ pub const Zld = struct { |
| 1448 | seg.vmsize = mem.alignForward(u64, seg.filesize, MachO.getPageSize(self.options.target.cpu.arch)); | 1457 | seg.vmsize = mem.alignForward(u64, seg.filesize, MachO.getPageSize(self.options.target.cpu.arch)); |
| 1449 | } | 1458 | } |
| 1450 | | 1459 | |
| 1451 | fn collectRebaseDataFromContainer( | | |
| 1452 | self: *Zld, | | |
| 1453 | sect_id: u8, | | |
| 1454 | rebase: *Rebase, | | |
| 1455 | container: anytype, | | |
| 1456 | ) !void { | | |
| 1457 | const slice = self.sections.slice(); | | |
| 1458 | const segment_index = slice.items(.segment_index)[sect_id]; | | |
| 1459 | const seg = self.getSegment(sect_id); | | |
| 1460 | | | |
| 1461 | try rebase.entries.ensureUnusedCapacity(self.gpa, container.items.len); | | |
| 1462 | | | |
| 1463 | for (container.items) |entry| { | | |
| 1464 | const target_sym = entry.getTargetSymbol(self); | | |
| 1465 | if (target_sym.undf()) continue; | | |
| 1466 | | | |
| 1467 | const atom_sym = entry.getAtomSymbol(self); | | |
| 1468 | const base_offset = atom_sym.n_value - seg.vmaddr; | | |
| 1469 | | | |
| 1470 | log.debug(" | rebase at {x}", .{base_offset}); | | |
| 1471 | | | |
| 1472 | rebase.entries.appendAssumeCapacity(.{ | | |
| 1473 | .offset = base_offset, | | |
| 1474 | .segment_id = segment_index, | | |
| 1475 | }); | | |
| 1476 | } | | |
| 1477 | } | | |
| 1478 | | | |
| 1479 | fn collectRebaseData(self: *Zld, rebase: *Rebase) !void { | 1460 | fn collectRebaseData(self: *Zld, rebase: *Rebase) !void { |
| 1480 | log.debug("collecting rebase data", .{}); | 1461 | log.debug("collecting rebase data", .{}); |
| 1481 | | 1462 | |
| 1482 | // First, unpack GOT entries | 1463 | // First, unpack GOT entries |
| 1483 | if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| { | 1464 | if (self.got_section_index) |sect_id| { |
| 1484 | try self.collectRebaseDataFromContainer(sect_id, rebase, self.got_entries); | 1465 | try MachO.collectRebaseDataFromTableSection(self.gpa, self, sect_id, rebase, self.got_table); |
| 1485 | } | 1466 | } |
| 1486 | | 1467 | |
| 1487 | const slice = self.sections.slice(); | 1468 | const slice = self.sections.slice(); |
| ... | @@ -1543,7 +1524,11 @@ pub const Zld = struct { | ... | @@ -1543,7 +1524,11 @@ pub const Zld = struct { |
| 1543 | }; | 1524 | }; |
| 1544 | | 1525 | |
| 1545 | if (should_rebase) { | 1526 | if (should_rebase) { |
| 1546 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); | 1527 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ |
| | 1528 | atom_index, |
| | 1529 | atom.sym_index, |
| | 1530 | self.getSymbolName(atom.getSymbolWithLoc()), |
| | 1531 | }); |
| 1547 | | 1532 | |
| 1548 | const code = Atom.getAtomCode(self, atom_index); | 1533 | const code = Atom.getAtomCode(self, atom_index); |
| 1549 | const relocs = Atom.getAtomRelocs(self, atom_index); | 1534 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| ... | @@ -1639,8 +1624,8 @@ pub const Zld = struct { | ... | @@ -1639,8 +1624,8 @@ pub const Zld = struct { |
| 1639 | log.debug("collecting bind data", .{}); | 1624 | log.debug("collecting bind data", .{}); |
| 1640 | | 1625 | |
| 1641 | // First, unpack GOT section | 1626 | // First, unpack GOT section |
| 1642 | if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| { | 1627 | if (self.got_section_index) |sect_id| { |
| 1643 | try self.collectBindDataFromContainer(sect_id, bind, self.got_entries); | 1628 | try MachO.collectBindDataFromTableSection(self.gpa, self, sect_id, bind, self.got_table); |
| 1644 | } | 1629 | } |
| 1645 | | 1630 | |
| 1646 | // Next, unpack TLV pointers section | 1631 | // Next, unpack TLV pointers section |
| ... | @@ -2237,7 +2222,7 @@ pub const Zld = struct { | ... | @@ -2237,7 +2222,7 @@ pub const Zld = struct { |
| 2237 | fn writeDysymtab(self: *Zld, ctx: SymtabCtx) !void { | 2222 | fn writeDysymtab(self: *Zld, ctx: SymtabCtx) !void { |
| 2238 | const gpa = self.gpa; | 2223 | const gpa = self.gpa; |
| 2239 | const nstubs = @as(u32, @intCast(self.stubs.items.len)); | 2224 | const nstubs = @as(u32, @intCast(self.stubs.items.len)); |
| 2240 | const ngot_entries = @as(u32, @intCast(self.got_entries.items.len)); | 2225 | const ngot_entries = @as(u32, @intCast(self.got_table.lookup.count())); |
| 2241 | const nindirectsyms = nstubs * 2 + ngot_entries; | 2226 | const nindirectsyms = nstubs * 2 + ngot_entries; |
| 2242 | const iextdefsym = ctx.nlocalsym; | 2227 | const iextdefsym = ctx.nlocalsym; |
| 2243 | const iundefsym = iextdefsym + ctx.nextdefsym; | 2228 | const iundefsym = iextdefsym + ctx.nextdefsym; |
| ... | @@ -2266,13 +2251,14 @@ pub const Zld = struct { | ... | @@ -2266,13 +2251,14 @@ pub const Zld = struct { |
| 2266 | } | 2251 | } |
| 2267 | } | 2252 | } |
| 2268 | | 2253 | |
| 2269 | if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| { | 2254 | if (self.got_section_index) |sect_id| { |
| 2270 | const got = &self.sections.items(.header)[sect_id]; | 2255 | const got = &self.sections.items(.header)[sect_id]; |
| 2271 | got.reserved1 = nstubs; | 2256 | got.reserved1 = nstubs; |
| 2272 | for (self.got_entries.items) |entry| { | 2257 | for (self.got_table.entries.items) |entry| { |
| 2273 | const target_sym = entry.getTargetSymbol(self); | 2258 | if (!self.got_table.lookup.contains(entry)) continue; |
| | 2259 | const target_sym = self.getSymbol(entry); |
| 2274 | if (target_sym.undf()) { | 2260 | if (target_sym.undf()) { |
| 2275 | try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry.target).?); | 2261 | try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry).?); |
| 2276 | } else { | 2262 | } else { |
| 2277 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); | 2263 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); |
| 2278 | } | 2264 | } |
| ... | @@ -2496,12 +2482,10 @@ pub const Zld = struct { | ... | @@ -2496,12 +2482,10 @@ pub const Zld = struct { |
| 2496 | } | 2482 | } |
| 2497 | } | 2483 | } |
| 2498 | | 2484 | |
| 2499 | /// Returns GOT atom that references `sym_with_loc` if one exists. | 2485 | pub fn getGotEntryAddress(self: *Zld, sym_with_loc: SymbolWithLoc) ?u64 { |
| 2500 | /// Returns null otherwise. | 2486 | const index = self.got_table.lookup.get(sym_with_loc) orelse return null; |
| 2501 | pub fn getGotAtomIndexForSymbol(self: *Zld, sym_with_loc: SymbolWithLoc) ?AtomIndex { | 2487 | const header = self.sections.items(.header)[self.got_section_index.?]; |
| 2502 | const index = self.got_table.get(sym_with_loc) orelse return null; | 2488 | return header.addr + @sizeOf(u64) * index; |
| 2503 | const entry = self.got_entries.items[index]; | | |
| 2504 | return entry.atom_index; | | |
| 2505 | } | 2489 | } |
| 2506 | | 2490 | |
| 2507 | /// Returns stubs atom that references `sym_with_loc` if one exists. | 2491 | /// Returns stubs atom that references `sym_with_loc` if one exists. |
| ... | @@ -2849,26 +2833,7 @@ pub const Zld = struct { | ... | @@ -2849,26 +2833,7 @@ pub const Zld = struct { |
| 2849 | } | 2833 | } |
| 2850 | | 2834 | |
| 2851 | scoped_log.debug("GOT entries:", .{}); | 2835 | scoped_log.debug("GOT entries:", .{}); |
| 2852 | for (self.got_entries.items, 0..) |entry, i| { | 2836 | scoped_log.debug("{}", .{self.got_table}); |
| 2853 | const atom_sym = entry.getAtomSymbol(self); | | |
| 2854 | const target_sym = entry.getTargetSymbol(self); | | |
| 2855 | const target_sym_name = entry.getTargetSymbolName(self); | | |
| 2856 | if (target_sym.undf()) { | | |
| 2857 | scoped_log.debug(" {d}@{x} => import('{s}')", .{ | | |
| 2858 | i, | | |
| 2859 | atom_sym.n_value, | | |
| 2860 | target_sym_name, | | |
| 2861 | }); | | |
| 2862 | } else { | | |
| 2863 | scoped_log.debug(" {d}@{x} => local(%{d}) in object({?}) {s}", .{ | | |
| 2864 | i, | | |
| 2865 | atom_sym.n_value, | | |
| 2866 | entry.target.sym_index, | | |
| 2867 | entry.target.file, | | |
| 2868 | logSymAttributes(target_sym, buf[0..4]), | | |
| 2869 | }); | | |
| 2870 | } | | |
| 2871 | } | | |
| 2872 | | 2837 | |
| 2873 | scoped_log.debug("__thread_ptrs entries:", .{}); | 2838 | scoped_log.debug("__thread_ptrs entries:", .{}); |
| 2874 | for (self.tlv_ptr_entries.items, 0..) |entry, i| { | 2839 | for (self.tlv_ptr_entries.items, 0..) |entry, i| { |
| ... | @@ -3470,6 +3435,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3470,6 +3435,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3470 | } | 3435 | } |
| 3471 | | 3436 | |
| 3472 | try zld.writeAtoms(); | 3437 | try zld.writeAtoms(); |
| | 3438 | try zld.writeGotEntries(); |
| 3473 | try eh_frame.write(&zld, &unwind_info); | 3439 | try eh_frame.write(&zld, &unwind_info); |
| 3474 | try unwind_info.write(&zld); | 3440 | try unwind_info.write(&zld); |
| 3475 | try zld.writeLinkeditSegmentData(); | 3441 | try zld.writeLinkeditSegmentData(); |