authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-11-30 13:59:33+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-11-30 13:59:33+01:00
log86fe47235eafc03ee4808f8c8b34b7903b816023
treeaff3e2796aab4c01c2bc6d7871e21289c38cb6e4
parent2873e19366400b2f11d3a99b10ea17e4f06c6b4b

macho: move nlist_64 type/flags helpers to std.macho


5 files changed, 70 insertions(+), 72 deletions(-)

lib/std/macho.zig+49
......@@ -744,6 +744,55 @@ pub const nlist_64 = extern struct {
744744 n_sect: u8,
745745 n_desc: u16,
746746 n_value: u64,
747
748 pub fn stab(sym: nlist_64) bool {
749 return (N_STAB & sym.n_type) != 0;
750 }
751
752 pub fn pext(sym: nlist_64) bool {
753 return (N_PEXT & sym.n_type) != 0;
754 }
755
756 pub fn ext(sym: nlist_64) bool {
757 return (N_EXT & sym.n_type) != 0;
758 }
759
760 pub fn sect(sym: nlist_64) bool {
761 const type_ = N_TYPE & sym.n_type;
762 return type_ == N_SECT;
763 }
764
765 pub fn undf(sym: nlist_64) bool {
766 const type_ = N_TYPE & sym.n_type;
767 return type_ == N_UNDF;
768 }
769
770 pub fn indr(sym: nlist_64) bool {
771 const type_ = N_TYPE & sym.n_type;
772 return type_ == N_INDR;
773 }
774
775 pub fn abs(sym: nlist_64) bool {
776 const type_ = N_TYPE & sym.n_type;
777 return type_ == N_ABS;
778 }
779
780 pub fn weakDef(sym: nlist_64) bool {
781 return (sym.n_desc & N_WEAK_DEF) != 0;
782 }
783
784 pub fn weakRef(sym: nlist_64) bool {
785 return (sym.n_desc & N_WEAK_REF) != 0;
786 }
787
788 pub fn discarded(sym: nlist_64) bool {
789 return (sym.n_desc & N_DESC_DISCARDED) != 0;
790 }
791
792 pub fn tentative(sym: nlist_64) bool {
793 if (!sym.undf()) return false;
794 return sym.n_value != 0;
795 }
747796};
748797
749798/// Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD
src/link/MachO.zig+15-66
......@@ -885,7 +885,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
885885 const sym_name = self.getString(sym.n_strx);
886886 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
887887
888 if (symbolIsDiscarded(sym.*)) {
888 if (sym.discarded()) {
889889 sym.* = .{
890890 .n_strx = 0,
891891 .n_type = macho.N_UNDF,
......@@ -2445,21 +2445,21 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24452445 const sym_id = @intCast(u32, id);
24462446 const sym_name = object.getString(sym.n_strx);
24472447
2448 if (symbolIsStab(sym)) {
2448 if (sym.stab()) {
24492449 log.err("unhandled symbol type: stab", .{});
24502450 log.err(" symbol '{s}'", .{sym_name});
24512451 log.err(" first definition in '{s}'", .{object.name});
24522452 return error.UnhandledSymbolType;
24532453 }
24542454
2455 if (symbolIsIndr(sym)) {
2455 if (sym.indr()) {
24562456 log.err("unhandled symbol type: indirect", .{});
24572457 log.err(" symbol '{s}'", .{sym_name});
24582458 log.err(" first definition in '{s}'", .{object.name});
24592459 return error.UnhandledSymbolType;
24602460 }
24612461
2462 if (symbolIsAbs(sym)) {
2462 if (sym.abs()) {
24632463 log.err("unhandled symbol type: absolute", .{});
24642464 log.err(" symbol '{s}'", .{sym_name});
24652465 log.err(" first definition in '{s}'", .{object.name});
......@@ -2467,7 +2467,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24672467 }
24682468
24692469 const n_strx = try self.makeString(sym_name);
2470 if (symbolIsSect(sym)) {
2470 if (sym.sect()) {
24712471 // Defined symbol regardless of scope lands in the locals symbol table.
24722472 const local_sym_index = @intCast(u32, self.locals.items.len);
24732473 try self.locals.append(self.base.allocator, .{
......@@ -2482,7 +2482,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24822482
24832483 // If the symbol's scope is not local aka translation unit, then we need work out
24842484 // if we should save the symbol as a global, or potentially flag the error.
2485 if (!symbolIsExt(sym)) continue;
2485 if (!sym.ext()) continue;
24862486
24872487 const local = self.locals.items[local_sym_index];
24882488 const resolv = self.symbol_resolver.getPtr(n_strx) orelse {
......@@ -2507,18 +2507,16 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
25072507 .global => {
25082508 const global = &self.globals.items[resolv.where_index];
25092509
2510 if (symbolIsTentative(global.*)) {
2510 if (global.tentative()) {
25112511 assert(self.tentatives.swapRemove(resolv.where_index));
2512 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and
2513 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
2514 {
2512 } else if (!(sym.weakDef() or sym.pext()) and !(global.weakDef() or global.pext())) {
25152513 log.err("symbol '{s}' defined multiple times", .{sym_name});
25162514 if (resolv.file) |file| {
25172515 log.err(" first definition in '{s}'", .{self.objects.items[file].name});
25182516 }
25192517 log.err(" next definition in '{s}'", .{object.name});
25202518 return error.MultipleSymbolDefinitions;
2521 } else if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it.
2519 } else if (sym.weakDef() or sym.pext()) continue; // Current symbol is weak, so skip it.
25222520
25232521 // Otherwise, update the resolver and the global symbol.
25242522 global.n_type = sym.n_type;
......@@ -2554,7 +2552,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
25542552 .local_sym_index = local_sym_index,
25552553 .file = object_id,
25562554 };
2557 } else if (symbolIsTentative(sym)) {
2555 } else if (sym.tentative()) {
25582556 // Symbol is a tentative definition.
25592557 const resolv = self.symbol_resolver.getPtr(n_strx) orelse {
25602558 const global_sym_index = @intCast(u32, self.globals.items.len);
......@@ -2577,7 +2575,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
25772575 switch (resolv.where) {
25782576 .global => {
25792577 const global = &self.globals.items[resolv.where_index];
2580 if (!symbolIsTentative(global.*)) continue;
2578 if (!global.tentative()) continue;
25812579 if (global.n_value >= sym.n_value) continue;
25822580
25832581 global.n_desc = sym.n_desc;
......@@ -3575,9 +3573,9 @@ pub fn updateDeclExports(
35753573
35763574 const sym = &self.globals.items[resolv.where_index];
35773575
3578 if (symbolIsTentative(sym.*)) {
3576 if (sym.tentative()) {
35793577 assert(self.tentatives.swapRemove(resolv.where_index));
3580 } else if (!is_weak and !(symbolIsWeakDef(sym.*) or symbolIsPext(sym.*))) {
3578 } else if (!is_weak and !(sym.weakDef() or sym.pext())) {
35813579 _ = try module.failed_exports.put(
35823580 module.gpa,
35833581 exp,
......@@ -5316,58 +5314,9 @@ pub fn getString(self: *MachO, off: u32) []const u8 {
53165314 return mem.sliceTo(@ptrCast([*:0]const u8, self.strtab.items.ptr + off), 0);
53175315}
53185316
5319pub fn symbolIsStab(sym: macho.nlist_64) bool {
5320 return (macho.N_STAB & sym.n_type) != 0;
5321}
5322
5323pub fn symbolIsPext(sym: macho.nlist_64) bool {
5324 return (macho.N_PEXT & sym.n_type) != 0;
5325}
5326
5327pub fn symbolIsExt(sym: macho.nlist_64) bool {
5328 return (macho.N_EXT & sym.n_type) != 0;
5329}
5330
5331pub fn symbolIsSect(sym: macho.nlist_64) bool {
5332 const type_ = macho.N_TYPE & sym.n_type;
5333 return type_ == macho.N_SECT;
5334}
5335
5336pub fn symbolIsUndf(sym: macho.nlist_64) bool {
5337 const type_ = macho.N_TYPE & sym.n_type;
5338 return type_ == macho.N_UNDF;
5339}
5340
5341pub fn symbolIsIndr(sym: macho.nlist_64) bool {
5342 const type_ = macho.N_TYPE & sym.n_type;
5343 return type_ == macho.N_INDR;
5344}
5345
5346pub fn symbolIsAbs(sym: macho.nlist_64) bool {
5347 const type_ = macho.N_TYPE & sym.n_type;
5348 return type_ == macho.N_ABS;
5349}
5350
5351pub fn symbolIsWeakDef(sym: macho.nlist_64) bool {
5352 return (sym.n_desc & macho.N_WEAK_DEF) != 0;
5353}
5354
5355pub fn symbolIsWeakRef(sym: macho.nlist_64) bool {
5356 return (sym.n_desc & macho.N_WEAK_REF) != 0;
5357}
5358
5359pub fn symbolIsDiscarded(sym: macho.nlist_64) bool {
5360 return (sym.n_desc & macho.N_DESC_DISCARDED) != 0;
5361}
5362
5363pub fn symbolIsTentative(sym: macho.nlist_64) bool {
5364 if (!symbolIsUndf(sym)) return false;
5365 return sym.n_value != 0;
5366}
5367
53685317pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool {
5369 if (!symbolIsSect(sym)) return false;
5370 if (symbolIsExt(sym)) return false;
5318 if (!sym.sect()) return false;
5319 if (sym.ext()) return false;
53715320 return mem.startsWith(u8, sym_name, "l") or mem.startsWith(u8, sym_name, "L");
53725321}
53735322
src/link/MachO/Atom.zig+2-2
......@@ -295,7 +295,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC
295295
296296 assert(subtractor == null);
297297 const sym = context.object.symtab.items[rel.r_symbolnum];
298 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
298 if (sym.sect() and !sym.ext()) {
299299 subtractor = context.object.symbol_mapping.get(rel.r_symbolnum).?;
300300 } else {
301301 const sym_name = context.object.getString(sym.n_strx);
......@@ -362,7 +362,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC
362362 const sym = context.object.symtab.items[rel.r_symbolnum];
363363 const sym_name = context.object.getString(sym.n_strx);
364364
365 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
365 if (sym.sect() and !sym.ext()) {
366366 const sym_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
367367 break :target Relocation.Target{ .local = sym_index };
368368 }
src/link/MachO/Dylib.zig+1-1
......@@ -226,7 +226,7 @@ fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {
226226 _ = try self.file.preadAll(strtab, symtab_cmd.stroff + self.library_offset);
227227
228228 for (slice) |sym| {
229 const add_to_symtab = MachO.symbolIsExt(sym) and (MachO.symbolIsSect(sym) or MachO.symbolIsIndr(sym));
229 const add_to_symtab = sym.ext() and (sym.sect() or sym.indr());
230230
231231 if (!add_to_symtab) continue;
232232
src/link/MachO/Object.zig+3-3
......@@ -338,8 +338,8 @@ const NlistWithIndex = struct {
338338 // afterwards by address in each group. Normally, dysymtab should
339339 // be enough to guarantee the sort, but turns out not every compiler
340340 // is kind enough to specify the symbols in the correct order.
341 if (MachO.symbolIsSect(lhs.nlist)) {
342 if (MachO.symbolIsSect(rhs.nlist)) {
341 if (lhs.nlist.sect()) {
342 if (rhs.nlist.sect()) {
343343 // Same group, sort by address.
344344 return lhs.nlist.n_value < rhs.nlist.n_value;
345345 } else {
......@@ -414,7 +414,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: *Allocator, macho_file: *MachO)
414414 var iundefsym: usize = sorted_all_nlists.items.len;
415415 while (iundefsym > 0) : (iundefsym -= 1) {
416416 const nlist = sorted_all_nlists.items[iundefsym];
417 if (MachO.symbolIsSect(nlist.nlist)) break;
417 if (nlist.nlist.sect()) break;
418418 }
419419 break :blk iundefsym;
420420 };