| ... | @@ -660,6 +660,19 @@ fn resolveRelocInner( | ... | @@ -660,6 +660,19 @@ fn resolveRelocInner( |
| 660 | // Address of the __got_zig table entry if any. | 660 | // Address of the __got_zig table entry if any. |
| 661 | const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file))); | 661 | const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file))); |
| 662 | | 662 | |
| | 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 | |
| 663 | switch (rel.tag) { | 676 | switch (rel.tag) { |
| 664 | .local => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] atom({d})", .{ | 677 | .local => relocs_log.debug(" {x}<+{d}>: {s}: [=> {x}] atom({d})", .{ |
| 665 | P, | 678 | P, |
| ... | @@ -831,12 +844,12 @@ fn resolveRelocInner( | ... | @@ -831,12 +844,12 @@ fn resolveRelocInner( |
| 831 | }; | 844 | }; |
| 832 | inst.load_store_register.offset = switch (inst.load_store_register.size) { | 845 | inst.load_store_register.offset = switch (inst.load_store_register.size) { |
| 833 | 0 => if (inst.load_store_register.v == 1) | 846 | 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) |
| 835 | else | 848 | else |
| 836 | @truncate(target), | 849 | @truncate(target), |
| 837 | 1 => try math.divExact(u12, @truncate(target), 2), | 850 | 1 => try divExact(self, rel, @truncate(target), 2, macho_file), |
| 838 | 2 => try math.divExact(u12, @truncate(target), 4), | 851 | 2 => try divExact(self, rel, @truncate(target), 4, macho_file), |
| 839 | 3 => try math.divExact(u12, @truncate(target), 8), | 852 | 3 => try divExact(self, rel, @truncate(target), 8, macho_file), |
| 840 | }; | 853 | }; |
| 841 | try writer.writeInt(u32, inst.toU32(), .little); | 854 | try writer.writeInt(u32, inst.toU32(), .little); |
| 842 | } | 855 | } |
| ... | @@ -847,7 +860,7 @@ fn resolveRelocInner( | ... | @@ -847,7 +860,7 @@ fn resolveRelocInner( |
| 847 | assert(rel.meta.length == 2); | 860 | assert(rel.meta.length == 2); |
| 848 | assert(!rel.meta.pcrel); | 861 | assert(!rel.meta.pcrel); |
| 849 | const target = math.cast(u64, G + A) orelse return error.Overflow; | 862 | 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]); |
| 851 | }, | 864 | }, |
| 852 | | 865 | |
| 853 | .tlvp_pageoff => { | 866 | .tlvp_pageoff => { |
| ... | @@ -899,7 +912,7 @@ fn resolveRelocInner( | ... | @@ -899,7 +912,7 @@ fn resolveRelocInner( |
| 899 | .load_store_register = .{ | 912 | .load_store_register = .{ |
| 900 | .rt = reg_info.rd, | 913 | .rt = reg_info.rd, |
| 901 | .rn = reg_info.rn, | 914 | .rn = reg_info.rn, |
| 902 | .offset = try math.divExact(u12, @truncate(target), 8), | 915 | .offset = try divExact(self, rel, @truncate(target), 8, macho_file), |
| 903 | .opc = 0b01, | 916 | .opc = 0b01, |
| 904 | .op1 = 0b01, | 917 | .op1 = 0b01, |
| 905 | .v = 0, | 918 | .v = 0, |