authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-11-29 21:05:19+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-11-30 10:22:26+01:00
log2873e19366400b2f11d3a99b10ea17e4f06c6b4b
treed3fd3f94f256a886713570f25c8fdff41cf3c75a
parent692c254336da71cbe21aaf9fbc21240fd1269b95

macho: ignore undefined symbols marked for discarding

If a symbol is undefined after we tried resolving it in static and dynamic libraries, and it is annotated with N_DESC_DISCARDED flag, we simply ignore it rather than flagging an undefined symbol error.

1 files changed, 29 insertions(+), 8 deletions(-)

src/link/MachO.zig+29-8
...@@ -878,14 +878,31 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -878,14 +878,31 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
878 try self.createDsoHandleAtom();878 try self.createDsoHandleAtom();
879 try self.addCodeSignatureLC();879 try self.addCodeSignatureLC();
880880
881 for (self.unresolved.keys()) |index| {881 {
882 const sym = self.undefs.items[index];882 var next_sym: usize = 0;
883 const sym_name = self.getString(sym.n_strx);883 while (next_sym < self.unresolved.count()) {
884 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;884 const sym = &self.undefs.items[self.unresolved.keys()[next_sym]];
885 const sym_name = self.getString(sym.n_strx);
886 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
887
888 if (symbolIsDiscarded(sym.*)) {
889 sym.* = .{
890 .n_strx = 0,
891 .n_type = macho.N_UNDF,
892 .n_sect = 0,
893 .n_desc = 0,
894 .n_value = 0,
895 };
896 _ = self.unresolved.swapRemove(resolv.where_index);
897 continue;
898 }
899
900 log.err("undefined reference to symbol '{s}'", .{sym_name});
901 if (resolv.file) |file| {
902 log.err(" first referenced in '{s}'", .{self.objects.items[file].name});
903 }
885904
886 log.err("undefined reference to symbol '{s}'", .{sym_name});905 next_sym += 1;
887 if (resolv.file) |file| {
888 log.err(" first referenced in '{s}'", .{self.objects.items[file].name});
889 }906 }
890 }907 }
891 if (self.unresolved.count() > 0) {908 if (self.unresolved.count() > 0) {
...@@ -2603,7 +2620,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2603,7 +2620,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2603 .n_strx = try self.makeString(sym_name),2620 .n_strx = try self.makeString(sym_name),
2604 .n_type = macho.N_UNDF,2621 .n_type = macho.N_UNDF,
2605 .n_sect = 0,2622 .n_sect = 0,
2606 .n_desc = 0,2623 .n_desc = sym.n_desc,
2607 .n_value = 0,2624 .n_value = 0,
2608 });2625 });
2609 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{2626 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
...@@ -5339,6 +5356,10 @@ pub fn symbolIsWeakRef(sym: macho.nlist_64) bool {...@@ -5339,6 +5356,10 @@ pub fn symbolIsWeakRef(sym: macho.nlist_64) bool {
5339 return (sym.n_desc & macho.N_WEAK_REF) != 0;5356 return (sym.n_desc & macho.N_WEAK_REF) != 0;
5340}5357}
53415358
5359pub fn symbolIsDiscarded(sym: macho.nlist_64) bool {
5360 return (sym.n_desc & macho.N_DESC_DISCARDED) != 0;
5361}
5362
5342pub fn symbolIsTentative(sym: macho.nlist_64) bool {5363pub fn symbolIsTentative(sym: macho.nlist_64) bool {
5343 if (!symbolIsUndf(sym)) return false;5364 if (!symbolIsUndf(sym)) return false;
5344 return sym.n_value != 0;5365 return sym.n_value != 0;