@@ -522,42 +522,39 @@ int64_t RelocationScanner::computeMipsAddend(const RelTy &rel, RelExpr expr,
522522
523523// Custom error message if Sym is defined in a discarded section.
524524template <class ELFT >
525- static std::string maybeReportDiscarded (Ctx &ctx, Undefined &sym) {
525+ static void maybeReportDiscarded (Ctx &ctx, ELFSyncStream &msg , Undefined &sym) {
526526 auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file );
527527 if (!file || !sym.discardedSecIdx )
528- return " " ;
528+ return ;
529529 ArrayRef<typename ELFT::Shdr> objSections =
530530 file->template getELFShdrs <ELFT>();
531531
532- std::string msg;
533532 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 (
536535 file->getObj ().getSectionName (objSections[sym.discardedSecIdx ]), file);
537536 } 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;
540538 }
541- msg += " \n >>> defined in " + toStr (ctx, file) ;
539+ msg << " \n >>> defined in " << file;
542540
543541 Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1 ];
544542 if (elfSec.sh_type != SHT_GROUP)
545- return msg ;
543+ return ;
546544
547545 // If the discarded section is a COMDAT.
548546 StringRef signature = file->getShtGroupSignature (objSections, elfSec);
549547 if (const InputFile *prevailing =
550548 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;
553551 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 "
555553 " binding and the symbol in a non-prevailing group had STB_GLOBAL "
556554 " binding. Mixing groups with STB_WEAK and STB_GLOBAL binding "
557555 " signature is not supported" ;
558556 }
559557 }
560- return msg;
561558}
562559
563560// 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,
695692static void reportUndefinedSymbol (Ctx &ctx, const UndefinedDiag &undef,
696693 bool correctSpelling) {
697694 Undefined &sym = *undef.sym ;
695+ ELFSyncStream msg (ctx, DiagLevel::None);
698696
699- auto visibility = [&]() -> std::string {
697+ auto visibility = [&]() {
700698 switch (sym.visibility ()) {
701699 case STV_INTERNAL:
702700 return " internal " ;
@@ -709,75 +707,70 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
709707 }
710708 };
711709
712- std::string msg;
713710 switch (ctx.arg .ekind ) {
714711 case ELF32LEKind:
715- msg = maybeReportDiscarded<ELF32LE>(ctx, sym);
712+ maybeReportDiscarded<ELF32LE>(ctx, msg , sym);
716713 break ;
717714 case ELF32BEKind:
718- msg = maybeReportDiscarded<ELF32BE>(ctx, sym);
715+ maybeReportDiscarded<ELF32BE>(ctx, msg , sym);
719716 break ;
720717 case ELF64LEKind:
721- msg = maybeReportDiscarded<ELF64LE>(ctx, sym);
718+ maybeReportDiscarded<ELF64LE>(ctx, msg , sym);
722719 break ;
723720 case ELF64BEKind:
724- msg = maybeReportDiscarded<ELF64BE>(ctx, sym);
721+ maybeReportDiscarded<ELF64BE>(ctx, msg , sym);
725722 break ;
726723 default :
727724 llvm_unreachable (" " );
728725 }
729- if (msg.empty ())
730- msg = " undefined " + visibility () + " symbol: " + toStr (ctx, sym) ;
726+ if (msg.str (). empty ())
727+ msg << " undefined " << visibility () << " symbol: " << & sym;
731728
732729 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)) {
737732 InputSectionBase &sec = *l.sec ;
738733 uint64_t offset = l.offset ;
739734
740- msg += " \n >>> referenced by " ;
735+ msg << " \n >>> referenced by " ;
741736 // In the absence of line number information, utilize DW_TAG_variable (if
742737 // present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).
743738 Symbol *enclosing = sec.getEnclosingSymbol (offset);
744739 std::string src = sec.getSrcMsg (enclosing ? *enclosing : sym, offset);
745740 if (!src.empty ())
746- msg += src + " \n >>> " ;
747- msg += sec.getObjMsg (offset);
748- i++;
741+ msg << src << " \n >>> " ;
742+ msg << sec.getObjMsg (offset);
749743 }
750744
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 " ;
754748
755749 if (correctSpelling) {
756750 std::string pre_hint = " : " , post_hint;
757751 if (const Symbol *corrected =
758752 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;
761754 if (corrected->file )
762- msg += " \n >>> defined in: " + toStr (ctx, corrected->file ) ;
755+ msg << " \n >>> defined in: " << corrected->file ;
763756 }
764757 }
765758
766759 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)" ;
770763 if (ctx.arg .gcSections && ctx.arg .zStartStopGC &&
771764 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 "
773766 " --gc-sections properly; consider -z nostart-stop-gc "
774767 " (see https://lld.llvm.org/ELF/start-stop-gc)" ;
775768 }
776769
777770 if (undef.isWarning )
778- Warn (ctx) << msg;
771+ Warn (ctx) << msg. str () ;
779772 else
780- ctx.e .error (msg, ErrorTag::SymbolNotFound, {sym.getName ()});
773+ ctx.e .error (msg. str () , ErrorTag::SymbolNotFound, {sym.getName ()});
781774}
782775
783776void elf::reportUndefinedSymbols (Ctx &ctx) {
0 commit comments