@@ -302,50 +302,78 @@ static void handleSegmentBoundarySymbol(const Undefined &sym, StringRef segName,
302
302
seg->segmentEndSymbols .push_back (createBoundarySymbol (sym));
303
303
}
304
304
305
- void lld::macho::treatUndefinedSymbol (const Undefined &sym, StringRef source) {
305
+ // Try to find a definition for an undefined symbol.
306
+ // Returns true if a definition was found and no diagnostics are needed.
307
+ static bool recoverFromUndefinedSymbol (const Undefined &sym) {
306
308
// Handle start/end symbols.
307
309
StringRef name = sym.getName ();
308
- if (name.consume_front (" section$start$" ))
309
- return handleSectionBoundarySymbol (sym, name, Boundary::Start);
310
- if (name.consume_front (" section$end$" ))
311
- return handleSectionBoundarySymbol (sym, name, Boundary::End);
312
- if (name.consume_front (" segment$start$" ))
313
- return handleSegmentBoundarySymbol (sym, name, Boundary::Start);
314
- if (name.consume_front (" segment$end$" ))
315
- return handleSegmentBoundarySymbol (sym, name, Boundary::End);
310
+ if (name.consume_front (" section$start$" )) {
311
+ handleSectionBoundarySymbol (sym, name, Boundary::Start);
312
+ return true ;
313
+ }
314
+ if (name.consume_front (" section$end$" )) {
315
+ handleSectionBoundarySymbol (sym, name, Boundary::End);
316
+ return true ;
317
+ }
318
+ if (name.consume_front (" segment$start$" )) {
319
+ handleSegmentBoundarySymbol (sym, name, Boundary::Start);
320
+ return true ;
321
+ }
322
+ if (name.consume_front (" segment$end$" )) {
323
+ handleSegmentBoundarySymbol (sym, name, Boundary::End);
324
+ return true ;
325
+ }
316
326
317
327
// Handle -U.
318
328
if (config->explicitDynamicLookups .count (sym.getName ())) {
319
329
symtab->addDynamicLookup (sym.getName ());
320
- return ;
330
+ return true ;
321
331
}
322
332
323
333
// Handle -undefined.
324
- auto message = [source, &sym]() {
325
- std::string message = " undefined symbol" ;
326
- if (config->archMultiple )
327
- message += (" for arch " + getArchitectureName (config->arch ())).str ();
328
- message += " : " + toString (sym);
329
- if (!source.empty ())
330
- message += " \n >>> referenced by " + source.str ();
331
- else
332
- message += " \n >>> referenced by " + toString (sym.getFile ());
333
- return message;
334
- };
335
- switch (config->undefinedSymbolTreatment ) {
336
- case UndefinedSymbolTreatment::error:
337
- error (message ());
338
- break ;
339
- case UndefinedSymbolTreatment::warning:
340
- warn (message ());
341
- LLVM_FALLTHROUGH;
342
- case UndefinedSymbolTreatment::dynamic_lookup:
343
- case UndefinedSymbolTreatment::suppress:
334
+ if (config->undefinedSymbolTreatment ==
335
+ UndefinedSymbolTreatment::dynamic_lookup ||
336
+ config->undefinedSymbolTreatment == UndefinedSymbolTreatment::suppress) {
344
337
symtab->addDynamicLookup (sym.getName ());
345
- break ;
346
- case UndefinedSymbolTreatment::unknown:
347
- llvm_unreachable (" unknown -undefined TREATMENT" );
338
+ return true ;
348
339
}
340
+
341
+ // We do not return true here, as we still need to print diagnostics.
342
+ if (config->undefinedSymbolTreatment == UndefinedSymbolTreatment::warning)
343
+ symtab->addDynamicLookup (sym.getName ());
344
+
345
+ return false ;
346
+ }
347
+
348
+ static void printUndefinedDiagnostic (StringRef name, StringRef source) {
349
+ std::string message = " undefined symbol" ;
350
+ if (config->archMultiple )
351
+ message += (" for arch " + getArchitectureName (config->arch ())).str ();
352
+ message += (" : " + name + " \n >>> referenced by " + source).str ();
353
+
354
+ if (config->undefinedSymbolTreatment == UndefinedSymbolTreatment::error)
355
+ error (message);
356
+ else if (config->undefinedSymbolTreatment ==
357
+ UndefinedSymbolTreatment::warning)
358
+ warn (message);
359
+ else
360
+ assert (false && " diagnostics make sense for -undefined error|warning only" );
361
+ }
362
+
363
+ void lld::macho::treatUndefinedSymbol (const Undefined &sym, StringRef source) {
364
+ if (recoverFromUndefinedSymbol (sym))
365
+ return ;
366
+ printUndefinedDiagnostic (sym.getName (), source);
367
+ }
368
+
369
+ void lld::macho::treatUndefinedSymbol (const Undefined &sym,
370
+ const InputSection *isec,
371
+ uint64_t offset) {
372
+ if (recoverFromUndefinedSymbol (sym))
373
+ return ;
374
+
375
+ // TODO: Get source file/line from debug information.
376
+ printUndefinedDiagnostic (toString (sym), isec->getLocation (offset));
349
377
}
350
378
351
379
std::unique_ptr<SymbolTable> macho::symtab;
0 commit comments