authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-02 12:31:40+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:49+01:00
log89d862180f1d032b36e8d4371a037ae018bc43c5
tree3c21e0203fb7d4a2a181a1c8fcda53812c1aaa56
parentfb88dab4c9c7d89ec7b5842dafdefe93ed939b3c
signaturelock-open Commit is signed but in an unrecognized format.

yet more


3 files changed, 28 insertions(+), 65 deletions(-)

lib/std/Build/Step/CheckObject.zig+6-6
...@@ -1097,7 +1097,7 @@ const MachODumper = struct {...@@ -1097,7 +1097,7 @@ const MachODumper = struct {
10971097
1098 for (ctx.symtab.items) |sym| {1098 for (ctx.symtab.items) |sym| {
1099 const sym_name = ctx.getString(sym.n_strx);1099 const sym_name = ctx.getString(sym.n_strx);
1100 if (sym.stab()) {1100 if (sym.n_type.bits.is_stab != 0) {
1101 const tt = switch (sym.n_type) {1101 const tt = switch (sym.n_type) {
1102 macho.N_SO => "SO",1102 macho.N_SO => "SO",
1103 macho.N_OSO => "OSO",1103 macho.N_OSO => "OSO",
...@@ -1114,7 +1114,7 @@ const MachODumper = struct {...@@ -1114,7 +1114,7 @@ const MachODumper = struct {
1114 try writer.print(" ({s},{s})", .{ sect.segName(), sect.sectName() });1114 try writer.print(" ({s},{s})", .{ sect.segName(), sect.sectName() });
1115 }1115 }
1116 try writer.print(" {s} (stab) {s}\n", .{ tt, sym_name });1116 try writer.print(" {s} (stab) {s}\n", .{ tt, sym_name });
1117 } else if (sym.sect()) {1117 } else if (sym.n_type.type == .sect) {
1118 const sect = ctx.sections.items[sym.n_sect - 1];1118 const sect = ctx.sections.items[sym.n_sect - 1];
1119 try writer.print("{x} ({s},{s})", .{1119 try writer.print("{x} ({s},{s})", .{
1120 sym.n_value,1120 sym.n_value,
...@@ -1122,8 +1122,8 @@ const MachODumper = struct {...@@ -1122,8 +1122,8 @@ const MachODumper = struct {
1122 sect.sectName(),1122 sect.sectName(),
1123 });1123 });
1124 if (sym.n_desc & macho.REFERENCED_DYNAMICALLY != 0) try writer.writeAll(" [referenced dynamically]");1124 if (sym.n_desc & macho.REFERENCED_DYNAMICALLY != 0) try writer.writeAll(" [referenced dynamically]");
1125 if (sym.weakDef()) try writer.writeAll(" weak");1125 if (sym.n_desc.weak_def_or_ref_to_weak) try writer.writeAll(" weak");
1126 if (sym.weakRef()) try writer.writeAll(" weakref");1126 if (sym.n_desc.weak_ref) try writer.writeAll(" weakref");
1127 if (sym.ext()) {1127 if (sym.ext()) {
1128 if (sym.pext()) try writer.writeAll(" private");1128 if (sym.pext()) try writer.writeAll(" private");
1129 try writer.writeAll(" external");1129 try writer.writeAll(" external");
...@@ -1134,7 +1134,7 @@ const MachODumper = struct {...@@ -1134,7 +1134,7 @@ const MachODumper = struct {
1134 try writer.print(" 0x{x:0>16} (common) (alignment 2^{d})", .{ sym.n_value, alignment });1134 try writer.print(" 0x{x:0>16} (common) (alignment 2^{d})", .{ sym.n_value, alignment });
1135 if (sym.ext()) try writer.writeAll(" external");1135 if (sym.ext()) try writer.writeAll(" external");
1136 try writer.print(" {s}\n", .{sym_name});1136 try writer.print(" {s}\n", .{sym_name});
1137 } else if (sym.undf()) {1137 } else if (sym.n_type.type == .undf) {
1138 const ordinal = @divFloor(@as(i16, @bitCast(sym.n_desc)), macho.N_SYMBOL_RESOLVER);1138 const ordinal = @divFloor(@as(i16, @bitCast(sym.n_desc)), macho.N_SYMBOL_RESOLVER);
1139 const import_name = blk: {1139 const import_name = blk: {
1140 if (ordinal <= 0) {1140 if (ordinal <= 0) {
...@@ -1153,7 +1153,7 @@ const MachODumper = struct {...@@ -1153,7 +1153,7 @@ const MachODumper = struct {
1153 break :blk basename[0..ext];1153 break :blk basename[0..ext];
1154 };1154 };
1155 try writer.writeAll("(undefined)");1155 try writer.writeAll("(undefined)");
1156 if (sym.weakRef()) try writer.writeAll(" weakref");1156 if (sym.n_desc.weak_ref) try writer.writeAll(" weakref");
1157 if (sym.ext()) try writer.writeAll(" external");1157 if (sym.ext()) try writer.writeAll(" external");
1158 try writer.print(" {s} (from {s})\n", .{1158 try writer.print(" {s} (from {s})\n", .{
1159 sym_name,1159 sym_name,
lib/std/macho.zig-37
...@@ -906,43 +906,6 @@ pub const nlist_64 = extern struct {...@@ -906,43 +906,6 @@ pub const nlist_64 = extern struct {
906 },906 },
907 n_value: u64,907 n_value: u64,
908908
909 // MLUGG TODO DELETE
910 pub fn stab(sym: nlist_64) bool {
911 return sym.n_type.bits.is_stab != 0;
912 }
913 // MLUGG TODO DELETE
914 pub fn sect(sym: nlist_64) bool {
915 return sym.n_type.type == .sect;
916 }
917 // MLUGG TODO DELETE
918 pub fn undf(sym: nlist_64) bool {
919 return sym.n_type.type == .undf;
920 }
921 // MLUGG TODO DELETE
922 pub fn indr(sym: nlist_64) bool {
923 return sym.n_type.type == .indr;
924 }
925 // MLUGG TODO DELETE
926 pub fn abs(sym: nlist_64) bool {
927 return sym.n_type.type == .abs;
928 }
929 // MLUGG TODO DELETE
930 pub fn weakDef(sym: nlist_64) bool {
931 return sym.n_desc.weak_def_or_ref_to_weak;
932 }
933 // MLUGG TODO DELETE
934 pub fn weakRef(sym: nlist_64) bool {
935 return sym.n_desc.weak_ref;
936 }
937 // MLUGG TODO DELETE
938 pub fn discarded(sym: nlist_64) bool {
939 return sym.n_desc.discarded_or_no_dead_strip;
940 }
941 // MLUGG TODO DELETE
942 pub fn noDeadStrip(sym: nlist_64) bool {
943 return sym.n_desc.discarded_or_no_dead_strip;
944 }
945
946 pub fn tentative(sym: nlist_64) bool {909 pub fn tentative(sym: nlist_64) bool {
947 return sym.n_type.type == .undf and sym.n_value != 0;910 return sym.n_type.type == .undf and sym.n_value != 0;
948 }911 }
src/link/MachO/Object.zig+22-22
...@@ -185,7 +185,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -185,7 +185,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
185 if (name[0] == 'l' or name[0] == 'L') return 4;185 if (name[0] == 'l' or name[0] == 'L') return 4;
186 return 3;186 return 3;
187 }187 }
188 return if (nl.weakDef()) 2 else 1;188 return if (nl.n_desc.weak_def_or_ref_to_weak) 2 else 1;
189 }189 }
190190
191 fn lessThan(ctx: *const Object, lhs: @This(), rhs: @This()) bool {191 fn lessThan(ctx: *const Object, lhs: @This(), rhs: @This()) bool {
...@@ -202,7 +202,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -202,7 +202,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
202 var nlists = try std.array_list.Managed(NlistIdx).initCapacity(gpa, self.symtab.items(.nlist).len);202 var nlists = try std.array_list.Managed(NlistIdx).initCapacity(gpa, self.symtab.items(.nlist).len);
203 defer nlists.deinit();203 defer nlists.deinit();
204 for (self.symtab.items(.nlist), 0..) |nlist, i| {204 for (self.symtab.items(.nlist), 0..) |nlist, i| {
205 if (nlist.stab() or !nlist.sect()) continue;205 if (nlist.n_type.bits.is_stab != 0 or nlist.n_type.type != .sect) continue;
206 nlists.appendAssumeCapacity(.{ .nlist = nlist, .idx = i });206 nlists.appendAssumeCapacity(.{ .nlist = nlist, .idx = i });
207 }207 }
208 mem.sort(NlistIdx, nlists.items, self, NlistIdx.lessThan);208 mem.sort(NlistIdx, nlists.items, self, NlistIdx.lessThan);
...@@ -805,7 +805,7 @@ fn linkNlistToAtom(self: *Object, macho_file: *MachO) !void {...@@ -805,7 +805,7 @@ fn linkNlistToAtom(self: *Object, macho_file: *MachO) !void {
805 const tracy = trace(@src());805 const tracy = trace(@src());
806 defer tracy.end();806 defer tracy.end();
807 for (self.symtab.items(.nlist), self.symtab.items(.atom)) |nlist, *atom| {807 for (self.symtab.items(.nlist), self.symtab.items(.atom)) |nlist, *atom| {
808 if (!nlist.stab() and nlist.sect()) {808 if (!nlist.n_type.bits.is_stab != 0 and nlist.n_type.type == .sect) {
809 const sect = self.sections.items(.header)[nlist.n_sect - 1];809 const sect = self.sections.items(.header)[nlist.n_sect - 1];
810 const subs = self.sections.items(.subsections)[nlist.n_sect - 1].items;810 const subs = self.sections.items(.subsections)[nlist.n_sect - 1].items;
811 if (nlist.n_value == sect.addr) {811 if (nlist.n_value == sect.addr) {
...@@ -852,30 +852,30 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {...@@ -852,30 +852,30 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
852 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});852 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
853853
854 if (self.getAtom(atom_index)) |atom| {854 if (self.getAtom(atom_index)) |atom| {
855 assert(!nlist.abs());855 assert(nlist.n_type.type != .abs);
856 symbol.value -= atom.getInputAddress(macho_file);856 symbol.value -= atom.getInputAddress(macho_file);
857 symbol.atom_ref = .{ .index = atom_index, .file = self.index };857 symbol.atom_ref = .{ .index = atom_index, .file = self.index };
858 }858 }
859859
860 symbol.flags.weak = nlist.weakDef();860 symbol.flags.weak = nlist.n_desc.weak_def_or_ref_to_weak;
861 symbol.flags.abs = nlist.abs();861 symbol.flags.abs = nlist.n_type.type == .abs;
862 symbol.flags.tentative = nlist.tentative();862 symbol.flags.tentative = nlist.tentative();
863 symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();863 symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.n_desc.discarded_or_no_dead_strip;
864 symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;864 symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
865 symbol.flags.interposable = false;865 symbol.flags.interposable = false;
866 // TODO866 // TODO
867 // symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();867 // symbol.flags.interposable = nlist.ext() and (nlist.n_type.type == .sect or nlist.n_type.type == .abs) and macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
868868
869 if (nlist.sect() and869 if (nlist.n_type.type == .sect and
870 self.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)870 self.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
871 {871 {
872 symbol.flags.tlv = true;872 symbol.flags.tlv = true;
873 }873 }
874874
875 if (nlist.ext()) {875 if (nlist.ext()) {
876 if (nlist.undf()) {876 if (nlist.n_type.type == .undf) {
877 symbol.flags.weak_ref = nlist.weakRef();877 symbol.flags.weak_ref = nlist.n_desc.weak_ref;
878 } else if (nlist.pext() or (nlist.weakDef() and nlist.weakRef()) or self.hidden) {878 } else if (nlist.pext() or (nlist.n_desc.weak_def_or_ref_to_weak and nlist.n_desc.weak_ref) or self.hidden) {
879 symbol.visibility = .hidden;879 symbol.visibility = .hidden;
880 } else {880 } else {
881 symbol.visibility = .global;881 symbol.visibility = .global;
...@@ -902,10 +902,10 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -902,10 +902,10 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
902 };902 };
903903
904 const start: u32 = for (self.symtab.items(.nlist), 0..) |nlist, i| {904 const start: u32 = for (self.symtab.items(.nlist), 0..) |nlist, i| {
905 if (nlist.stab()) break @intCast(i);905 if (nlist.n_type.bits.is_stab != 0) break @intCast(i);
906 } else @intCast(self.symtab.items(.nlist).len);906 } else @intCast(self.symtab.items(.nlist).len);
907 const end: u32 = for (self.symtab.items(.nlist)[start..], start..) |nlist, i| {907 const end: u32 = for (self.symtab.items(.nlist)[start..], start..) |nlist, i| {
908 if (!nlist.stab()) break @intCast(i);908 if (nlist.n_type.bits.is_stab == 0) break @intCast(i);
909 } else @intCast(self.symtab.items(.nlist).len);909 } else @intCast(self.symtab.items(.nlist).len);
910910
911 if (start == end) return;911 if (start == end) return;
...@@ -919,7 +919,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -919,7 +919,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
919 var addr_lookup = std.StringHashMap(u64).init(allocator);919 var addr_lookup = std.StringHashMap(u64).init(allocator);
920 defer addr_lookup.deinit();920 defer addr_lookup.deinit();
921 for (syms) |sym| {921 for (syms) |sym| {
922 if (sym.sect() and (sym.ext() or sym.pext())) {922 if (sym.n_type.type == .sect and (sym.ext() or sym.pext())) {
923 try addr_lookup.putNoClobber(self.getNStrx(sym.n_strx), sym.n_value);923 try addr_lookup.putNoClobber(self.getNStrx(sym.n_strx), sym.n_value);
924 }924 }
925 }925 }
...@@ -1241,8 +1241,8 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target....@@ -1241,8 +1241,8 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target.
12411241
1242 const slice = self.symtab.slice();1242 const slice = self.symtab.slice();
1243 for (slice.items(.nlist), slice.items(.atom), slice.items(.size)) |nlist, atom, size| {1243 for (slice.items(.nlist), slice.items(.atom), slice.items(.size)) |nlist, atom, size| {
1244 if (nlist.stab()) continue;1244 if (nlist.n_type.bits.is_stab != 0) continue;
1245 if (!nlist.sect()) continue;1245 if (nlist.n_type.type != .sect) continue;
1246 const sect = self.sections.items(.header)[nlist.n_sect - 1];1246 const sect = self.sections.items(.header)[nlist.n_sect - 1];
1247 if (sect.isCode() and sect.size > 0) {1247 if (sect.isCode() and sect.size > 0) {
1248 try superposition.ensureUnusedCapacity(1);1248 try superposition.ensureUnusedCapacity(1);
...@@ -1459,7 +1459,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {...@@ -1459,7 +1459,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {
14591459
1460 for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {1460 for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {
1461 if (!nlist.ext()) continue;1461 if (!nlist.ext()) continue;
1462 if (nlist.sect()) {1462 if (nlist.n_type.type == .sect) {
1463 const atom = self.getAtom(atom_index).?;1463 const atom = self.getAtom(atom_index).?;
1464 if (!atom.isAlive()) continue;1464 if (!atom.isAlive()) continue;
1465 }1465 }
...@@ -1473,7 +1473,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {...@@ -1473,7 +1473,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {
1473 }1473 }
1474 global.* = gop.index;1474 global.* = gop.index;
14751475
1476 if (nlist.undf() and !nlist.tentative()) continue;1476 if (nlist.n_type.type == .undf and !nlist.tentative()) continue;
1477 if (gop.ref.getFile(macho_file) == null) {1477 if (gop.ref.getFile(macho_file) == null) {
1478 gop.ref.* = .{ .index = @intCast(i), .file = self.index };1478 gop.ref.* = .{ .index = @intCast(i), .file = self.index };
1479 continue;1479 continue;
...@@ -1481,7 +1481,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {...@@ -1481,7 +1481,7 @@ pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {
14811481
1482 if (self.asFile().getSymbolRank(.{1482 if (self.asFile().getSymbolRank(.{
1483 .archive = !self.alive,1483 .archive = !self.alive,
1484 .weak = nlist.weakDef(),1484 .weak = nlist.n_desc.weak_def_or_ref_to_weak,
1485 .tentative = nlist.tentative(),1485 .tentative = nlist.tentative(),
1486 }) < gop.ref.getSymbol(macho_file).?.getSymbolRank(macho_file)) {1486 }) < gop.ref.getSymbol(macho_file).?.getSymbolRank(macho_file)) {
1487 gop.ref.* = .{ .index = @intCast(i), .file = self.index };1487 gop.ref.* = .{ .index = @intCast(i), .file = self.index };
...@@ -1500,7 +1500,7 @@ pub fn markLive(self: *Object, macho_file: *MachO) void {...@@ -1500,7 +1500,7 @@ pub fn markLive(self: *Object, macho_file: *MachO) void {
1500 const ref = self.getSymbolRef(@intCast(i), macho_file);1500 const ref = self.getSymbolRef(@intCast(i), macho_file);
1501 const file = ref.getFile(macho_file) orelse continue;1501 const file = ref.getFile(macho_file) orelse continue;
1502 const sym = ref.getSymbol(macho_file).?;1502 const sym = ref.getSymbol(macho_file).?;
1503 const should_keep = nlist.undf() or (nlist.tentative() and !sym.flags.tentative);1503 const should_keep = nlist.n_type.type == .undf or (nlist.tentative() and !sym.flags.tentative);
1504 if (should_keep and file == .object and !file.object.alive) {1504 if (should_keep and file == .object and !file.object.alive) {
1505 file.object.alive = true;1505 file.object.alive = true;
1506 file.object.markLive(macho_file);1506 file.object.markLive(macho_file);
...@@ -1685,7 +1685,7 @@ pub fn parseAr(self: *Object, macho_file: *MachO) !void {...@@ -1685,7 +1685,7 @@ pub fn parseAr(self: *Object, macho_file: *MachO) !void {
1685pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {1685pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {
1686 const gpa = macho_file.base.comp.gpa;1686 const gpa = macho_file.base.comp.gpa;
1687 for (self.symtab.items(.nlist)) |nlist| {1687 for (self.symtab.items(.nlist)) |nlist| {
1688 if (!nlist.ext() or (nlist.undf() and !nlist.tentative())) continue;1688 if (!nlist.ext() or (nlist.n_type.type == .undf and !nlist.tentative())) continue;
1689 const off = try ar_symtab.strtab.insert(gpa, self.getNStrx(nlist.n_strx));1689 const off = try ar_symtab.strtab.insert(gpa, self.getNStrx(nlist.n_strx));
1690 try ar_symtab.entries.append(gpa, .{ .off = off, .file = self.index });1690 try ar_symtab.entries.append(gpa, .{ .off = off, .file = self.index });
1691 }1691 }