macho: resolve relocs pointing at __got_zig

This commit is contained in:
Jakub Konka 2024-01-19 21:15:07 +01:00
parent a112241f64
commit 8f74d2519f
3 changed files with 20 additions and 3 deletions

View File

@ -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 => {

View File

@ -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,

View File

@ -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);