@@ -24,7 +24,7 @@ resolver: SymbolResolver = .{},
24
24
25
25
/// This table will be populated after `scanRelocs` has run.
26
26
/// Key is symbol index.
27
- undefs : std .AutoArrayHashMapUnmanaged (SymbolResolver.Index , std . ArrayListUnmanaged ( Ref ) ) = .{},
27
+ undefs : std .AutoArrayHashMapUnmanaged (SymbolResolver.Index , UndefRefs ) = .{},
28
28
undefs_mutex : std.Thread.Mutex = .{},
29
29
30
30
dupes : std .AutoArrayHashMapUnmanaged (SymbolResolver.Index , std .ArrayListUnmanaged (File .Index )) = .{},
@@ -1227,6 +1227,9 @@ fn scanRelocs(self: *MachO) !void {
1227
1227
1228
1228
if (self .has_errors .swap (false , .seq_cst )) return error .FlushFailed ;
1229
1229
1230
+ if (self .getInternalObject ()) | obj | {
1231
+ try obj .checkUndefs (self );
1232
+ }
1230
1233
try self .reportUndefs ();
1231
1234
1232
1235
for (self .objects .items ) | index | {
@@ -1292,29 +1295,43 @@ fn reportUndefs(self: *MachO) !void {
1292
1295
}
1293
1296
}.lessThan ;
1294
1297
1295
- for (self .undefs .values ()) | * refs | {
1296
- mem .sort (Ref , refs .items , {}, refLessThan );
1297
- }
1298
+ for (self .undefs .values ()) | * undefs | switch (undefs .* ) {
1299
+ .refs = > | refs | mem .sort (Ref , refs .items , {}, refLessThan ),
1300
+ else = > {},
1301
+ };
1298
1302
1299
1303
for (keys .items ) | key | {
1300
1304
const undef_sym = self .resolver .keys .items [key - 1 ];
1301
1305
const notes = self .undefs .get (key ).? ;
1302
- const nnotes = @min (notes .items .len , max_notes ) + @intFromBool (notes .items .len > max_notes );
1306
+ const nnotes = nnotes : {
1307
+ const nnotes = switch (notes ) {
1308
+ .refs = > | refs | refs .items .len ,
1309
+ else = > 1 ,
1310
+ };
1311
+ break :nnotes @min (nnotes , max_notes ) + @intFromBool (nnotes > max_notes );
1312
+ };
1303
1313
1304
1314
const err = try addFn (& self .base , nnotes );
1305
1315
try err .addMsg ("undefined symbol: {s}" , .{undef_sym .getName (self )});
1306
1316
1307
- var inote : usize = 0 ;
1308
- while (inote < @min (notes .items .len , max_notes )) : (inote += 1 ) {
1309
- const note = notes .items [inote ];
1310
- const file = self .getFile (note .file ).? ;
1311
- const atom = note .getAtom (self ).? ;
1312
- try err .addNote ("referenced by {}:{s}" , .{ file .fmtPath (), atom .getName (self ) });
1313
- }
1317
+ switch (notes ) {
1318
+ .force_undefined = > try err .addNote ("referenced with linker flag -u" , .{}),
1319
+ .entry = > try err .addNote ("referenced with linker flag -e" , .{}),
1320
+ .dyld_stub_binder , .objc_msgsend = > try err .addNote ("referenced implicitly" , .{}),
1321
+ .refs = > | refs | {
1322
+ var inote : usize = 0 ;
1323
+ while (inote < @min (refs .items .len , max_notes )) : (inote += 1 ) {
1324
+ const ref = refs .items [inote ];
1325
+ const file = self .getFile (ref .file ).? ;
1326
+ const atom = ref .getAtom (self ).? ;
1327
+ try err .addNote ("referenced by {}:{s}" , .{ file .fmtPath (), atom .getName (self ) });
1328
+ }
1314
1329
1315
- if (notes .items .len > max_notes ) {
1316
- const remaining = notes .items .len - max_notes ;
1317
- try err .addNote ("referenced {d} more times" , .{remaining });
1330
+ if (refs .items .len > max_notes ) {
1331
+ const remaining = refs .items .len - max_notes ;
1332
+ try err .addNote ("referenced {d} more times" , .{remaining });
1333
+ }
1334
+ },
1318
1335
}
1319
1336
}
1320
1337
return error .UndefinedSymbols ;
@@ -3283,6 +3300,18 @@ pub const SymbolResolver = struct {
3283
3300
pub const Index = u32 ;
3284
3301
};
3285
3302
3303
+ pub const UndefRefs = union (enum ) {
3304
+ force_undefined ,
3305
+ entry ,
3306
+ dyld_stub_binder ,
3307
+ objc_msgsend ,
3308
+ refs : std .ArrayListUnmanaged (Ref ),
3309
+
3310
+ pub fn deinit (self : * UndefRefs , allocator : Allocator ) void {
3311
+ self .refs .deinit (allocator );
3312
+ }
3313
+ };
3314
+
3286
3315
pub const String = struct {
3287
3316
pos : u32 = 0 ,
3288
3317
len : u32 = 0 ,
0 commit comments