authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-21 22:22:40+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-21 22:22:40+01:00
log887709ed5cac0275c09e6d2aa2faf729c5b5603d
tree85b16ccd0e8ca7b3c293866118cebb8e3c00381b
parentd7d47a2c0c1585885d6ba45beb10744af48c2092

elf+aarch64: implement some resolveRelocAlloc logic


1 files changed, 120 insertions(+), 0 deletions(-)

src/link/Elf/Atom.zig+120
......@@ -768,6 +768,14 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
768768 => has_reloc_errors = true,
769769 else => |e| return e,
770770 },
771 .aarch64 => aarch64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
772 error.RelocFailure,
773 error.RelaxFailure,
774 error.UnexpectedRemainder,
775 error.DivisionByZero,
776 => has_reloc_errors = true,
777 else => |e| return e,
778 },
771779 else => return error.UnsupportedCpuArch,
772780 }
773781 }
......@@ -1606,6 +1614,117 @@ const aarch64 = struct {
16061614 else => try atom.reportUnhandledRelocError(rel, elf_file),
16071615 }
16081616 }
1617
1618 fn resolveRelocAlloc(
1619 atom: Atom,
1620 elf_file: *Elf,
1621 rel: elf.Elf64_Rela,
1622 target: *const Symbol,
1623 args: ResolveArgs,
1624 it: *RelocsIterator,
1625 code: []u8,
1626 stream: anytype,
1627 ) (error{ UnexpectedRemainder, DivisionByZero } || RelocError)!void {
1628 _ = it;
1629
1630 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
1631 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
1632
1633 try stream.seekTo(r_offset);
1634 const cwriter = stream.writer();
1635
1636 const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args;
1637 _ = TP;
1638 _ = DTP;
1639 _ = ZIG_GOT;
1640
1641 switch (r_type) {
1642 .NONE => unreachable,
1643 .ABS64 => {
1644 try atom.resolveDynAbsReloc(
1645 target,
1646 rel,
1647 dynAbsRelocAction(target, elf_file),
1648 elf_file,
1649 cwriter,
1650 );
1651 },
1652
1653 .CALL26,
1654 .JUMP26,
1655 => {
1656 // TODO: add thunk support
1657 const disp: i28 = math.cast(i28, S + A - P) orelse {
1658 var err = try elf_file.addErrorWithNotes(1);
1659 try err.addMsg(elf_file, "TODO: branch relocation target ({s}) exceeds max jump distance", .{
1660 target.name(elf_file),
1661 });
1662 try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{
1663 atom.file(elf_file).?.fmtPath(),
1664 atom.name(elf_file),
1665 r_offset,
1666 });
1667 return;
1668 };
1669 try aarch64_util.writeBranchImm(disp, code[r_offset..][0..4]);
1670 },
1671
1672 .ADR_PREL_PG_HI21 => {
1673 // TODO: check for relaxation of ADRP+ADD
1674 const saddr = @as(u64, @intCast(P));
1675 const taddr = @as(u64, @intCast(S + A));
1676 const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(saddr, taddr)));
1677 try aarch64_util.writePages(pages, code[r_offset..][0..4]);
1678 },
1679
1680 .ADR_GOT_PAGE => if (target.flags.has_got) {
1681 const saddr = @as(u64, @intCast(P));
1682 const taddr = @as(u64, @intCast(G + GOT + A));
1683 const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(saddr, taddr)));
1684 try aarch64_util.writePages(pages, code[r_offset..][0..4]);
1685 } else {
1686 // TODO: relax
1687 var err = try elf_file.addErrorWithNotes(1);
1688 try err.addMsg(elf_file, "TODO: relax ADR_GOT_PAGE", .{});
1689 try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{
1690 atom.file(elf_file).?.fmtPath(),
1691 atom.name(elf_file),
1692 r_offset,
1693 });
1694 },
1695
1696 .LD64_GOT_LO12_NC => {
1697 assert(target.flags.has_got);
1698 const taddr = @as(u64, @intCast(G + GOT + A));
1699 try aarch64_util.writePageOffset(.load_store_64, taddr, code[r_offset..][0..4]);
1700 },
1701
1702 .ADD_ABS_LO12_NC,
1703 .LDST8_ABS_LO12_NC,
1704 .LDST16_ABS_LO12_NC,
1705 .LDST32_ABS_LO12_NC,
1706 .LDST64_ABS_LO12_NC,
1707 .LDST128_ABS_LO12_NC,
1708 => {
1709 // TODO: NC means no overflow check
1710 const taddr = @as(u64, @intCast(S + A));
1711 const kind: aarch64_util.PageOffsetInstKind = switch (r_type) {
1712 .ADD_ABS_LO12_NC => .arithmetic,
1713 .LDST8_ABS_LO12_NC => .load_store_8,
1714 .LDST16_ABS_LO12_NC => .load_store_16,
1715 .LDST32_ABS_LO12_NC => .load_store_32,
1716 .LDST64_ABS_LO12_NC => .load_store_64,
1717 .LDST128_ABS_LO12_NC => .load_store_128,
1718 else => unreachable,
1719 };
1720 try aarch64_util.writePageOffset(kind, taddr, code[r_offset..][0..4]);
1721 },
1722
1723 else => try atom.reportUnhandledRelocError(rel, elf_file),
1724 }
1725 }
1726
1727 const aarch64_util = @import("../aarch64.zig");
16091728};
16101729
16111730const ResolveArgs = struct { i64, i64, i64, i64, i64, i64, i64, i64 };
......@@ -1647,6 +1766,7 @@ const assert = std.debug.assert;
16471766const elf = std.elf;
16481767const eh_frame = @import("eh_frame.zig");
16491768const log = std.log.scoped(.link);
1769const math = std.math;
16501770const relocs_log = std.log.scoped(.link_relocs);
16511771const relocation = @import("relocation.zig");
16521772