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