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 {...@@ -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 types3879 // TODO we should come up with our own, backend independent relocation types
3864 // which each backend (Elf, MachO, etc.) would then translate into an actual3880 // 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 }
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
3889 // MOV reg, [reg]3892 // MOV reg, [reg]
3890 encoder.rex(.{3893 encoder.rex(.{
3891 .w = abi_size == 64,3894 .w = abi_size == 64,