aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-01-19 21:15:07 +0100
committerJakub Konka <kubkon@jakubkonka.com>2024-01-24 12:34:41 +0100
commit8f74d2519f2d262ee4ff9ab14316e76433c05901 (patch)
tree28e500e490e9b466e869c08112c1f4f7d7d72a9f /src
parenta112241f6454b3dd5b93703337339d38c2707be7 (diff)
downloadzig-8f74d2519f2d262ee4ff9ab14316e76433c05901.tar.gz
zig-8f74d2519f2d262ee4ff9ab14316e76433c05901.zip
macho: resolve relocs pointing at __got_zig
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO/Atom.zig14
-rw-r--r--src/link/MachO/Relocation.zig7
-rw-r--r--src/link/MachO/Symbol.zig2
3 files changed, 20 insertions, 3 deletions
diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig
index 90a3e129c9..c8564c95d8 100644
--- a/src/link/MachO/Atom.zig
+++ b/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 => {
diff --git a/src/link/MachO/Relocation.zig b/src/link/MachO/Relocation.zig
index 20891f07e3..eff628071f 100644
--- a/src/link/MachO/Relocation.zig
+++ b/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,
diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig
index 5ffbabe1e2..dfdb81c605 100644
--- a/src/link/MachO/Symbol.zig
+++ b/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);