Commit 8f74d2519f
Changed files (3)
src
link
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);