authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-27 20:55:34+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-27 20:55:34+01:00
log5ed76268c9f0ecca8c5d62cb7e56da05aa8f1f7c
tree6f8e91dd2bef0543d309003e7447c96df127f127
parent02baaac506d0d64d1c946219335b7492222c4b64

stage2 macho: apply more review comments


2 files changed, 70 insertions(+), 46 deletions(-)

src/codegen.zig+37-21
......@@ -2601,11 +2601,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26012601 }).toU32());
26022602 // adr x28, #8
26032603 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
2604 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2605 .address = addr,
2606 .start = self.code.items.len,
2607 .len = 4,
2608 });
2604 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2605 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2606 .address = addr,
2607 .start = self.code.items.len,
2608 .len = 4,
2609 });
2610 } else {
2611 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2612 }
26092613 // b [label]
26102614 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
26112615 // mov r, x0
......@@ -2626,11 +2630,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26262630 }).toU32());
26272631 // adr x28, #8
26282632 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
2629 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2630 .address = addr,
2631 .start = self.code.items.len,
2632 .len = 4,
2633 });
2633 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2634 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2635 .address = addr,
2636 .start = self.code.items.len,
2637 .len = 4,
2638 });
2639 } else {
2640 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2641 }
26342642 // b [label]
26352643 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
26362644 // mov r, x0
......@@ -2828,7 +2836,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28282836 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8B, R });
28292837 },
28302838 .memory => |x| {
2831 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2839 if (self.bin_file.options.pie) {
28322840 // For MachO, the binary, with the exception of object files, has to be a PIE.
28332841 // Therefore, we cannot load an absolute address.
28342842 assert(x > math.maxInt(u32)); // 32bit direct addressing is not supported by MachO.
......@@ -2838,11 +2846,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28382846 // later in the linker.
28392847 if (reg.id() == 0) { // %rax is special-cased
28402848 try self.code.ensureCapacity(self.code.items.len + 5);
2841 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2842 .address = x,
2843 .start = self.code.items.len,
2844 .len = 5,
2845 });
2849 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2850 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2851 .address = x,
2852 .start = self.code.items.len,
2853 .len = 5,
2854 });
2855 } else {
2856 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2857 }
28462858 // call [label]
28472859 self.code.appendSliceAssumeCapacity(&[_]u8{
28482860 0xE8,
......@@ -2855,11 +2867,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28552867 try self.code.ensureCapacity(self.code.items.len + 10);
28562868 // push %rax
28572869 self.code.appendSliceAssumeCapacity(&[_]u8{0x50});
2858 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2859 .address = x,
2860 .start = self.code.items.len,
2861 .len = 5,
2862 });
2870 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2871 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2872 .address = x,
2873 .start = self.code.items.len,
2874 .len = 5,
2875 });
2876 } else {
2877 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2878 }
28632879 // call [label]
28642880 self.code.appendSliceAssumeCapacity(&[_]u8{
28652881 0xE8,
src/link/MachO.zig+33-25
......@@ -1015,14 +1015,18 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
10151015 while (self.pie_fixups.popOrNull()) |fixup| {
10161016 const target_addr = fixup.address;
10171017 const this_addr = symbol.n_value + fixup.start;
1018 if (self.base.options.target.cpu.arch == .x86_64) {
1019 const displacement = @intCast(u32, target_addr - this_addr - fixup.len);
1020 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
1021 mem.writeIntSliceLittle(u32, placeholder, displacement);
1022 } else {
1023 const displacement = @intCast(u27, target_addr - this_addr);
1024 var placeholder = code_buffer.items[fixup.start..][0..fixup.len];
1025 mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32());
1018 switch (self.base.options.target.cpu.arch) {
1019 .x86_64 => {
1020 const displacement = @intCast(u32, target_addr - this_addr - fixup.len);
1021 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
1022 mem.writeIntSliceLittle(u32, placeholder, displacement);
1023 },
1024 .aarch64 => {
1025 const displacement = @intCast(u27, target_addr - this_addr);
1026 var placeholder = code_buffer.items[fixup.start..][0..fixup.len];
1027 mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32());
1028 },
1029 else => unreachable, // unsupported target architecture
10261030 }
10271031 }
10281032
......@@ -1651,23 +1655,27 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
16511655 const vmaddr = sect.addr + @sizeOf(u64) * index;
16521656
16531657 var code: [8]u8 = undefined;
1654 if (self.base.options.target.cpu.arch == .x86_64) {
1655 const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);
1656 const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);
1657 // lea %rax, [rip - disp]
1658 code[0] = 0x48;
1659 code[1] = 0x8D;
1660 code[2] = 0x5;
1661 mem.writeIntLittle(u32, code[3..7], symbol_off);
1662 // ret
1663 code[7] = 0xC3;
1664 } else {
1665 const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);
1666 const symbol_off = @intCast(i21, pos_symbol_off) * -1;
1667 // adr x0, #-disp
1668 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());
1669 // ret x28
1670 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(.x28).toU32());
1658 switch (self.base.options.target.cpu.arch) {
1659 .x86_64 => {
1660 const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);
1661 const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);
1662 // lea %rax, [rip - disp]
1663 code[0] = 0x48;
1664 code[1] = 0x8D;
1665 code[2] = 0x5;
1666 mem.writeIntLittle(u32, code[3..7], symbol_off);
1667 // ret
1668 code[7] = 0xC3;
1669 },
1670 .aarch64 => {
1671 const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);
1672 const symbol_off = @intCast(i21, pos_symbol_off) * -1;
1673 // adr x0, #-disp
1674 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());
1675 // ret x28
1676 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(.x28).toU32());
1677 },
1678 else => unreachable, // unsupported target architecture
16711679 }
16721680 log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off });
16731681 try self.base.file.?.pwriteAll(&code, off);