authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-03 10:52:29+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-03 10:52:29+01:00
log0a0f90f949942b19950455647bc955b369407dd4
tree44debca2e688edfcee5db118bbc4c5967dd304f3
parentaa1aa9886333e8b260901572142a227e5544f4df

macho: migrate thunks to use new relative addressing mechanism


4 files changed, 11 insertions(+), 16 deletions(-)

src/link/MachO.zig+1-10
...@@ -596,7 +596,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -596,7 +596,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
596596
597 try self.allocateSections();597 try self.allocateSections();
598 self.allocateSegments();598 self.allocateSegments();
599 self.allocateAtoms();
600 self.allocateSyntheticSymbols();599 self.allocateSyntheticSymbols();
601 try self.allocateLinkeditSegment();600 try self.allocateLinkeditSegment();
602601
...@@ -2392,14 +2391,6 @@ fn allocateSegments(self: *MachO) void {...@@ -2392,14 +2391,6 @@ fn allocateSegments(self: *MachO) void {
2392 }2391 }
2393}2392}
23942393
2395pub fn allocateAtoms(self: *MachO) void {
2396 // TODO: redo this like atoms
2397 for (self.thunks.items) |*thunk| {
2398 const header = self.sections.items(.header)[thunk.out_n_sect];
2399 thunk.value += header.addr;
2400 }
2401}
2402
2403fn allocateSyntheticSymbols(self: *MachO) void {2394fn allocateSyntheticSymbols(self: *MachO) void {
2404 const text_seg = self.getTextSegment();2395 const text_seg = self.getTextSegment();
24052396
...@@ -2608,7 +2599,7 @@ fn writeAtoms(self: *MachO) !void {...@@ -2608,7 +2599,7 @@ fn writeAtoms(self: *MachO) !void {
26082599
2609 for (self.thunks.items) |thunk| {2600 for (self.thunks.items) |thunk| {
2610 const header = slice.items(.header)[thunk.out_n_sect];2601 const header = slice.items(.header)[thunk.out_n_sect];
2611 const offset = thunk.value - header.addr + header.offset;2602 const offset = thunk.value + header.offset;
2612 const buffer = try gpa.alloc(u8, thunk.size());2603 const buffer = try gpa.alloc(u8, thunk.size());
2613 defer gpa.free(buffer);2604 defer gpa.free(buffer);
2614 var stream = std.io.fixedBufferStream(buffer);2605 var stream = std.io.fixedBufferStream(buffer);
src/link/MachO/Atom.zig+1-1
...@@ -706,7 +706,7 @@ fn resolveRelocInner(...@@ -706,7 +706,7 @@ fn resolveRelocInner(
706 .aarch64 => {706 .aarch64 => {
707 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {707 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {
708 const thunk = self.getThunk(macho_file);708 const thunk = self.getThunk(macho_file);
709 const S_: i64 = @intCast(thunk.getAddress(rel.target));709 const S_: i64 = @intCast(thunk.getTargetAddress(rel.target, macho_file));
710 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;710 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
711 };711 };
712 var inst = aarch64.Instruction{712 var inst = aarch64.Instruction{
src/link/MachO/relocatable.zig-1
...@@ -61,7 +61,6 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u...@@ -61,7 +61,6 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u
61 try createSegment(macho_file);61 try createSegment(macho_file);
62 try allocateSections(macho_file);62 try allocateSections(macho_file);
63 allocateSegment(macho_file);63 allocateSegment(macho_file);
64 macho_file.allocateAtoms();
6564
66 var off = off: {65 var off = off: {
67 const seg = macho_file.segments.items[0];66 const seg = macho_file.segments.items[0];
src/link/MachO/thunks.zig+9-4
...@@ -66,7 +66,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool {...@@ -66,7 +66,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool {
66 if (atom.out_n_sect != target.out_n_sect) return false;66 if (atom.out_n_sect != target.out_n_sect) return false;
67 const target_atom = target.getAtom(macho_file).?;67 const target_atom = target.getAtom(macho_file).?;
68 if (target_atom.value == @as(u64, @bitCast(@as(i64, -1)))) return false;68 if (target_atom.value == @as(u64, @bitCast(@as(i64, -1)))) return false;
69 const saddr = @as(i64, @intCast(atom.value)) + @as(i64, @intCast(rel.offset - atom.off));69 const saddr = @as(i64, @intCast(atom.getAddress(macho_file))) + @as(i64, @intCast(rel.offset - atom.off));
70 const taddr: i64 = @intCast(rel.getTargetAddress(macho_file));70 const taddr: i64 = @intCast(rel.getTargetAddress(macho_file));
71 _ = math.cast(i28, taddr + rel.addend - saddr) orelse return false;71 _ = math.cast(i28, taddr + rel.addend - saddr) orelse return false;
72 return true;72 return true;
...@@ -85,14 +85,19 @@ pub const Thunk = struct {...@@ -85,14 +85,19 @@ pub const Thunk = struct {
85 return thunk.symbols.keys().len * trampoline_size;85 return thunk.symbols.keys().len * trampoline_size;
86 }86 }
8787
88 pub fn getAddress(thunk: Thunk, sym_index: Symbol.Index) u64 {88 pub fn getAddress(thunk: Thunk, macho_file: *MachO) u64 {
89 return thunk.value + thunk.symbols.getIndex(sym_index).? * trampoline_size;89 const header = macho_file.sections.items(.header)[thunk.out_n_sect];
90 return header.addr + thunk.value;
91 }
92
93 pub fn getTargetAddress(thunk: Thunk, sym_index: Symbol.Index, macho_file: *MachO) u64 {
94 return thunk.getAddress(macho_file) + thunk.symbols.getIndex(sym_index).? * trampoline_size;
90 }95 }
9196
92 pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {97 pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {
93 for (thunk.symbols.keys(), 0..) |sym_index, i| {98 for (thunk.symbols.keys(), 0..) |sym_index, i| {
94 const sym = macho_file.getSymbol(sym_index);99 const sym = macho_file.getSymbol(sym_index);
95 const saddr = thunk.value + i * trampoline_size;100 const saddr = thunk.getAddress(macho_file) + i * trampoline_size;
96 const taddr = sym.getAddress(.{}, macho_file);101 const taddr = sym.getAddress(.{}, macho_file);
97 const pages = try Relocation.calcNumberOfPages(saddr, taddr);102 const pages = try Relocation.calcNumberOfPages(saddr, taddr);
98 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);103 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);