diff options
| author | gracefu <81774659+gracefuu@users.noreply.github.com> | 2021-04-11 16:41:49 +0800 |
|---|---|---|
| committer | gracefu <81774659+gracefuu@users.noreply.github.com> | 2021-04-16 15:21:17 +0800 |
| commit | b004c3da159645cf4a3387f808ab3e8a6277ba2f (patch) | |
| tree | b8657e250daa840659c573a61948cdd8a230cdcf /src | |
| parent | 0409f9e0244aebab5c47f0ec24114e101c3f54e6 (diff) | |
| download | zig-b004c3da159645cf4a3387f808ab3e8a6277ba2f.tar.gz zig-b004c3da159645cf4a3387f808ab3e8a6277ba2f.zip | |
stage2 x86_64: try to fix RIP-relative offset to GOT for macho
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.zig | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 27a60597d4..e24d197d54 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -3860,32 +3860,35 @@ 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. + const abi_size = ty.abiSize(self.target.*); + const encoder = try X8664Encoder.init(self.code, 7); + + // LEA reg, [<offset>] + + // 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 [<offset>] will be at self.code.items.len - 4. + encoder.rex(.{ + .w = abi_size == 64, + .r = reg.isExtended(), + }); + encoder.opcode_1byte(0x8D); + 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 + 3, + .offset = self.code.items.len - 4, .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, [<offset>] - // 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. - encoder.rex(.{ - .w = abi_size == 64, - .r = reg.isExtended(), - }); - encoder.opcode_1byte(0x8D); - encoder.modRm_RIPDisp32(reg.low_id()); - encoder.disp32(0); - // MOV reg, [reg] encoder.rex(.{ .w = abi_size == 64, |
