authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-07 07:37:35+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-13 11:47:51+02:00
log094ff60252cf57b2ae7bb69abb3e8e696873a3be
tree34b87d0d8962450c64de422fc2438236f3d70f8e
parent09b6bd86dea690aeb1fe1a832bb56b44b414120b

macho: emit TLV pointers and variables


3 files changed, 135 insertions(+), 36 deletions(-)

src/link.zig+2-2
...@@ -540,7 +540,7 @@ pub const File = struct {...@@ -540,7 +540,7 @@ pub const File = struct {
540 /// May be called before or after updateDeclExports for any given Decl.540 /// May be called before or after updateDeclExports for any given Decl.
541 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {541 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
542 const decl = module.declPtr(decl_index);542 const decl = module.declPtr(decl_index);
543 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmtDebug() });543 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmt(module) });
544 assert(decl.has_tv);544 assert(decl.has_tv);
545 if (build_options.only_c) {545 if (build_options.only_c) {
546 assert(base.tag == .c);546 assert(base.tag == .c);
...@@ -564,7 +564,7 @@ pub const File = struct {...@@ -564,7 +564,7 @@ pub const File = struct {
564 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {564 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {
565 const owner_decl = module.declPtr(func.owner_decl);565 const owner_decl = module.declPtr(func.owner_decl);
566 log.debug("updateFunc {*} ({s}), type={}", .{566 log.debug("updateFunc {*} ({s}), type={}", .{
567 owner_decl, owner_decl.name, owner_decl.ty.fmtDebug(),567 owner_decl, owner_decl.name, owner_decl.ty.fmt(module),
568 });568 });
569 if (build_options.only_c) {569 if (build_options.only_c) {
570 assert(base.tag == .c);570 assert(base.tag == .c);
src/link/MachO.zig+119-31
...@@ -1338,13 +1338,12 @@ pub fn createAtom(self: *MachO) !Atom.Index {...@@ -1338,13 +1338,12 @@ pub fn createAtom(self: *MachO) !Atom.Index {
13381338
1339pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index {1339pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index {
1340 const atom_index = try self.createAtom();1340 const atom_index = try self.createAtom();
1341 const atom = self.getAtomPtr(atom_index);1341 self.getAtomPtr(atom_index).size = @sizeOf(u64);
1342 atom.size = @sizeOf(u64);
13431342
1344 const sym = atom.getSymbolPtr(self);1343 const sym = self.getAtom(atom_index).getSymbolPtr(self);
1345 sym.n_type = macho.N_SECT;1344 sym.n_type = macho.N_SECT;
1346 sym.n_sect = self.got_section_index.? + 1;1345 sym.n_sect = self.got_section_index.? + 1;
1347 sym.n_value = try self.allocateAtom(atom_index, atom.size, @alignOf(u64));1346 sym.n_value = try self.allocateAtom(atom_index, @sizeOf(u64), @alignOf(u64));
13481347
1349 log.debug("allocated GOT atom at 0x{x}", .{sym.n_value});1348 log.debug("allocated GOT atom at 0x{x}", .{sym.n_value});
13501349
...@@ -1553,7 +1552,7 @@ fn createStubHelperAtom(self: *MachO) !Atom.Index {...@@ -1553,7 +1552,7 @@ fn createStubHelperAtom(self: *MachO) !Atom.Index {
15531552
1554 try Atom.addRelocation(self, atom_index, .{1553 try Atom.addRelocation(self, atom_index, .{
1555 .type = .branch,1554 .type = .branch,
1556 .target = .{ .sym_index = stub_helper_preamble_atom_sym_index, .file = null },1555 .target = .{ .sym_index = stub_helper_preamble_atom_sym_index },
1557 .offset = 6,1556 .offset = 6,
1558 .addend = 0,1557 .addend = 0,
1559 .pcrel = true,1558 .pcrel = true,
...@@ -1576,7 +1575,7 @@ fn createStubHelperAtom(self: *MachO) !Atom.Index {...@@ -1576,7 +1575,7 @@ fn createStubHelperAtom(self: *MachO) !Atom.Index {
15761575
1577 try Atom.addRelocation(self, atom_index, .{1576 try Atom.addRelocation(self, atom_index, .{
1578 .type = .branch,1577 .type = .branch,
1579 .target = .{ .sym_index = stub_helper_preamble_atom_sym_index, .file = null },1578 .target = .{ .sym_index = stub_helper_preamble_atom_sym_index },
1580 .offset = 4,1579 .offset = 4,
1581 .addend = 0,1580 .addend = 0,
1582 .pcrel = true,1581 .pcrel = true,
...@@ -1604,7 +1603,7 @@ fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLo...@@ -1604,7 +1603,7 @@ fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLo
16041603
1605 try Atom.addRelocation(self, atom_index, .{1604 try Atom.addRelocation(self, atom_index, .{
1606 .type = .unsigned,1605 .type = .unsigned,
1607 .target = .{ .sym_index = stub_sym_index, .file = null },1606 .target = .{ .sym_index = stub_sym_index },
1608 .offset = 0,1607 .offset = 0,
1609 .addend = 0,1608 .addend = 0,
1610 .pcrel = false,1609 .pcrel = false,
...@@ -1658,7 +1657,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {...@@ -1658,7 +1657,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
16581657
1659 try Atom.addRelocation(self, atom_index, .{1658 try Atom.addRelocation(self, atom_index, .{
1660 .type = .branch,1659 .type = .branch,
1661 .target = .{ .sym_index = laptr_sym_index, .file = null },1660 .target = .{ .sym_index = laptr_sym_index },
1662 .offset = 2,1661 .offset = 2,
1663 .addend = 0,1662 .addend = 0,
1664 .pcrel = true,1663 .pcrel = true,
...@@ -1680,7 +1679,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {...@@ -1680,7 +1679,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
1680 try Atom.addRelocations(self, atom_index, &[_]Relocation{1679 try Atom.addRelocations(self, atom_index, &[_]Relocation{
1681 .{1680 .{
1682 .type = .page,1681 .type = .page,
1683 .target = .{ .sym_index = laptr_sym_index, .file = null },1682 .target = .{ .sym_index = laptr_sym_index },
1684 .offset = 0,1683 .offset = 0,
1685 .addend = 0,1684 .addend = 0,
1686 .pcrel = true,1685 .pcrel = true,
...@@ -1688,7 +1687,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {...@@ -1688,7 +1687,7 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
1688 },1687 },
1689 .{1688 .{
1690 .type = .pageoff,1689 .type = .pageoff,
1691 .target = .{ .sym_index = laptr_sym_index, .file = null },1690 .target = .{ .sym_index = laptr_sym_index },
1692 .offset = 4,1691 .offset = 4,
1693 .addend = 0,1692 .addend = 0,
1694 .pcrel = false,1693 .pcrel = false,
...@@ -1706,6 +1705,67 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {...@@ -1706,6 +1705,67 @@ fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
1706 return atom_index;1705 return atom_index;
1707}1706}
17081707
1708fn createThreadLocalDescriptorAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index {
1709 const gpa = self.base.allocator;
1710 const size = 3 * @sizeOf(u64);
1711 const required_alignment: u32 = 1;
1712 const atom_index = try self.createAtom();
1713 self.getAtomPtr(atom_index).size = size;
1714
1715 const target_sym_name = self.getSymbolName(target);
1716 const name_delimiter = mem.indexOf(u8, target_sym_name, "$").?;
1717 const sym_name = try gpa.dupe(u8, target_sym_name[0..name_delimiter]);
1718 defer gpa.free(sym_name);
1719
1720 const sym = self.getAtom(atom_index).getSymbolPtr(self);
1721 sym.n_type = macho.N_SECT;
1722 sym.n_sect = self.thread_vars_section_index.? + 1;
1723 sym.n_strx = try self.strtab.insert(gpa, sym_name);
1724 sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
1725
1726 log.debug("allocated threadlocal descriptor atom '{s}' at 0x{x}", .{ sym_name, sym.n_value });
1727
1728 try Atom.addRelocation(self, atom_index, .{
1729 .type = .tlv_initializer,
1730 .target = target,
1731 .offset = 0x10,
1732 .addend = 0,
1733 .pcrel = false,
1734 .length = 3,
1735 });
1736
1737 var code: [size]u8 = undefined;
1738 mem.set(u8, &code, 0);
1739 try self.writeAtom(atom_index, &code);
1740
1741 return atom_index;
1742}
1743
1744fn createThreadLocalPointerAtom(self: *MachO, tlv_desc_sym_index: u32) !Atom.Index {
1745 const atom_index = try self.createAtom();
1746 self.getAtomPtr(atom_index).size = @sizeOf(u64);
1747
1748 const sym = self.getAtom(atom_index).getSymbolPtr(self);
1749 sym.n_type = macho.N_SECT;
1750 sym.n_sect = self.thread_ptr_section_index.? + 1;
1751 sym.n_value = try self.allocateAtom(atom_index, @sizeOf(u64), @alignOf(u64));
1752
1753 log.debug("allocated threadlocal pointer atom at 0x{x}", .{sym.n_value});
1754
1755 try Atom.addRelocation(self, atom_index, .{
1756 .type = .unsigned,
1757 .target = .{ .sym_index = tlv_desc_sym_index },
1758 .offset = 0,
1759 .addend = 0,
1760 .pcrel = false,
1761 .length = 3,
1762 });
1763 try Atom.addRebase(self, atom_index, 0);
1764 try self.writePtrWidthAtom(atom_index);
1765
1766 return atom_index;
1767}
1768
1709fn createMhExecuteHeaderSymbol(self: *MachO) !void {1769fn createMhExecuteHeaderSymbol(self: *MachO) !void {
1710 if (self.base.options.output_mode != .Exe) return;1770 if (self.base.options.output_mode != .Exe) return;
1711 if (self.getGlobal("__mh_execute_header")) |global| {1771 if (self.getGlobal("__mh_execute_header")) |global| {
...@@ -2091,6 +2151,13 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {...@@ -2091,6 +2151,13 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
20912151
2092fn addTlvEntry(self: *MachO, target: SymbolWithLoc) !void {2152fn addTlvEntry(self: *MachO, target: SymbolWithLoc) !void {
2093 if (self.tlvp_table.lookup.contains(target)) return;2153 if (self.tlvp_table.lookup.contains(target)) return;
2154 const tlvp_index = try self.tlvp_table.allocateEntry(self.base.allocator, target);
2155 const tlv_desc_atom_index = try self.createThreadLocalDescriptorAtom(target);
2156 const tlv_desc_atom = self.getAtom(tlv_desc_atom_index);
2157 const tlv_ptr_atom_index = try self.createThreadLocalPointerAtom(tlv_desc_atom.getSymbolIndex().?);
2158 const tlv_ptr_atom = self.getAtom(tlv_ptr_atom_index);
2159 self.tlvp_table.entries.items[tlvp_index].sym_index = tlv_ptr_atom.getSymbolIndex().?;
2160 self.markRelocsDirtyByTarget(target);
2094}2161}
20952162
2096pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {2163pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
...@@ -2444,16 +2511,28 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2444,16 +2511,28 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
24442511
2445 const required_alignment = decl.getAlignment(self.base.options.target);2512 const required_alignment = decl.getAlignment(self.base.options.target);
24462513
2447 const sym_name = try decl.getFullyQualifiedName(mod);2514 const decl_name = try decl.getFullyQualifiedName(mod);
2448 defer self.base.allocator.free(sym_name);2515 defer gpa.free(decl_name);
24492516
2450 const decl_metadata = self.decls.get(decl_index).?;2517 const decl_metadata = self.decls.get(decl_index).?;
2451 const atom_index = decl_metadata.atom;2518 const atom_index = decl_metadata.atom;
2452 const atom = self.getAtom(atom_index);2519 const atom = self.getAtom(atom_index);
2453 const sym_index = atom.getSymbolIndex().?;2520 const sym_index = atom.getSymbolIndex().?;
2454 const sect_id = decl_metadata.section;2521 const sect_id = decl_metadata.section;
2522 const header = &self.sections.items(.header)[sect_id];
2523 const segment = self.getSegment(sect_id);
2524 const is_threadlocal = if (!self.base.options.single_threaded)
2525 header.flags == macho.S_THREAD_LOCAL_REGULAR or header.flags == macho.S_THREAD_LOCAL_ZEROFILL
2526 else
2527 false;
2455 const code_len = code.len;2528 const code_len = code.len;
24562529
2530 const sym_name = if (is_threadlocal)
2531 try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name})
2532 else
2533 decl_name;
2534 defer if (is_threadlocal) gpa.free(sym_name);
2535
2457 if (atom.size != 0) {2536 if (atom.size != 0) {
2458 const sym = atom.getSymbolPtr(self);2537 const sym = atom.getSymbolPtr(self);
2459 sym.n_strx = try self.strtab.insert(gpa, sym_name);2538 sym.n_strx = try self.strtab.insert(gpa, sym_name);
...@@ -2471,25 +2550,29 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2471,25 +2550,29 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
24712550
2472 if (vaddr != sym.n_value) {2551 if (vaddr != sym.n_value) {
2473 sym.n_value = vaddr;2552 sym.n_value = vaddr;
2474 log.debug(" (updating GOT entry)", .{});2553 const target = SymbolWithLoc{ .sym_index = sym_index };
2475 const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };2554 self.markRelocsDirtyByTarget(target);
2476 const got_atom_index = self.got_table.getAtomIndex(self, got_target).?;2555 if (is_threadlocal) {
2477 self.markRelocsDirtyByTarget(got_target);2556 @panic("TODO update the threadlocal variable's name also");
2478 try self.writePtrWidthAtom(got_atom_index);2557 // log.debug(" (updating threadlocal pointer entry)", .{});
2558 // const tlvp_atom_index = self.tlvp_table.getAtomIndex(self, target).?;
2559 // try self.writePtrWidthAtom(tlvp_atom_index);
2560 } else {
2561 log.debug(" (updating GOT entry)", .{});
2562 const got_atom_index = self.got_table.getAtomIndex(self, target).?;
2563 try self.writePtrWidthAtom(got_atom_index);
2564 }
2479 }2565 }
2480 } else if (code_len < atom.size) {2566 } else if (code_len < atom.size) {
2481 self.shrinkAtom(atom_index, code_len);2567 self.shrinkAtom(atom_index, code_len);
2482 } else if (atom.next_index == null) {2568 } else if (atom.next_index == null) {
2483 const header = &self.sections.items(.header)[sect_id];
2484 const segment = self.getSegment(sect_id);
2485 const needed_size = (sym.n_value + code_len) - segment.vmaddr;2569 const needed_size = (sym.n_value + code_len) - segment.vmaddr;
2486 header.size = needed_size;2570 header.size = needed_size;
2487 }2571 }
2488 self.getAtomPtr(atom_index).size = code_len;2572 self.getAtomPtr(atom_index).size = code_len;
2489 } else {2573 } else {
2490 const name_str_index = try self.strtab.insert(gpa, sym_name);
2491 const sym = atom.getSymbolPtr(self);2574 const sym = atom.getSymbolPtr(self);
2492 sym.n_strx = name_str_index;2575 sym.n_strx = try self.strtab.insert(gpa, sym_name);
2493 sym.n_type = macho.N_SECT;2576 sym.n_type = macho.N_SECT;
2494 sym.n_sect = sect_id + 1;2577 sym.n_sect = sect_id + 1;
2495 sym.n_desc = 0;2578 sym.n_desc = 0;
...@@ -2503,7 +2586,12 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2503,7 +2586,12 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
2503 self.getAtomPtr(atom_index).size = code_len;2586 self.getAtomPtr(atom_index).size = code_len;
2504 sym.n_value = vaddr;2587 sym.n_value = vaddr;
25052588
2506 try self.addGotEntry(.{ .sym_index = sym_index });2589 const target: SymbolWithLoc = .{ .sym_index = sym_index };
2590 if (is_threadlocal) {
2591 try self.addTlvEntry(target);
2592 } else {
2593 try self.addGotEntry(target);
2594 }
2507 }2595 }
25082596
2509 try self.writeAtom(atom_index, code);2597 try self.writeAtom(atom_index, code);
...@@ -2851,7 +2939,7 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -2851,7 +2939,7 @@ fn populateMissingMetadata(self: *MachO) !void {
2851 if (self.thread_vars_section_index == null) {2939 if (self.thread_vars_section_index == null) {
2852 self.thread_vars_section_index = try self.allocateSection("__DATA3", "__thread_vars", .{2940 self.thread_vars_section_index = try self.allocateSection("__DATA3", "__thread_vars", .{
2853 .size = @sizeOf(u64) * 3,2941 .size = @sizeOf(u64) * 3,
2854 .alignment = @alignOf(u64),2942 .alignment = @sizeOf(u64),
2855 .flags = macho.S_THREAD_LOCAL_VARIABLES,2943 .flags = macho.S_THREAD_LOCAL_VARIABLES,
2856 .prot = macho.PROT.READ | macho.PROT.WRITE,2944 .prot = macho.PROT.READ | macho.PROT.WRITE,
2857 });2945 });
...@@ -3650,6 +3738,10 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {...@@ -3650,6 +3738,10 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
3650 var header: macho.mach_header_64 = .{};3738 var header: macho.mach_header_64 = .{};
3651 header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;3739 header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;
36523740
3741 if (!self.base.options.single_threaded) {
3742 header.flags |= macho.MH_HAS_TLV_DESCRIPTORS;
3743 }
3744
3653 switch (self.base.options.target.cpu.arch) {3745 switch (self.base.options.target.cpu.arch) {
3654 .aarch64 => {3746 .aarch64 => {
3655 header.cputype = macho.CPU_TYPE_ARM64;3747 header.cputype = macho.CPU_TYPE_ARM64;
...@@ -3674,12 +3766,6 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {...@@ -3674,12 +3766,6 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
3674 else => unreachable,3766 else => unreachable,
3675 }3767 }
36763768
3677 if (self.getSectionByName("__DATA", "__thread_vars")) |sect_id| {
3678 if (self.sections.items(.header)[sect_id].size > 0) {
3679 header.flags |= macho.MH_HAS_TLV_DESCRIPTORS;
3680 }
3681 }
3682
3683 header.ncmds = ncmds;3769 header.ncmds = ncmds;
3684 header.sizeofcmds = sizeofcmds;3770 header.sizeofcmds = sizeofcmds;
36853771
...@@ -3859,8 +3945,7 @@ pub fn getSymbol(self: *const MachO, sym_with_loc: SymbolWithLoc) macho.nlist_64...@@ -3859,8 +3945,7 @@ pub fn getSymbol(self: *const MachO, sym_with_loc: SymbolWithLoc) macho.nlist_64
38593945
3860/// Returns name of the symbol described by `sym_with_loc` descriptor.3946/// Returns name of the symbol described by `sym_with_loc` descriptor.
3861pub fn getSymbolName(self: *const MachO, sym_with_loc: SymbolWithLoc) []const u8 {3947pub fn getSymbolName(self: *const MachO, sym_with_loc: SymbolWithLoc) []const u8 {
3862 assert(sym_with_loc.file == null);3948 const sym = self.getSymbol(sym_with_loc);
3863 const sym = self.locals.items[sym_with_loc.sym_index];
3864 return self.strtab.get(sym.n_strx).?;3949 return self.strtab.get(sym.n_strx).?;
3865}3950}
38663951
...@@ -4274,6 +4359,9 @@ pub fn logSymtab(self: *MachO) void {...@@ -4274,6 +4359,9 @@ pub fn logSymtab(self: *MachO) void {
42744359
4275 log.debug("stubs entries:", .{});4360 log.debug("stubs entries:", .{});
4276 log.debug("{}", .{self.stubs_table.fmtDebug(self)});4361 log.debug("{}", .{self.stubs_table.fmtDebug(self)});
4362
4363 log.debug("threadlocal entries:", .{});
4364 log.debug("{}", .{self.tlvp_table.fmtDebug(self)});
4277}4365}
42784366
4279pub fn logAtoms(self: *MachO) void {4367pub fn logAtoms(self: *MachO) void {
src/link/MachO/Relocation.zig+14-3
...@@ -37,6 +37,8 @@ pub const Type = enum {...@@ -37,6 +37,8 @@ pub const Type = enum {
37 branch,37 branch,
38 /// Absolute pointer value38 /// Absolute pointer value
39 unsigned,39 unsigned,
40 /// Relative offset to TLV initializer
41 tlv_initializer,
40};42};
4143
42/// Returns true if and only if the reloc is dirty AND the target address is available.44/// Returns true if and only if the reloc is dirty AND the target address is available.
...@@ -65,7 +67,16 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, cod...@@ -65,7 +67,16 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, cod
6567
66 const target_atom_index = self.getTargetAtomIndex(macho_file).?; // Oops, you didn't check if the relocation can be resolved with isResolvable().68 const target_atom_index = self.getTargetAtomIndex(macho_file).?; // Oops, you didn't check if the relocation can be resolved with isResolvable().
67 const target_atom = macho_file.getAtom(target_atom_index);69 const target_atom = macho_file.getAtom(target_atom_index);
68 const target_addr = @intCast(i64, target_atom.getSymbol(macho_file).n_value) + self.addend;70
71 const target_addr: i64 = switch (self.type) {
72 .tlv_initializer => blk: {
73 assert(self.addend == 0); // Addend here makes no sense.
74 const header = macho_file.sections.items(.header)[macho_file.thread_data_section_index.?];
75 const target_sym = target_atom.getSymbol(macho_file);
76 break :blk @intCast(i64, target_sym.n_value - header.addr);
77 },
78 else => @intCast(i64, target_atom.getSymbol(macho_file).n_value) + self.addend,
79 };
6980
70 log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{81 log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{
71 source_addr,82 source_addr,
...@@ -190,7 +201,7 @@ fn resolveAarch64(self: Relocation, source_addr: u64, target_addr: i64, code: []...@@ -190,7 +201,7 @@ fn resolveAarch64(self: Relocation, source_addr: u64, target_addr: i64, code: []
190 };201 };
191 mem.writeIntLittle(u32, buffer[0..4], inst.toU32());202 mem.writeIntLittle(u32, buffer[0..4], inst.toU32());
192 },203 },
193 .unsigned => switch (self.length) {204 .tlv_initializer, .unsigned => switch (self.length) {
194 2 => mem.writeIntLittle(u32, buffer[0..4], @truncate(u32, @bitCast(u64, target_addr))),205 2 => mem.writeIntLittle(u32, buffer[0..4], @truncate(u32, @bitCast(u64, target_addr))),
195 3 => mem.writeIntLittle(u64, buffer[0..8], @bitCast(u64, target_addr)),206 3 => mem.writeIntLittle(u64, buffer[0..8], @bitCast(u64, target_addr)),
196 else => unreachable,207 else => unreachable,
...@@ -205,7 +216,7 @@ fn resolveX8664(self: Relocation, source_addr: u64, target_addr: i64, code: []u8...@@ -205,7 +216,7 @@ fn resolveX8664(self: Relocation, source_addr: u64, target_addr: i64, code: []u8
205 const displacement = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4);216 const displacement = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4);
206 mem.writeIntLittle(u32, code[self.offset..][0..4], @bitCast(u32, displacement));217 mem.writeIntLittle(u32, code[self.offset..][0..4], @bitCast(u32, displacement));
207 },218 },
208 .unsigned => {219 .tlv_initializer, .unsigned => {
209 switch (self.length) {220 switch (self.length) {
210 2 => {221 2 => {
211 mem.writeIntLittle(u32, code[self.offset..][0..4], @truncate(u32, @bitCast(u64, target_addr)));222 mem.writeIntLittle(u32, code[self.offset..][0..4], @truncate(u32, @bitCast(u64, target_addr)));