Commit 5ed76268c9

Jakub Konka <kubkon@jakubkonka.com>
2020-11-27 20:55:34
stage2 macho: apply more review comments
1 parent 02baaac
Changed files (2)
src/link/MachO.zig
@@ -1015,14 +1015,18 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
     while (self.pie_fixups.popOrNull()) |fixup| {
         const target_addr = fixup.address;
         const this_addr = symbol.n_value + fixup.start;
-        if (self.base.options.target.cpu.arch == .x86_64) {
-            const displacement = @intCast(u32, target_addr - this_addr - fixup.len);
-            var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
-            mem.writeIntSliceLittle(u32, placeholder, displacement);
-        } else {
-            const displacement = @intCast(u27, target_addr - this_addr);
-            var placeholder = code_buffer.items[fixup.start..][0..fixup.len];
-            mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32());
+        switch (self.base.options.target.cpu.arch) {
+            .x86_64 => {
+                const displacement = @intCast(u32, target_addr - this_addr - fixup.len);
+                var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
+                mem.writeIntSliceLittle(u32, placeholder, displacement);
+            },
+            .aarch64 => {
+                const displacement = @intCast(u27, target_addr - this_addr);
+                var placeholder = code_buffer.items[fixup.start..][0..fixup.len];
+                mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32());
+            },
+            else => unreachable, // unsupported target architecture
         }
     }
 
@@ -1651,23 +1655,27 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
     const vmaddr = sect.addr + @sizeOf(u64) * index;
 
     var code: [8]u8 = undefined;
-    if (self.base.options.target.cpu.arch == .x86_64) {
-        const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);
-        const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);
-        // lea %rax, [rip - disp]
-        code[0] = 0x48;
-        code[1] = 0x8D;
-        code[2] = 0x5;
-        mem.writeIntLittle(u32, code[3..7], symbol_off);
-        // ret
-        code[7] = 0xC3;
-    } else {
-        const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);
-        const symbol_off = @intCast(i21, pos_symbol_off) * -1;
-        // adr x0, #-disp
-        mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());
-        // ret x28
-        mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(.x28).toU32());
+    switch (self.base.options.target.cpu.arch) {
+        .x86_64 => {
+            const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7);
+            const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1);
+            // lea %rax, [rip - disp]
+            code[0] = 0x48;
+            code[1] = 0x8D;
+            code[2] = 0x5;
+            mem.writeIntLittle(u32, code[3..7], symbol_off);
+            // ret
+            code[7] = 0xC3;
+        },
+        .aarch64 => {
+            const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]);
+            const symbol_off = @intCast(i21, pos_symbol_off) * -1;
+            // adr x0, #-disp
+            mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());
+            // ret x28
+            mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(.x28).toU32());
+        },
+        else => unreachable, // unsupported target architecture
     }
     log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off });
     try self.base.file.?.pwriteAll(&code, off);
src/codegen.zig
@@ -2601,11 +2601,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
                                 }).toU32());
                                 // adr x28, #8
                                 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
-                                try macho_file.pie_fixups.append(self.bin_file.allocator, .{
-                                    .address = addr,
-                                    .start = self.code.items.len,
-                                    .len = 4,
-                                });
+                                if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+                                    try macho_file.pie_fixups.append(self.bin_file.allocator, .{
+                                        .address = addr,
+                                        .start = self.code.items.len,
+                                        .len = 4,
+                                    });
+                                } else {
+                                    return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
+                                }
                                 // b [label]
                                 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
                                 // mov r, x0
@@ -2626,11 +2630,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
                                 }).toU32());
                                 // adr x28, #8
                                 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
-                                try macho_file.pie_fixups.append(self.bin_file.allocator, .{
-                                    .address = addr,
-                                    .start = self.code.items.len,
-                                    .len = 4,
-                                });
+                                if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+                                    try macho_file.pie_fixups.append(self.bin_file.allocator, .{
+                                        .address = addr,
+                                        .start = self.code.items.len,
+                                        .len = 4,
+                                    });
+                                } else {
+                                    return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
+                                }
                                 // b [label]
                                 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
                                 // mov r, x0
@@ -2828,7 +2836,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
                         self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8B, R });
                     },
                     .memory => |x| {
-                        if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+                        if (self.bin_file.options.pie) {
                             // For MachO, the binary, with the exception of object files, has to be a PIE.
                             // Therefore, we cannot load an absolute address.
                             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 {
                             // later in the linker.
                             if (reg.id() == 0) { // %rax is special-cased
                                 try self.code.ensureCapacity(self.code.items.len + 5);
-                                try macho_file.pie_fixups.append(self.bin_file.allocator, .{
-                                    .address = x,
-                                    .start = self.code.items.len,
-                                    .len = 5,
-                                });
+                                if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+                                    try macho_file.pie_fixups.append(self.bin_file.allocator, .{
+                                        .address = x,
+                                        .start = self.code.items.len,
+                                        .len = 5,
+                                    });
+                                } else {
+                                    return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
+                                }
                                 // call [label]
                                 self.code.appendSliceAssumeCapacity(&[_]u8{
                                     0xE8,
@@ -2855,11 +2867,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
                                 try self.code.ensureCapacity(self.code.items.len + 10);
                                 // push %rax
                                 self.code.appendSliceAssumeCapacity(&[_]u8{0x50});
-                                try macho_file.pie_fixups.append(self.bin_file.allocator, .{
-                                    .address = x,
-                                    .start = self.code.items.len,
-                                    .len = 5,
-                                });
+                                if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+                                    try macho_file.pie_fixups.append(self.bin_file.allocator, .{
+                                        .address = x,
+                                        .start = self.code.items.len,
+                                        .len = 5,
+                                    });
+                                } else {
+                                    return self.fail(src, "TODO implement genSetReg for PIE on this platform", .{});
+                                }
                                 // call [label]
                                 self.code.appendSliceAssumeCapacity(&[_]u8{
                                     0xE8,