authorgravatar for 81774659+gracefuu@users.noreply.github.comgracefu <81774659+gracefuu@users.noreply.github.com> 2021-04-11 16:41:49+08:00
committergravatar for 81774659+gracefuu@users.noreply.github.comgracefu <81774659+gracefuu@users.noreply.github.com> 2021-04-16 15:21:17+08:00
logb004c3da159645cf4a3387f808ab3e8a6277ba2f
treeb8657e250daa840659c573a61948cdd8a230cdcf
parent0409f9e0244aebab5c47f0ec24114e101c3f54e6
signaturelock-open Commit is signed but in an unrecognized format.

stage2 x86_64: try to fix RIP-relative offset to GOT for macho


1 files changed, 17 insertions(+), 14 deletions(-)

src/codegen.zig+17-14
......@@ -3860,32 +3860,35 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
38603860 .memory => |x| {
38613861 if (self.bin_file.options.pie) {
38623862 // 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
38633879 // TODO we should come up with our own, backend independent relocation types
38643880 // which each backend (Elf, MachO, etc.) would then translate into an actual
38653881 // fixup when linking.
38663882 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
38673883 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
38683884 .target_addr = x,
3869 .offset = self.code.items.len + 3,
3885 .offset = self.code.items.len - 4,
38703886 .size = 4,
38713887 });
38723888 } else {
38733889 return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{});
38743890 }
38753891
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
38893892 // MOV reg, [reg]
38903893 encoder.rex(.{
38913894 .w = abi_size == 64,