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 {...@@ -546,8 +546,8 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
546546
547 relocs_log.debug("{x}: {s}", .{ self.value, name });547 relocs_log.debug("{x}: {s}", .{ self.value, name });
548548
549 var has_error = false;
549 var stream = std.io.fixedBufferStream(buffer);550 var stream = std.io.fixedBufferStream(buffer);
550
551 var i: usize = 0;551 var i: usize = 0;
552 while (i < relocs.len) : (i += 1) {552 while (i < relocs.len) : (i += 1) {
553 const rel = relocs[i];553 const rel = relocs[i];
...@@ -562,25 +562,34 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {...@@ -562,25 +562,34 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
562 self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {562 self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {
563 switch (err) {563 switch (err) {
564 error.RelaxFail => {564 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 };
565 try macho_file.reportParseError2(569 try macho_file.reportParseError2(
566 file.getIndex(),570 file.getIndex(),
567 "{s}: 0x{x}: failed to relax relocation: in {s}",571 "{s}: 0x{x}: 0x{x}: failed to relax relocation: type {s}, target {s}",
568 .{ name, rel.offset, @tagName(rel.type) },572 .{ name, self.value, rel.offset, @tagName(rel.type), target },
569 );573 );
570 return error.ResolveFailed;574 has_error = true;
571 },575 },
576 error.RelaxFailUnexpectedInstruction => has_error = true,
572 else => |e| return e,577 else => |e| return e,
573 }578 }
574 };579 };
575 }580 }
581
582 if (has_error) return error.ResolveFailed;
576}583}
577584
578const ResolveError = error{585const ResolveError = error{
579 RelaxFail,586 RelaxFail,
587 RelaxFailUnexpectedInstruction,
580 NoSpaceLeft,588 NoSpaceLeft,
581 DivisionByZero,589 DivisionByZero,
582 UnexpectedRemainder,590 UnexpectedRemainder,
583 Overflow,591 Overflow,
592 OutOfMemory,
584};593};
585594
586fn resolveRelocInner(595fn resolveRelocInner(
...@@ -704,7 +713,7 @@ fn resolveRelocInner(...@@ -704,7 +713,7 @@ fn resolveRelocInner(
704 if (rel.getTargetSymbol(macho_file).flags.has_got) {713 if (rel.getTargetSymbol(macho_file).flags.has_got) {
705 try writer.writeInt(i32, @intCast(G + A - P), .little);714 try writer.writeInt(i32, @intCast(G + A - P), .little);
706 } else {715 } else {
707 try x86_64.relaxGotLoad(code[rel_offset - 3 ..]);716 try x86_64.relaxGotLoad(self, code[rel_offset - 3 ..], rel, macho_file);
708 try writer.writeInt(i32, @intCast(S + A - P), .little);717 try writer.writeInt(i32, @intCast(S + A - P), .little);
709 }718 }
710 },719 },
...@@ -898,7 +907,7 @@ fn resolveRelocInner(...@@ -898,7 +907,7 @@ fn resolveRelocInner(
898}907}
899908
900const x86_64 = struct {909const 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 {
902 const old_inst = disassemble(code) orelse return error.RelaxFail;911 const old_inst = disassemble(code) orelse return error.RelaxFail;
903 switch (old_inst.encoding.mnemonic) {912 switch (old_inst.encoding.mnemonic) {
904 .mov => {913 .mov => {
...@@ -906,7 +915,18 @@ const x86_64 = struct {...@@ -906,7 +915,18 @@ const x86_64 = struct {
906 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });915 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
907 encode(&.{inst}, code) catch return error.RelaxFail;916 encode(&.{inst}, code) catch return error.RelaxFail;
908 },917 },
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 },
910 }930 }
911 }931 }
912932