authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-23 10:13:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-23 12:04:17+02:00
log71bbc5efc9c35e4d862dba4f40e5bafe165fcbe4
tree079f4683ca39675d86ff2763a3090ad327d851d8
parent78b441e8deeb4e779335c09b865a497c13531657

link/macho: print error message when hitting unexpected remainder error


2 files changed, 72 insertions(+), 6 deletions(-)

src/link/MachO/Atom.zig+19-6
......@@ -660,6 +660,19 @@ fn resolveRelocInner(
660660 // Address of the __got_zig table entry if any.
661661 const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file)));
662662
663 const divExact = struct {
664 fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 {
665 return math.divExact(u12, num, den) catch {
666 try ctx.reportParseError2(atom.getFile(ctx).getIndex(), "{s}: unexpected remainder when resolving {s} at offset 0x{x}", .{
667 atom.getName(ctx),
668 r.fmtPretty(ctx.getTarget().cpu.arch),
669 r.offset,
670 });
671 return error.UnexpectedRemainder;
672 };
673 }
674 }.divExact;
675
663676 switch (rel.tag) {
664677 .local => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] atom({d})", .{
665678 P,
......@@ -831,12 +844,12 @@ fn resolveRelocInner(
831844 };
832845 inst.load_store_register.offset = switch (inst.load_store_register.size) {
833846 0 => if (inst.load_store_register.v == 1)
834 try math.divExact(u12, @truncate(target), 16)
847 try divExact(self, rel, @truncate(target), 16, macho_file)
835848 else
836849 @truncate(target),
837 1 => try math.divExact(u12, @truncate(target), 2),
838 2 => try math.divExact(u12, @truncate(target), 4),
839 3 => try math.divExact(u12, @truncate(target), 8),
850 1 => try divExact(self, rel, @truncate(target), 2, macho_file),
851 2 => try divExact(self, rel, @truncate(target), 4, macho_file),
852 3 => try divExact(self, rel, @truncate(target), 8, macho_file),
840853 };
841854 try writer.writeInt(u32, inst.toU32(), .little);
842855 }
......@@ -847,7 +860,7 @@ fn resolveRelocInner(
847860 assert(rel.meta.length == 2);
848861 assert(!rel.meta.pcrel);
849862 const target = math.cast(u64, G + A) orelse return error.Overflow;
850 aarch64.writeLoadStoreRegInst(try math.divExact(u12, @truncate(target), 8), code[rel_offset..][0..4]);
863 aarch64.writeLoadStoreRegInst(try divExact(self, rel, @truncate(target), 8, macho_file), code[rel_offset..][0..4]);
851864 },
852865
853866 .tlvp_pageoff => {
......@@ -899,7 +912,7 @@ fn resolveRelocInner(
899912 .load_store_register = .{
900913 .rt = reg_info.rd,
901914 .rn = reg_info.rn,
902 .offset = try math.divExact(u12, @truncate(target), 8),
915 .offset = try divExact(self, rel, @truncate(target), 8, macho_file),
903916 .opc = 0b01,
904917 .op1 = 0b01,
905918 .v = 0,
src/link/MachO/Relocation.zig+53
......@@ -60,6 +60,59 @@ pub fn lessThan(ctx: void, lhs: Relocation, rhs: Relocation) bool {
6060 return lhs.offset < rhs.offset;
6161}
6262
63const FormatCtx = struct { Relocation, std.Target.Cpu.Arch };
64
65pub fn fmtPretty(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) std.fmt.Formatter(formatPretty) {
66 return .{ .data = .{ rel, cpu_arch } };
67}
68
69fn formatPretty(
70 ctx: FormatCtx,
71 comptime unused_fmt_string: []const u8,
72 options: std.fmt.FormatOptions,
73 writer: anytype,
74) !void {
75 _ = options;
76 _ = unused_fmt_string;
77 const rel, const cpu_arch = ctx;
78 const str = switch (rel.type) {
79 .signed => "X86_64_RELOC_SIGNED",
80 .signed1 => "X86_64_RELOC_SIGNED_1",
81 .signed2 => "X86_64_RELOC_SIGNED_2",
82 .signed4 => "X86_64_RELOC_SIGNED_4",
83 .got_load => "X86_64_RELOC_GOT_LOAD",
84 .tlv => "X86_64_RELOC_TLV",
85 .zig_got_load => "ZIG_GOT_LOAD",
86 .page => "ARM64_RELOC_PAGE21",
87 .pageoff => "ARM64_RELOC_PAGEOFF12",
88 .got_load_page => "ARM64_RELOC_GOT_LOAD_PAGE21",
89 .got_load_pageoff => "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
90 .tlvp_page => "ARM64_RELOC_TLVP_LOAD_PAGE21",
91 .tlvp_pageoff => "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
92 .branch => switch (cpu_arch) {
93 .x86_64 => "X86_64_RELOC_BRANCH",
94 .aarch64 => "ARM64_RELOC_BRANCH26",
95 else => unreachable,
96 },
97 .got => switch (cpu_arch) {
98 .x86_64 => "X86_64_RELOC_GOT",
99 .aarch64 => "ARM64_RELOC_POINTER_TO_GOT",
100 else => unreachable,
101 },
102 .subtractor => switch (cpu_arch) {
103 .x86_64 => "X86_64_RELOC_SUBTRACTOR",
104 .aarch64 => "ARM64_RELOC_SUBTRACTOR",
105 else => unreachable,
106 },
107 .unsigned => switch (cpu_arch) {
108 .x86_64 => "X86_64_RELOC_UNSIGNED",
109 .aarch64 => "ARM64_RELOC_UNSIGNED",
110 else => unreachable,
111 },
112 };
113 try writer.writeAll(str);
114}
115
63116pub const Type = enum {
64117 // x86_64
65118 /// RIP-relative displacement (X86_64_RELOC_SIGNED)