authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-31 15:21:59+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-31 15:21:59+01:00
log788a0409af15d5823e0e96652ffb71458f78f820
tree4189ac0c5e6c25370729bc2ddc0bfe4733cd833d
parentd7a27bf803fd29c499090c7bd0460fae9f0cf0f7
parentd4966517f6d7204bb4c23204025cbd5ff3e06a03
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #18761 from ziglang/macho-fixes

macho: misc fixes and improvements

3 files changed, 38 insertions(+), 19 deletions(-)

src/arch/x86_64/Emit.zig+5-3
......@@ -62,7 +62,7 @@ pub fn emitMir(emit: *Emit) Error!void {
6262 .pcrel = true,
6363 .has_subtractor = false,
6464 .length = 2,
65 .symbolnum = 0,
65 .symbolnum = @intCast(symbol.sym_index),
6666 },
6767 });
6868 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
......@@ -165,7 +165,9 @@ pub fn emitMir(emit: *Emit) Error!void {
165165 const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
166166 .zig_got_load
167167 else if (sym.flags.needs_got)
168 .got_load
168 // TODO: it is possible to emit .got_load here that can potentially be relaxed
169 // however this requires always to use a MOVQ mnemonic
170 .got
169171 else if (sym.flags.tlv)
170172 .tlv
171173 else
......@@ -180,7 +182,7 @@ pub fn emitMir(emit: *Emit) Error!void {
180182 .pcrel = true,
181183 .has_subtractor = false,
182184 .length = 2,
183 .symbolnum = 0,
185 .symbolnum = @intCast(data.sym_index),
184186 },
185187 });
186188 } else unreachable,
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
src/link/MachO/ZigObject.zig+6-9
......@@ -390,7 +390,7 @@ pub fn getDeclVAddr(
390390 .pcrel = false,
391391 .has_subtractor = false,
392392 .length = 3,
393 .symbolnum = 0,
393 .symbolnum = @intCast(sym.nlist_idx),
394394 },
395395 });
396396 return vaddr;
......@@ -416,7 +416,7 @@ pub fn getAnonDeclVAddr(
416416 .pcrel = false,
417417 .has_subtractor = false,
418418 .length = 3,
419 .symbolnum = 0,
419 .symbolnum = @intCast(sym.nlist_idx),
420420 },
421421 });
422422 return vaddr;
......@@ -856,21 +856,18 @@ fn createTlvDescriptor(
856856 atom.alignment = alignment;
857857 atom.size = size;
858858
859 const tlv_bootstrap_index = blk: {
860 const index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
861 break :blk self.symbols.items[index];
862 };
859 const tlv_bootstrap_index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
863860 try atom.addReloc(macho_file, .{
864861 .tag = .@"extern",
865862 .offset = 0,
866 .target = tlv_bootstrap_index,
863 .target = self.symbols.items[tlv_bootstrap_index],
867864 .addend = 0,
868865 .type = .unsigned,
869866 .meta = .{
870867 .pcrel = false,
871868 .has_subtractor = false,
872869 .length = 3,
873 .symbolnum = 0,
870 .symbolnum = @intCast(tlv_bootstrap_index),
874871 },
875872 });
876873 try atom.addReloc(macho_file, .{
......@@ -883,7 +880,7 @@ fn createTlvDescriptor(
883880 .pcrel = false,
884881 .has_subtractor = false,
885882 .length = 3,
886 .symbolnum = 0,
883 .symbolnum = @intCast(macho_file.getSymbol(init_sym_index).nlist_idx),
887884 },
888885 });
889886