authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-29 19:58:00+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-31 09:33:39+01:00
log1ee628a3e08ab5a150e45e79a778ac04e7f8b1e0
treed521e5f0775ed39b23e6e2c5da2607b3517e4a84
parentd7a27bf803fd29c499090c7bd0460fae9f0cf0f7

macho: improve error msg when relaxing GOT fails


1 files changed, 27 insertions(+), 7 deletions(-)

src/link/MachO/Atom.zig+27-7
......@@ -546,8 +546,8 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
546546
547547 relocs_log.debug("{x}: {s}", .{ self.value, name });
548548
549 var has_error = false;
549550 var stream = std.io.fixedBufferStream(buffer);
550
551551 var i: usize = 0;
552552 while (i < relocs.len) : (i += 1) {
553553 const rel = relocs[i];
......@@ -562,25 +562,34 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
562562 self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {
563563 switch (err) {
564564 error.RelaxFail => {
565 const target = switch (rel.tag) {
566 .@"extern" => rel.getTargetSymbol(macho_file).getName(macho_file),
567 .local => rel.getTargetAtom(macho_file).getName(macho_file),
568 };
565569 try macho_file.reportParseError2(
566570 file.getIndex(),
567 "{s}: 0x{x}: failed to relax relocation: in {s}",
568 .{ name, rel.offset, @tagName(rel.type) },
571 "{s}: 0x{x}: 0x{x}: failed to relax relocation: type {s}, target {s}",
572 .{ name, self.value, rel.offset, @tagName(rel.type), target },
569573 );
570 return error.ResolveFailed;
574 has_error = true;
571575 },
576 error.RelaxFailUnexpectedInstruction => has_error = true,
572577 else => |e| return e,
573578 }
574579 };
575580 }
581
582 if (has_error) return error.ResolveFailed;
576583}
577584
578585const ResolveError = error{
579586 RelaxFail,
587 RelaxFailUnexpectedInstruction,
580588 NoSpaceLeft,
581589 DivisionByZero,
582590 UnexpectedRemainder,
583591 Overflow,
592 OutOfMemory,
584593};
585594
586595fn resolveRelocInner(
......@@ -704,7 +713,7 @@ fn resolveRelocInner(
704713 if (rel.getTargetSymbol(macho_file).flags.has_got) {
705714 try writer.writeInt(i32, @intCast(G + A - P), .little);
706715 } else {
707 try x86_64.relaxGotLoad(code[rel_offset - 3 ..]);
716 try x86_64.relaxGotLoad(self, code[rel_offset - 3 ..], rel, macho_file);
708717 try writer.writeInt(i32, @intCast(S + A - P), .little);
709718 }
710719 },
......@@ -898,7 +907,7 @@ fn resolveRelocInner(
898907}
899908
900909const x86_64 = struct {
901 fn relaxGotLoad(code: []u8) error{RelaxFail}!void {
910 fn relaxGotLoad(self: Atom, code: []u8, rel: Relocation, macho_file: *MachO) ResolveError!void {
902911 const old_inst = disassemble(code) orelse return error.RelaxFail;
903912 switch (old_inst.encoding.mnemonic) {
904913 .mov => {
......@@ -906,7 +915,18 @@ const x86_64 = struct {
906915 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
907916 encode(&.{inst}, code) catch return error.RelaxFail;
908917 },
909 else => return error.RelaxFail,
918 else => |x| {
919 var err = try macho_file.addErrorWithNotes(2);
920 try err.addMsg(macho_file, "{s}: 0x{x}: 0x{x}: failed to relax relocation of type {s}", .{
921 self.getName(macho_file),
922 self.value,
923 rel.offset,
924 @tagName(rel.type),
925 });
926 try err.addNote(macho_file, "expected .mov instruction but found .{s}", .{@tagName(x)});
927 try err.addNote(macho_file, "while parsing {}", .{self.getFile(macho_file).fmtPath()});
928 return error.RelaxFailUnexpectedInstruction;
929 },
910930 }
911931 }
912932