| ... | @@ -7,6 +7,7 @@ const fs = std.fs; | ... | @@ -7,6 +7,7 @@ const fs = std.fs; |
| 7 | const log = std.log.scoped(.link); | 7 | const log = std.log.scoped(.link); |
| 8 | const macho = std.macho; | 8 | const macho = std.macho; |
| 9 | const codegen = @import("../codegen.zig"); | 9 | const codegen = @import("../codegen.zig"); |
| | 10 | const aarch64 = @import("../codegen/aarch64.zig"); |
| 10 | const math = std.math; | 11 | const math = std.math; |
| 11 | const mem = std.mem; | 12 | const mem = std.mem; |
| 12 | | 13 | |
| ... | @@ -1020,9 +1021,15 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1020,9 +1021,15 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1020 | while (decl.link.macho.pie_fixups.popOrNull()) |fixup| { | 1021 | while (decl.link.macho.pie_fixups.popOrNull()) |fixup| { |
| 1021 | const target_addr = fixup.address; | 1022 | const target_addr = fixup.address; |
| 1022 | const this_addr = symbol.n_value + fixup.start; | 1023 | const this_addr = symbol.n_value + fixup.start; |
| 1023 | const displacement = @intCast(u32, target_addr - this_addr - fixup.len); | 1024 | if (self.base.options.target.cpu.arch == .x86_64) { |
| 1024 | var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)]; | 1025 | const displacement = @intCast(u32, target_addr - this_addr - fixup.len); |
| 1025 | mem.writeIntSliceLittle(u32, placeholder, displacement); | 1026 | var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)]; |
| | 1027 | mem.writeIntSliceLittle(u32, placeholder, displacement); |
| | 1028 | } else { |
| | 1029 | const displacement = @intCast(u27, target_addr - this_addr); |
| | 1030 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; |
| | 1031 | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.bl(@intCast(i28, displacement)).toU32()); |
| | 1032 | } |
| 1026 | } | 1033 | } |
| 1027 | | 1034 | |
| 1028 | const text_section = self.sections.items[self.text_section_index.?]; | 1035 | const text_section = self.sections.items[self.text_section_index.?]; |
| ... | @@ -1646,22 +1653,28 @@ fn findFreeSpace(self: *MachO, object_size: u64, min_alignment: u16) u64 { | ... | @@ -1646,22 +1653,28 @@ fn findFreeSpace(self: *MachO, object_size: u64, min_alignment: u16) u64 { |
| 1646 | | 1653 | |
| 1647 | fn writeOffsetTableEntry(self: *MachO, index: usize) !void { | 1654 | fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 1648 | const sect = &self.sections.items[self.got_section_index.?]; | 1655 | const sect = &self.sections.items[self.got_section_index.?]; |
| 1649 | const endian = self.base.options.target.cpu.arch.endian(); | | |
| 1650 | | | |
| 1651 | const off = sect.offset + @sizeOf(u64) * index; | 1656 | const off = sect.offset + @sizeOf(u64) * index; |
| 1652 | const vmaddr = sect.addr + @sizeOf(u64) * index; | 1657 | const vmaddr = sect.addr + @sizeOf(u64) * index; |
| 1653 | const pos_symbol_off = @truncate(u31, vmaddr - self.offset_table.items[index] + 7); | | |
| 1654 | const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1); | | |
| 1655 | | 1658 | |
| 1656 | var code: [8]u8 = undefined; | 1659 | var code: [8]u8 = undefined; |
| 1657 | // lea %rax, [rip - disp] | 1660 | if (self.base.options.target.cpu.arch == .x86_64) { |
| 1658 | code[0] = 0x48; | 1661 | const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7); |
| 1659 | code[1] = 0x8D; | 1662 | const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1); |
| 1660 | code[2] = 0x5; | 1663 | // lea %rax, [rip - disp] |
| 1661 | mem.writeInt(u32, code[3..7], symbol_off, endian); | 1664 | code[0] = 0x48; |
| 1662 | // ret | 1665 | code[1] = 0x8D; |
| 1663 | code[7] = 0xC3; | 1666 | code[2] = 0x5; |
| 1664 | | 1667 | mem.writeIntLittle(u32, code[3..7], symbol_off); |
| | 1668 | // ret |
| | 1669 | code[7] = 0xC3; |
| | 1670 | } else { |
| | 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(.x1, symbol_off).toU32()); |
| | 1675 | // ret |
| | 1676 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ret(null).toU32()); |
| | 1677 | } |
| 1665 | log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off }); | 1678 | log.debug("writing offset table entry 0x{x} at 0x{x}\n", .{ self.offset_table.items[index], off }); |
| 1666 | try self.base.file.?.pwriteAll(&code, off); | 1679 | try self.base.file.?.pwriteAll(&code, off); |
| 1667 | } | 1680 | } |