| ... | @@ -3860,32 +3860,35 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -3860,32 +3860,35 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 3860 | .memory => |x| { | 3860 | .memory => |x| { |
| 3861 | if (self.bin_file.options.pie) { | 3861 | if (self.bin_file.options.pie) { |
| 3862 | // RIP-relative displacement to the entry in the GOT table. | 3862 | // RIP-relative displacement to the entry in the GOT table. |
| | 3863 | const abi_size = ty.abiSize(self.target.*); |
| | 3864 | const encoder = try X8664Encoder.init(self.code, 7); |
| | 3865 | |
| | 3866 | // LEA reg, [<offset>] |
| | 3867 | |
| | 3868 | // We encode the instruction FIRST because prefixes may or may not appear. |
| | 3869 | // After we encode the instruction, we will know that the displacement bytes |
| | 3870 | // for [<offset>] will be at self.code.items.len - 4. |
| | 3871 | encoder.rex(.{ |
| | 3872 | .w = abi_size == 64, |
| | 3873 | .r = reg.isExtended(), |
| | 3874 | }); |
| | 3875 | encoder.opcode_1byte(0x8D); |
| | 3876 | encoder.modRm_RIPDisp32(reg.low_id()); |
| | 3877 | encoder.disp32(0); |
| | 3878 | |
| 3863 | // TODO we should come up with our own, backend independent relocation types | 3879 | // TODO we should come up with our own, backend independent relocation types |
| 3864 | // which each backend (Elf, MachO, etc.) would then translate into an actual | 3880 | // which each backend (Elf, MachO, etc.) would then translate into an actual |
| 3865 | // fixup when linking. | 3881 | // fixup when linking. |
| 3866 | if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 3882 | if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 3867 | try macho_file.pie_fixups.append(self.bin_file.allocator, .{ | 3883 | try macho_file.pie_fixups.append(self.bin_file.allocator, .{ |
| 3868 | .target_addr = x, | 3884 | .target_addr = x, |
| 3869 | .offset = self.code.items.len + 3, | 3885 | .offset = self.code.items.len - 4, |
| 3870 | .size = 4, | 3886 | .size = 4, |
| 3871 | }); | 3887 | }); |
| 3872 | } else { | 3888 | } else { |
| 3873 | return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{}); | 3889 | return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{}); |
| 3874 | } | 3890 | } |
| 3875 | | 3891 | |
| 3876 | const abi_size = ty.abiSize(self.target.*); | | |
| 3877 | const encoder = try X8664Encoder.init(self.code, 7); | | |
| 3878 | // LEA reg, [<offset>] | | |
| 3879 | // TODO: Check if this breaks on macho if abi_size != 64 and reg is not extended | | |
| 3880 | // this causes rex byte to be omitted, which might mean the offset (+3) above is wrong. | | |
| 3881 | encoder.rex(.{ | | |
| 3882 | .w = abi_size == 64, | | |
| 3883 | .r = reg.isExtended(), | | |
| 3884 | }); | | |
| 3885 | encoder.opcode_1byte(0x8D); | | |
| 3886 | encoder.modRm_RIPDisp32(reg.low_id()); | | |
| 3887 | encoder.disp32(0); | | |
| 3888 | | | |
| 3889 | // MOV reg, [reg] | 3892 | // MOV reg, [reg] |
| 3890 | encoder.rex(.{ | 3893 | encoder.rex(.{ |
| 3891 | .w = abi_size == 64, | 3894 | .w = abi_size == 64, |