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