Commit 8f74d2519f

Jakub Konka <kubkon@jakubkonka.com>
2024-01-19 21:15:07
macho: resolve relocs pointing at __got_zig
1 parent a112241
Changed files (3)
src/link/MachO/Atom.zig
@@ -588,6 +588,8 @@ fn resolveRelocInner(
     const G: i64 = @intCast(rel.getGotTargetAddress(macho_file));
     const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));
     const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(macho_file))) else 0;
+    // Address of the __got_zig table entry if any.
+    const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file)));
 
     switch (rel.tag) {
         .local => relocs_log.debug("  {x}<+{d}>: {s}: [=> {x}] atom({d})", .{
@@ -597,12 +599,13 @@ fn resolveRelocInner(
             S + A - SUB,
             rel.getTargetAtom(macho_file).atom_index,
         }),
-        .@"extern" => relocs_log.debug("  {x}<+{d}>: {s}: [=> {x}] G({x}) ({s})", .{
+        .@"extern" => relocs_log.debug("  {x}<+{d}>: {s}: [=> {x}] G({x}) ZG({x}) ({s})", .{
             P,
             rel_offset,
             @tagName(rel.type),
             S + A - SUB,
             G + A,
+            ZIG_GOT + A,
             rel.getTargetSymbol(macho_file).getName(macho_file),
         }),
     }
@@ -696,7 +699,14 @@ fn resolveRelocInner(
         },
 
         .zig_got_load => {
-            @panic("TODO resolve __got_zig indirection reloc");
+            assert(rel.tag == .@"extern");
+            assert(rel.meta.length == 2);
+            assert(rel.meta.pcrel);
+            switch (cpu_arch) {
+                .x86_64 => try writer.writeInt(i32, @intCast(ZIG_GOT + A - P), .little),
+                .aarch64 => @panic("TODO resolve __got_zig indirection reloc"),
+                else => unreachable,
+            }
         },
 
         .tlv => {
src/link/MachO/Relocation.zig
@@ -34,6 +34,13 @@ pub fn getGotTargetAddress(rel: Relocation, macho_file: *MachO) u64 {
     };
 }
 
+pub fn getZigGotTargetAddress(rel: Relocation, macho_file: *MachO) u64 {
+    return switch (rel.tag) {
+        .local => 0,
+        .@"extern" => rel.getTargetSymbol(macho_file).getZigGotAddress(macho_file),
+    };
+}
+
 pub fn getRelocAddend(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) i64 {
     const addend: i64 = switch (rel.type) {
         .signed => 0,
src/link/MachO/Symbol.zig
@@ -162,7 +162,7 @@ pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, macho_file:
     return .{ .found_existing = false, .index = index };
 }
 
-pub fn zigGotAddress(symbol: Symbol, macho_file: *MachO) u64 {
+pub fn getZigGotAddress(symbol: Symbol, macho_file: *MachO) u64 {
     if (!symbol.flags.has_zig_got) return 0;
     const extras = symbol.getExtra(macho_file).?;
     return macho_file.zig_got.entryAddress(extras.zig_got, macho_file);