macho: migrate thunks to use new relative addressing mechanism

This commit is contained in:
Jakub Konka 2024-02-03 10:52:29 +01:00
parent aa1aa98863
commit 0a0f90f949
4 changed files with 11 additions and 16 deletions

View File

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

View File

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

View File

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

View File

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