From 0a0f90f949942b19950455647bc955b369407dd4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 3 Feb 2024 10:52:29 +0100 Subject: [PATCH] macho: migrate thunks to use new relative addressing mechanism --- src/link/MachO.zig | 11 +---------- src/link/MachO/Atom.zig | 2 +- src/link/MachO/relocatable.zig | 1 - src/link/MachO/thunks.zig | 13 +++++++++---- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index d5706eb4d..b0b576acf 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -596,7 +596,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node try self.allocateSections(); self.allocateSegments(); - self.allocateAtoms(); self.allocateSyntheticSymbols(); try self.allocateLinkeditSegment(); @@ -2392,14 +2391,6 @@ fn allocateSegments(self: *MachO) void { } } -pub fn allocateAtoms(self: *MachO) void { - // TODO: redo this like atoms - for (self.thunks.items) |*thunk| { - const header = self.sections.items(.header)[thunk.out_n_sect]; - thunk.value += header.addr; - } -} - fn allocateSyntheticSymbols(self: *MachO) void { const text_seg = self.getTextSegment(); @@ -2608,7 +2599,7 @@ fn writeAtoms(self: *MachO) !void { for (self.thunks.items) |thunk| { const header = slice.items(.header)[thunk.out_n_sect]; - const offset = thunk.value - header.addr + header.offset; + const offset = thunk.value + header.offset; const buffer = try gpa.alloc(u8, thunk.size()); defer gpa.free(buffer); var stream = std.io.fixedBufferStream(buffer); diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 7e18c002a..a38c60140 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -706,7 +706,7 @@ fn resolveRelocInner( .aarch64 => { const disp: i28 = math.cast(i28, S + A - P) orelse blk: { const thunk = self.getThunk(macho_file); - const S_: i64 = @intCast(thunk.getAddress(rel.target)); + const S_: i64 = @intCast(thunk.getTargetAddress(rel.target, macho_file)); break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow; }; var inst = aarch64.Instruction{ diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index 0a7000f9b..72db2b347 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -61,7 +61,6 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u try createSegment(macho_file); try allocateSections(macho_file); allocateSegment(macho_file); - macho_file.allocateAtoms(); var off = off: { const seg = macho_file.segments.items[0]; diff --git a/src/link/MachO/thunks.zig b/src/link/MachO/thunks.zig index 2e9602f8d..cd9ea20c8 100644 --- a/src/link/MachO/thunks.zig +++ b/src/link/MachO/thunks.zig @@ -66,7 +66,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool { if (atom.out_n_sect != target.out_n_sect) return false; const target_atom = target.getAtom(macho_file).?; if (target_atom.value == @as(u64, @bitCast(@as(i64, -1)))) return false; - const saddr = @as(i64, @intCast(atom.value)) + @as(i64, @intCast(rel.offset - atom.off)); + const saddr = @as(i64, @intCast(atom.getAddress(macho_file))) + @as(i64, @intCast(rel.offset - atom.off)); const taddr: i64 = @intCast(rel.getTargetAddress(macho_file)); _ = math.cast(i28, taddr + rel.addend - saddr) orelse return false; return true; @@ -85,14 +85,19 @@ pub const Thunk = struct { return thunk.symbols.keys().len * trampoline_size; } - pub fn getAddress(thunk: Thunk, sym_index: Symbol.Index) u64 { - return thunk.value + thunk.symbols.getIndex(sym_index).? * trampoline_size; + pub fn getAddress(thunk: Thunk, macho_file: *MachO) u64 { + const header = macho_file.sections.items(.header)[thunk.out_n_sect]; + return header.addr + thunk.value; + } + + pub fn getTargetAddress(thunk: Thunk, sym_index: Symbol.Index, macho_file: *MachO) u64 { + return thunk.getAddress(macho_file) + thunk.symbols.getIndex(sym_index).? * trampoline_size; } pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void { for (thunk.symbols.keys(), 0..) |sym_index, i| { const sym = macho_file.getSymbol(sym_index); - const saddr = thunk.value + i * trampoline_size; + const saddr = thunk.getAddress(macho_file) + i * trampoline_size; const taddr = sym.getAddress(.{}, macho_file); const pages = try Relocation.calcNumberOfPages(saddr, taddr); try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);