From dc6480dba5ec4533f6a20292f93fe5c25a1a689f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 15 Sep 2022 22:02:40 +0200 Subject: [PATCH] macho: allow for add and ldr when resolving GOT_LOAD_* relocs --- src/arch/aarch64/Emit.zig | 5 +++-- src/link/MachO.zig | 1 + src/link/MachO/Relocation.zig | 33 +++++++-------------------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index a868b74edc..5e1e1c7135 100644 --- a/src/arch/aarch64/Emit.zig +++ b/src/arch/aarch64/Emit.zig @@ -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)); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2b7a3d43ae..2e21aa1af9 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -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) { diff --git a/src/link/MachO/Relocation.zig b/src/link/MachO/Relocation.zig index 2b68051c5b..1acbb30a24 100644 --- a/src/link/MachO/Relocation.zig +++ b/src/link/MachO/Relocation.zig @@ -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]; },