From b004c3da159645cf4a3387f808ab3e8a6277ba2f Mon Sep 17 00:00:00 2001 From: gracefu <81774659+gracefuu@users.noreply.github.com> Date: Sun, 11 Apr 2021 16:41:49 +0800 Subject: [PATCH] stage2 x86_64: try to fix RIP-relative offset to GOT for macho --- src/codegen.zig | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/codegen.zig b/src/codegen.zig index 27a60597d4..e24d197d54 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -3860,24 +3860,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .memory => |x| { if (self.bin_file.options.pie) { // RIP-relative displacement to the entry in the GOT table. - // TODO we should come up with our own, backend independent relocation types - // which each backend (Elf, MachO, etc.) would then translate into an actual - // fixup when linking. - if (self.bin_file.cast(link.File.MachO)) |macho_file| { - try macho_file.pie_fixups.append(self.bin_file.allocator, .{ - .target_addr = x, - .offset = self.code.items.len + 3, - .size = 4, - }); - } else { - return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{}); - } - const abi_size = ty.abiSize(self.target.*); const encoder = try X8664Encoder.init(self.code, 7); + // LEA reg, [] - // TODO: Check if this breaks on macho if abi_size != 64 and reg is not extended - // this causes rex byte to be omitted, which might mean the offset (+3) above is wrong. + + // We encode the instruction FIRST because prefixes may or may not appear. + // After we encode the instruction, we will know that the displacement bytes + // for [] will be at self.code.items.len - 4. encoder.rex(.{ .w = abi_size == 64, .r = reg.isExtended(), @@ -3886,6 +3876,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { encoder.modRm_RIPDisp32(reg.low_id()); encoder.disp32(0); + // TODO we should come up with our own, backend independent relocation types + // which each backend (Elf, MachO, etc.) would then translate into an actual + // fixup when linking. + if (self.bin_file.cast(link.File.MachO)) |macho_file| { + try macho_file.pie_fixups.append(self.bin_file.allocator, .{ + .target_addr = x, + .offset = self.code.items.len - 4, + .size = 4, + }); + } else { + return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{}); + } + // MOV reg, [reg] encoder.rex(.{ .w = abi_size == 64,