authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-19 21:15:07+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
log8f74d2519f2d262ee4ff9ab14316e76433c05901
tree28e500e490e9b466e869c08112c1f4f7d7d72a9f
parenta112241f6454b3dd5b93703337339d38c2707be7

macho: resolve relocs pointing at __got_zig


3 files changed, 20 insertions(+), 3 deletions(-)

src/link/MachO/Atom.zig+12-2
...@@ -588,6 +588,8 @@ fn resolveRelocInner(...@@ -588,6 +588,8 @@ fn resolveRelocInner(
588 const G: i64 = @intCast(rel.getGotTargetAddress(macho_file));588 const G: i64 = @intCast(rel.getGotTargetAddress(macho_file));
589 const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));589 const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));
590 const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(macho_file))) else 0;590 const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(macho_file))) else 0;
591 // Address of the __got_zig table entry if any.
592 const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file)));
591593
592 switch (rel.tag) {594 switch (rel.tag) {
593 .local => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] atom({d})", .{595 .local => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] atom({d})", .{
...@@ -597,12 +599,13 @@ fn resolveRelocInner(...@@ -597,12 +599,13 @@ fn resolveRelocInner(
597 S + A - SUB,599 S + A - SUB,
598 rel.getTargetAtom(macho_file).atom_index,600 rel.getTargetAtom(macho_file).atom_index,
599 }),601 }),
600 .@"extern" => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] G({x}) ({s})", .{602 .@"extern" => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] G({x}) ZG({x}) ({s})", .{
601 P,603 P,
602 rel_offset,604 rel_offset,
603 @tagName(rel.type),605 @tagName(rel.type),
604 S + A - SUB,606 S + A - SUB,
605 G + A,607 G + A,
608 ZIG_GOT + A,
606 rel.getTargetSymbol(macho_file).getName(macho_file),609 rel.getTargetSymbol(macho_file).getName(macho_file),
607 }),610 }),
608 }611 }
...@@ -696,7 +699,14 @@ fn resolveRelocInner(...@@ -696,7 +699,14 @@ fn resolveRelocInner(
696 },699 },
697700
698 .zig_got_load => {701 .zig_got_load => {
699 @panic("TODO resolve __got_zig indirection reloc");702 assert(rel.tag == .@"extern");
703 assert(rel.meta.length == 2);
704 assert(rel.meta.pcrel);
705 switch (cpu_arch) {
706 .x86_64 => try writer.writeInt(i32, @intCast(ZIG_GOT + A - P), .little),
707 .aarch64 => @panic("TODO resolve __got_zig indirection reloc"),
708 else => unreachable,
709 }
700 },710 },
701711
702 .tlv => {712 .tlv => {
src/link/MachO/Relocation.zig+7
...@@ -34,6 +34,13 @@ pub fn getGotTargetAddress(rel: Relocation, macho_file: *MachO) u64 {...@@ -34,6 +34,13 @@ pub fn getGotTargetAddress(rel: Relocation, macho_file: *MachO) u64 {
34 };34 };
35}35}
3636
37pub fn getZigGotTargetAddress(rel: Relocation, macho_file: *MachO) u64 {
38 return switch (rel.tag) {
39 .local => 0,
40 .@"extern" => rel.getTargetSymbol(macho_file).getZigGotAddress(macho_file),
41 };
42}
43
37pub fn getRelocAddend(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) i64 {44pub fn getRelocAddend(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) i64 {
38 const addend: i64 = switch (rel.type) {45 const addend: i64 = switch (rel.type) {
39 .signed => 0,46 .signed => 0,
src/link/MachO/Symbol.zig+1-1
...@@ -162,7 +162,7 @@ pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, macho_file:...@@ -162,7 +162,7 @@ pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, macho_file:
162 return .{ .found_existing = false, .index = index };162 return .{ .found_existing = false, .index = index };
163}163}
164164
165pub fn zigGotAddress(symbol: Symbol, macho_file: *MachO) u64 {165pub fn getZigGotAddress(symbol: Symbol, macho_file: *MachO) u64 {
166 if (!symbol.flags.has_zig_got) return 0;166 if (!symbol.flags.has_zig_got) return 0;
167 const extras = symbol.getExtra(macho_file).?;167 const extras = symbol.getExtra(macho_file).?;
168 return macho_file.zig_got.entryAddress(extras.zig_got, macho_file);168 return macho_file.zig_got.entryAddress(extras.zig_got, macho_file);