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 {...@@ -2601,11 +2601,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2601 }).toU32());2601 }).toU32());
2602 // adr x28, #82602 // adr x28, #8
2603 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());2603 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
2604 try macho_file.pie_fixups.append(self.bin_file.allocator, .{2604 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2605 .address = addr,2605 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2606 .start = self.code.items.len,2606 .address = addr,
2607 .len = 4,2607 .start = self.code.items.len,
2608 });2608 .len = 4,
2609 });
2610 } else {
2611 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2612 }
2609 // b [label]2613 // b [label]
2610 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());2614 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
2611 // mov r, x02615 // mov r, x0
...@@ -2626,11 +2630,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2626,11 +2630,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2626 }).toU32());2630 }).toU32());
2627 // adr x28, #82631 // adr x28, #8
2628 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());2632 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
2629 try macho_file.pie_fixups.append(self.bin_file.allocator, .{2633 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2630 .address = addr,2634 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2631 .start = self.code.items.len,2635 .address = addr,
2632 .len = 4,2636 .start = self.code.items.len,
2633 });2637 .len = 4,
2638 });
2639 } else {
2640 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2641 }
2634 // b [label]2642 // b [label]
2635 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());2643 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
2636 // mov r, x02644 // mov r, x0
...@@ -2828,7 +2836,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2828,7 +2836,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2828 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8B, R });2836 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8B, R });
2829 },2837 },
2830 .memory => |x| {2838 .memory => |x| {
2831 if (self.bin_file.cast(link.File.MachO)) |macho_file| {2839 if (self.bin_file.options.pie) {
2832 // For MachO, the binary, with the exception of object files, has to be a PIE.2840 // For MachO, the binary, with the exception of object files, has to be a PIE.
2833 // Therefore, we cannot load an absolute address.2841 // Therefore, we cannot load an absolute address.
2834 assert(x > math.maxInt(u32)); // 32bit direct addressing is not supported by MachO.2842 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 {...@@ -2838,11 +2846,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2838 // later in the linker.2846 // later in the linker.
2839 if (reg.id() == 0) { // %rax is special-cased2847 if (reg.id() == 0) { // %rax is special-cased
2840 try self.code.ensureCapacity(self.code.items.len + 5);2848 try self.code.ensureCapacity(self.code.items.len + 5);
2841 try macho_file.pie_fixups.append(self.bin_file.allocator, .{2849 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2842 .address = x,2850 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2843 .start = self.code.items.len,2851 .address = x,
2844 .len = 5,2852 .start = self.code.items.len,
2845 });2853 .len = 5,
2854 });
2855 } else {
2856 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2857 }
2846 // call [label]2858 // call [label]
2847 self.code.appendSliceAssumeCapacity(&[_]u8{2859 self.code.appendSliceAssumeCapacity(&[_]u8{
2848 0xE8,2860 0xE8,
...@@ -2855,11 +2867,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2855,11 +2867,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2855 try self.code.ensureCapacity(self.code.items.len + 10);2867 try self.code.ensureCapacity(self.code.items.len + 10);
2856 // push %rax2868 // push %rax
2857 self.code.appendSliceAssumeCapacity(&[_]u8{0x50});2869 self.code.appendSliceAssumeCapacity(&[_]u8{0x50});
2858 try macho_file.pie_fixups.append(self.bin_file.allocator, .{2870 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2859 .address = x,2871 try macho_file.pie_fixups.append(self.bin_file.allocator, .{
2860 .start = self.code.items.len,2872 .address = x,
2861 .len = 5,2873 .start = self.code.items.len,
2862 });2874 .len = 5,
2875 });
2876 } else {
2877 return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
2878 }
2863 // call [label]2879 // call [label]
2864 self.code.appendSliceAssumeCapacity(&[_]u8{2880 self.code.appendSliceAssumeCapacity(&[_]u8{
2865 0xE8,2881 0xE8,
src/link/MachO.zig+33-25
...@@ -1015,14 +1015,18 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -1015,14 +1015,18 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
1015 while (self.pie_fixups.popOrNull()) |fixup| {1015 while (self.pie_fixups.popOrNull()) |fixup| {
1016 const target_addr = fixup.address;1016 const target_addr = fixup.address;
1017 const this_addr = symbol.n_value + fixup.start;1017 const this_addr = symbol.n_value + fixup.start;
1018 if (self.base.options.target.cpu.arch == .x86_64) {1018 switch (self.base.options.target.cpu.arch) {
1019 const displacement = @intCast(u32, target_addr - this_addr - fixup.len);1019 .x86_64 => {
1020 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];1020 const displacement = @intCast(u32, target_addr - this_addr - fixup.len);
1021 mem.writeIntSliceLittle(u32, placeholder, displacement);1021 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
1022 } else {1022 mem.writeIntSliceLittle(u32, placeholder, displacement);
1023 const displacement = @intCast(u27, target_addr - this_addr);1023 },
1024 var placeholder = code_buffer.items[fixup.start..][0..fixup.len];1024 .aarch64 => {
1025 mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32());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
1026 }1030 }
1027 }1031 }
10281032
...@@ -1651,23 +1655,27 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {...@@ -1651,23 +1655,27 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
1651 const vmaddr = sect.addr + @sizeOf(u64) * index;1655 const vmaddr = sect.addr + @sizeOf(u64) * index;
16521656
1653 var code: [8]u8 = undefined;1657 var code: [8]u8 = undefined;
1654 if (self.base.options.target.cpu.arch == .x86_64) {1658 switch (self.base.options.target.cpu.arch) {
1655 const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);1659 .x86_64 => {
1656 const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);1660 const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);
1657 // lea %rax, [rip - disp]1661 const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);
1658 code[0] = 0x48;1662 // lea %rax, [rip - disp]
1659 code[1] = 0x8D;1663 code[0] = 0x48;
1660 code[2] = 0x5;1664 code[1] = 0x8D;
1661 mem.writeIntLittle(u32, code[3..7], symbol_off);1665 code[2] = 0x5;
1662 // ret1666 mem.writeIntLittle(u32, code[3..7], symbol_off);
1663 code[7] = 0xC3;1667 // ret
1664 } else {1668 code[7] = 0xC3;
1665 const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);1669 },
1666 const symbol_off = @intCast(i21, pos_symbol_off) * -1;1670 .aarch64 => {
1667 // adr x0, #-disp1671 const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);
1668 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());1672 const symbol_off = @intCast(i21, pos_symbol_off) * -1;
1669 // ret x281673 // adr x0, #-disp
1670 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(.x28).toU32());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
1671 }1679 }
1672 log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off });1680 log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off });
1673 try self.base.file.?.pwriteAll(&code, off);1681 try self.base.file.?.pwriteAll(&code, off);