macho: allow for add and ldr when resolving GOT_LOAD_* relocs

This commit is contained in:
Jakub Konka 2022-09-15 22:02:40 +02:00
parent 618c7a3546
commit dc6480dba5
3 changed files with 11 additions and 28 deletions

View File

@ -845,7 +845,8 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
try emit.writeInstruction(Instruction.adrp(reg.to64(), 0));
switch (tag) {
.load_memory_got => {
.load_memory_got,
=> {
// ldr reg, reg, offset
try emit.writeInstruction(Instruction.ldr(
reg,
@ -871,8 +872,8 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
Instruction.LoadStoreOffset.imm(0),
));
},
.load_memory_ptr_got,
.load_memory_ptr_direct,
.load_memory_ptr_got,
=> {
// add reg, reg, offset
try emit.writeInstruction(Instruction.add(reg, reg, 0, false));

View File

@ -3434,6 +3434,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
}
if (self.text_section_index == null) {
// Sadly, segments need unique string identfiers for some reason.
self.text_section_index = try self.allocateSection("__TEXT1", "__text", .{
.size = self.base.options.program_code_size_hint,
.alignment = switch (cpu_arch) {

View File

@ -135,7 +135,9 @@ fn resolveAarch64(
inst.pc_relative_address.immlo = @truncate(u2, pages);
mem.writeIntLittle(u32, &buffer, inst.toU32());
},
.ARM64_RELOC_PAGEOFF12 => {
.ARM64_RELOC_PAGEOFF12,
.ARM64_RELOC_GOT_LOAD_PAGEOFF12,
=> {
const narrowed = @truncate(u12, @intCast(u64, target_addr));
if (isArithmeticOp(&buffer)) {
var inst = aarch64.Instruction{
@ -170,18 +172,6 @@ fn resolveAarch64(
mem.writeIntLittle(u32, &buffer, inst.toU32());
}
},
.ARM64_RELOC_GOT_LOAD_PAGEOFF12 => {
const narrowed = @truncate(u12, @intCast(u64, target_addr));
var inst: aarch64.Instruction = .{
.load_store_register = mem.bytesToValue(meta.TagPayload(
aarch64.Instruction,
aarch64.Instruction.load_store_register,
), &buffer),
};
const offset = @divExact(narrowed, 8);
inst.load_store_register.offset = offset;
mem.writeIntLittle(u32, &buffer, inst.toU32());
},
.ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
const RegInfo = struct {
rd: u5,
@ -226,11 +216,8 @@ fn resolveAarch64(
mem.writeIntLittle(u32, &buffer, inst.toU32());
},
.ARM64_RELOC_POINTER_TO_GOT => {
const result = math.cast(
i32,
@intCast(i64, target_addr) - @intCast(i64, source_addr),
) orelse return error.Overflow;
mem.writeIntLittle(u32, &buffer, @bitCast(u32, result));
const result = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));
mem.writeIntLittle(i32, &buffer, result);
},
.ARM64_RELOC_SUBTRACTOR => unreachable,
.ARM64_RELOC_ADDEND => unreachable,
@ -255,10 +242,7 @@ fn resolveX8664(
.X86_64_RELOC_GOT_LOAD,
.X86_64_RELOC_TLV,
=> {
const displacement = math.cast(
i32,
@intCast(i64, target_addr) - @intCast(i64, source_addr) - 4,
) orelse return error.Overflow;
const displacement = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4);
mem.writeIntLittle(u32, buffer[0..4], @bitCast(u32, displacement));
break :blk buffer[0..4];
},
@ -274,10 +258,7 @@ fn resolveX8664(
.X86_64_RELOC_SIGNED_4 => 4,
else => unreachable,
};
const displacement = math.cast(
i32,
target_addr - @intCast(i64, source_addr + correction + 4),
) orelse return error.Overflow;
const displacement = @intCast(i32, target_addr - @intCast(i64, source_addr + correction + 4));
mem.writeIntLittle(u32, buffer[0..4], @bitCast(u32, displacement));
break :blk buffer[0..4];
},