@@ -522,42 +522,39 @@ int64_t RelocationScanner::computeMipsAddend(const RelTy &rel, RelExpr expr,
522
522
523
523
// Custom error message if Sym is defined in a discarded section.
524
524
template <class ELFT >
525
- static std::string maybeReportDiscarded (Ctx &ctx, Undefined &sym) {
525
+ static void maybeReportDiscarded (Ctx &ctx, ELFSyncStream &msg , Undefined &sym) {
526
526
auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file );
527
527
if (!file || !sym.discardedSecIdx )
528
- return " " ;
528
+ return ;
529
529
ArrayRef<typename ELFT::Shdr> objSections =
530
530
file->template getELFShdrs <ELFT>();
531
531
532
- std::string msg;
533
532
if (sym.type == ELF::STT_SECTION) {
534
- msg = " relocation refers to a discarded section: " ;
535
- msg += CHECK2 (
533
+ msg << " relocation refers to a discarded section: " ;
534
+ msg << CHECK2 (
536
535
file->getObj ().getSectionName (objSections[sym.discardedSecIdx ]), file);
537
536
} else {
538
- msg = " relocation refers to a symbol in a discarded section: " +
539
- toStr (ctx, sym);
537
+ msg << " relocation refers to a symbol in a discarded section: " << &sym;
540
538
}
541
- msg += " \n >>> defined in " + toStr (ctx, file) ;
539
+ msg << " \n >>> defined in " << file;
542
540
543
541
Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1 ];
544
542
if (elfSec.sh_type != SHT_GROUP)
545
- return msg ;
543
+ return ;
546
544
547
545
// If the discarded section is a COMDAT.
548
546
StringRef signature = file->getShtGroupSignature (objSections, elfSec);
549
547
if (const InputFile *prevailing =
550
548
ctx.symtab ->comdatGroups .lookup (CachedHashStringRef (signature))) {
551
- msg += " \n >>> section group signature: " + signature. str () +
552
- " \n >>> prevailing definition is in " + toStr (ctx, prevailing) ;
549
+ msg << " \n >>> section group signature: "
550
+ << signature. str () + " \n >>> prevailing definition is in " << prevailing;
553
551
if (sym.nonPrevailing ) {
554
- msg += " \n >>> or the symbol in the prevailing group had STB_WEAK "
552
+ msg << " \n >>> or the symbol in the prevailing group had STB_WEAK "
555
553
" binding and the symbol in a non-prevailing group had STB_GLOBAL "
556
554
" binding. Mixing groups with STB_WEAK and STB_GLOBAL binding "
557
555
" signature is not supported" ;
558
556
}
559
557
}
560
- return msg;
561
558
}
562
559
563
560
// Check whether the definition name def is a mangled function name that matches
@@ -695,8 +692,9 @@ static const Symbol *getAlternativeSpelling(Ctx &ctx, const Undefined &sym,
695
692
static void reportUndefinedSymbol (Ctx &ctx, const UndefinedDiag &undef,
696
693
bool correctSpelling) {
697
694
Undefined &sym = *undef.sym ;
695
+ ELFSyncStream msg (ctx, DiagLevel::None);
698
696
699
- auto visibility = [&]() -> std::string {
697
+ auto visibility = [&]() {
700
698
switch (sym.visibility ()) {
701
699
case STV_INTERNAL:
702
700
return " internal " ;
@@ -709,75 +707,70 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
709
707
}
710
708
};
711
709
712
- std::string msg;
713
710
switch (ctx.arg .ekind ) {
714
711
case ELF32LEKind:
715
- msg = maybeReportDiscarded<ELF32LE>(ctx, sym);
712
+ maybeReportDiscarded<ELF32LE>(ctx, msg , sym);
716
713
break ;
717
714
case ELF32BEKind:
718
- msg = maybeReportDiscarded<ELF32BE>(ctx, sym);
715
+ maybeReportDiscarded<ELF32BE>(ctx, msg , sym);
719
716
break ;
720
717
case ELF64LEKind:
721
- msg = maybeReportDiscarded<ELF64LE>(ctx, sym);
718
+ maybeReportDiscarded<ELF64LE>(ctx, msg , sym);
722
719
break ;
723
720
case ELF64BEKind:
724
- msg = maybeReportDiscarded<ELF64BE>(ctx, sym);
721
+ maybeReportDiscarded<ELF64BE>(ctx, msg , sym);
725
722
break ;
726
723
default :
727
724
llvm_unreachable (" " );
728
725
}
729
- if (msg.empty ())
730
- msg = " undefined " + visibility () + " symbol: " + toStr (ctx, sym) ;
726
+ if (msg.str (). empty ())
727
+ msg << " undefined " << visibility () << " symbol: " << & sym;
731
728
732
729
const size_t maxUndefReferences = 3 ;
733
- size_t i = 0 ;
734
- for (UndefinedDiag::Loc l : undef.locs ) {
735
- if (i >= maxUndefReferences)
736
- break ;
730
+ for (UndefinedDiag::Loc l :
731
+ ArrayRef (undef.locs ).take_front (maxUndefReferences)) {
737
732
InputSectionBase &sec = *l.sec ;
738
733
uint64_t offset = l.offset ;
739
734
740
- msg += " \n >>> referenced by " ;
735
+ msg << " \n >>> referenced by " ;
741
736
// In the absence of line number information, utilize DW_TAG_variable (if
742
737
// present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).
743
738
Symbol *enclosing = sec.getEnclosingSymbol (offset);
744
739
std::string src = sec.getSrcMsg (enclosing ? *enclosing : sym, offset);
745
740
if (!src.empty ())
746
- msg += src + " \n >>> " ;
747
- msg += sec.getObjMsg (offset);
748
- i++;
741
+ msg << src << " \n >>> " ;
742
+ msg << sec.getObjMsg (offset);
749
743
}
750
744
751
- if (i < undef.locs .size ())
752
- msg += ( " \n >>> referenced " + Twine (undef.locs .size () - i) + " more times " )
753
- . str () ;
745
+ if (maxUndefReferences < undef.locs .size ())
746
+ msg << " \n >>> referenced " << (undef.locs .size () - maxUndefReferences )
747
+ << " more times " ;
754
748
755
749
if (correctSpelling) {
756
750
std::string pre_hint = " : " , post_hint;
757
751
if (const Symbol *corrected =
758
752
getAlternativeSpelling (ctx, sym, pre_hint, post_hint)) {
759
- msg +=
760
- " \n >>> did you mean" + pre_hint + toStr (ctx, *corrected) + post_hint;
753
+ msg << " \n >>> did you mean" << pre_hint << corrected << post_hint;
761
754
if (corrected->file )
762
- msg += " \n >>> defined in: " + toStr (ctx, corrected->file ) ;
755
+ msg << " \n >>> defined in: " << corrected->file ;
763
756
}
764
757
}
765
758
766
759
if (sym.getName ().starts_with (" _ZTV" ))
767
- msg +=
768
- " \n >>> the vtable symbol may be undefined because the class is missing "
769
- " its key function (see https://lld.llvm.org/missingkeyfunction)" ;
760
+ msg << " \n >>> the vtable symbol may be undefined because the class is "
761
+ " missing its key function "
762
+ " (see https://lld.llvm.org/missingkeyfunction)" ;
770
763
if (ctx.arg .gcSections && ctx.arg .zStartStopGC &&
771
764
sym.getName ().starts_with (" __start_" )) {
772
- msg += " \n >>> the encapsulation symbol needs to be retained under "
765
+ msg << " \n >>> the encapsulation symbol needs to be retained under "
773
766
" --gc-sections properly; consider -z nostart-stop-gc "
774
767
" (see https://lld.llvm.org/ELF/start-stop-gc)" ;
775
768
}
776
769
777
770
if (undef.isWarning )
778
- Warn (ctx) << msg;
771
+ Warn (ctx) << msg. str () ;
779
772
else
780
- ctx.e .error (msg, ErrorTag::SymbolNotFound, {sym.getName ()});
773
+ ctx.e .error (msg. str () , ErrorTag::SymbolNotFound, {sym.getName ()});
781
774
}
782
775
783
776
void elf::reportUndefinedSymbols (Ctx &ctx) {
0 commit comments