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 {...@@ -62,7 +62,7 @@ pub fn emitMir(emit: *Emit) Error!void {
62 .pcrel = true,62 .pcrel = true,
63 .has_subtractor = false,63 .has_subtractor = false,
64 .length = 2,64 .length = 2,
65 .symbolnum = 0,65 .symbolnum = @intCast(symbol.sym_index),
66 },66 },
67 });67 });
68 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {68 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
...@@ -165,7 +165,9 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -165,7 +165,9 @@ pub fn emitMir(emit: *Emit) Error!void {
165 const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)165 const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
166 .zig_got_load166 .zig_got_load
167 else if (sym.flags.needs_got)167 else if (sym.flags.needs_got)
168 .got_load168 // 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
169 else if (sym.flags.tlv)171 else if (sym.flags.tlv)
170 .tlv172 .tlv
171 else173 else
...@@ -180,7 +182,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -180,7 +182,7 @@ pub fn emitMir(emit: *Emit) Error!void {
180 .pcrel = true,182 .pcrel = true,
181 .has_subtractor = false,183 .has_subtractor = false,
182 .length = 2,184 .length = 2,
183 .symbolnum = 0,185 .symbolnum = @intCast(data.sym_index),
184 },186 },
185 });187 });
186 } else unreachable,188 } else unreachable,
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
src/link/MachO/ZigObject.zig+6-9
...@@ -390,7 +390,7 @@ pub fn getDeclVAddr(...@@ -390,7 +390,7 @@ pub fn getDeclVAddr(
390 .pcrel = false,390 .pcrel = false,
391 .has_subtractor = false,391 .has_subtractor = false,
392 .length = 3,392 .length = 3,
393 .symbolnum = 0,393 .symbolnum = @intCast(sym.nlist_idx),
394 },394 },
395 });395 });
396 return vaddr;396 return vaddr;
...@@ -416,7 +416,7 @@ pub fn getAnonDeclVAddr(...@@ -416,7 +416,7 @@ pub fn getAnonDeclVAddr(
416 .pcrel = false,416 .pcrel = false,
417 .has_subtractor = false,417 .has_subtractor = false,
418 .length = 3,418 .length = 3,
419 .symbolnum = 0,419 .symbolnum = @intCast(sym.nlist_idx),
420 },420 },
421 });421 });
422 return vaddr;422 return vaddr;
...@@ -856,21 +856,18 @@ fn createTlvDescriptor(...@@ -856,21 +856,18 @@ fn createTlvDescriptor(
856 atom.alignment = alignment;856 atom.alignment = alignment;
857 atom.size = size;857 atom.size = size;
858858
859 const tlv_bootstrap_index = blk: {859 const tlv_bootstrap_index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
860 const index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
861 break :blk self.symbols.items[index];
862 };
863 try atom.addReloc(macho_file, .{860 try atom.addReloc(macho_file, .{
864 .tag = .@"extern",861 .tag = .@"extern",
865 .offset = 0,862 .offset = 0,
866 .target = tlv_bootstrap_index,863 .target = self.symbols.items[tlv_bootstrap_index],
867 .addend = 0,864 .addend = 0,
868 .type = .unsigned,865 .type = .unsigned,
869 .meta = .{866 .meta = .{
870 .pcrel = false,867 .pcrel = false,
871 .has_subtractor = false,868 .has_subtractor = false,
872 .length = 3,869 .length = 3,
873 .symbolnum = 0,870 .symbolnum = @intCast(tlv_bootstrap_index),
874 },871 },
875 });872 });
876 try atom.addReloc(macho_file, .{873 try atom.addReloc(macho_file, .{
...@@ -883,7 +880,7 @@ fn createTlvDescriptor(...@@ -883,7 +880,7 @@ fn createTlvDescriptor(
883 .pcrel = false,880 .pcrel = false,
884 .has_subtractor = false,881 .has_subtractor = false,
885 .length = 3,882 .length = 3,
886 .symbolnum = 0,883 .symbolnum = @intCast(macho_file.getSymbol(init_sym_index).nlist_idx),
887 },884 },
888 });885 });
889886