@@ -74,27 +74,27 @@ static std::optional<std::string> getLinkerScriptLocation(Ctx &ctx,
7474 return std::nullopt ;
7575}
7676
77- static std::string getDefinedLocation (Ctx &ctx , const Symbol &sym) {
78- const char msg[] = " \n >>> defined in " ;
77+ static void printDefinedLocation (ELFSyncStream &s , const Symbol &sym) {
78+ s << " \n >>> defined in " ;
7979 if (sym.file )
80- return msg + toStr (ctx, sym.file );
81- if (std::optional<std::string> loc = getLinkerScriptLocation (ctx, sym))
82- return msg + *loc;
83- return " " ;
80+ return void (s << sym.file );
81+ if (std::optional<std::string> loc = getLinkerScriptLocation (s.ctx , sym))
82+ return void (s << *loc);
8483}
8584
8685// Construct a message in the following format.
8786//
8887// >>> defined in /home/alice/src/foo.o
8988// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
9089// >>> /home/alice/src/bar.o:(.text+0x1)
91- static std::string getLocation (Ctx &ctx, InputSectionBase &s, const Symbol &sym,
92- uint64_t off) {
93- std::string msg = getDefinedLocation (ctx, sym) + " \n >>> referenced by " ;
94- std::string src = s.getSrcMsg (sym, off);
90+ static void printLocation (ELFSyncStream &s, InputSectionBase &sec,
91+ const Symbol &sym, uint64_t off) {
92+ printDefinedLocation (s, sym);
93+ s << " \n >>> referenced by " ;
94+ std::string src = sec.getSrcMsg (sym, off);
9595 if (!src.empty ())
96- msg += src + " \n >>> " ;
97- return msg + s .getObjMsg (off);
96+ s << src << " \n >>> " ;
97+ s << sec .getObjMsg (off);
9898}
9999
100100void elf::reportRangeError (Ctx &ctx, uint8_t *loc, const Relocation &rel,
@@ -121,7 +121,7 @@ void elf::reportRangeError(Ctx &ctx, uint8_t *loc, const Relocation &rel,
121121 if (!errPlace.srcLoc .empty ())
122122 diag << " \n >>> referenced by " << errPlace.srcLoc ;
123123 if (rel.sym && !rel.sym ->isSection ())
124- diag << getDefinedLocation (ctx , *rel.sym );
124+ printDefinedLocation (diag , *rel.sym );
125125
126126 if (errPlace.isec && errPlace.isec ->name .starts_with (" .debug" ))
127127 diag << " ; consider recompiling with -fdebug-types-section to reduce size "
@@ -133,8 +133,10 @@ void elf::reportRangeError(Ctx &ctx, uint8_t *loc, int64_t v, int n,
133133 auto diag = Err (ctx);
134134 diag << getErrorPlace (ctx, loc).loc << msg << " is out of range: " << v
135135 << " is not in [" << llvm::minIntN (n) << " , " << llvm::maxIntN (n) << " ]" ;
136- if (!sym.getName ().empty ())
137- diag << " ; references '" << &sym << ' \' ' << getDefinedLocation (ctx, sym);
136+ if (!sym.getName ().empty ()) {
137+ diag << " ; references '" << &sym << ' \' ' ;
138+ printDefinedLocation (diag, sym);
139+ }
138140}
139141
140142// Build a bitmask with one bit set for each 64 subset of RelExpr.
@@ -546,8 +548,8 @@ static void maybeReportDiscarded(Ctx &ctx, ELFSyncStream &msg, Undefined &sym) {
546548 StringRef signature = file->getShtGroupSignature (objSections, elfSec);
547549 if (const InputFile *prevailing =
548550 ctx.symtab ->comdatGroups .lookup (CachedHashStringRef (signature))) {
549- msg << " \n >>> section group signature: "
550- << signature. str () + " \n >>> prevailing definition is in " << prevailing;
551+ msg << " \n >>> section group signature: " << signature
552+ << " \n >>> prevailing definition is in " << prevailing;
551553 if (sym.nonPrevailing ) {
552554 msg << " \n >>> or the symbol in the prevailing group had STB_WEAK "
553555 " binding and the symbol in a non-prevailing group had STB_GLOBAL "
@@ -1013,9 +1015,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
10131015 if (sym.scriptDefined )
10141016 return true ;
10151017
1016- Err (ctx) << " relocation " << type
1017- << " cannot refer to absolute symbol: " << &sym
1018- << getLocation (ctx , *sec, sym, relOff);
1018+ auto diag = Err (ctx);
1019+ diag << " relocation " << type << " cannot refer to absolute symbol: " << &sym;
1020+ printLocation (diag , *sec, sym, relOff);
10191021 return true ;
10201022}
10211023
@@ -1181,18 +1183,21 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11811183 if (!ctx.arg .shared && sym.isShared () &&
11821184 !(ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
11831185 if (!canDefineSymbolInExecutable (ctx, sym)) {
1184- Err (ctx) << " cannot preempt symbol: " << &sym
1185- << getLocation (ctx, *sec, sym, offset);
1186+ auto diag = Err (ctx);
1187+ diag << " cannot preempt symbol: " << &sym;
1188+ printLocation (diag, *sec, sym, offset);
11861189 return ;
11871190 }
11881191
11891192 if (sym.isObject ()) {
11901193 // Produce a copy relocation.
11911194 if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
1192- if (!ctx.arg .zCopyreloc )
1193- Err (ctx) << " unresolvable relocation " << type << " against symbol '"
1194- << ss << " '; recompile with -fPIC or remove '-z nocopyreloc'"
1195- << getLocation (ctx, *sec, sym, offset);
1195+ if (!ctx.arg .zCopyreloc ) {
1196+ auto diag = Err (ctx);
1197+ diag << " unresolvable relocation " << type << " against symbol '"
1198+ << ss << " '; recompile with -fPIC or remove '-z nocopyreloc'" ;
1199+ printLocation (diag, *sec, sym, offset);
1200+ }
11961201 sym.setFlags (NEEDS_COPY);
11971202 }
11981203 sec->addReloc ({expr, type, offset, addend, &sym});
@@ -1227,20 +1232,26 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12271232 // * If a library definition gets preempted to the executable, it will have
12281233 // the wrong ebx value.
12291234 if (sym.isFunc ()) {
1230- if (ctx.arg .pie && ctx.arg .emachine == EM_386)
1231- Err (ctx) << " symbol '" << &sym
1232- << " ' cannot be preempted; recompile with -fPIE"
1233- << getLocation (ctx, *sec, sym, offset);
1235+ if (ctx.arg .pie && ctx.arg .emachine == EM_386) {
1236+ auto diag = Err (ctx);
1237+ diag << " symbol '" << &sym
1238+ << " ' cannot be preempted; recompile with -fPIE" ;
1239+ printLocation (diag, *sec, sym, offset);
1240+ }
12341241 sym.setFlags (NEEDS_COPY | NEEDS_PLT);
12351242 sec->addReloc ({expr, type, offset, addend, &sym});
12361243 return ;
12371244 }
12381245 }
12391246
1240- Err (ctx) << " relocation " << type << " cannot be used against "
1241- << (sym.getName ().empty () ? " local symbol"
1242- : (" symbol '" + toStr (ctx, sym) + " '" ))
1243- << " ; recompile with -fPIC" << getLocation (ctx, *sec, sym, offset);
1247+ auto diag = Err (ctx);
1248+ diag << " relocation " << type << " cannot be used against " ;
1249+ if (sym.getName ().empty ())
1250+ diag << " local symbol" ;
1251+ else
1252+ diag << " symbol '" << &sym << " '" ;
1253+ diag << " ; recompile with -fPIC" ;
1254+ printLocation (diag, *sec, sym, offset);
12441255}
12451256
12461257// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -1277,9 +1288,10 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
12771288 int64_t addend) {
12781289 if (expr == R_TPREL || expr == R_TPREL_NEG) {
12791290 if (ctx.arg .shared ) {
1280- Err (ctx) << " relocation " << type << " against " << &sym
1281- << " cannot be used with -shared"
1282- << getLocation (ctx, *sec, sym, offset);
1291+ auto diag = Err (ctx);
1292+ diag << " relocation " << type << " against " << &sym
1293+ << " cannot be used with -shared" ;
1294+ printLocation (diag, *sec, sym, offset);
12831295 return 1 ;
12841296 }
12851297 return 0 ;
@@ -1486,9 +1498,10 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
14861498 // Skip the error check for CREL, which does not set `end`.
14871499 if constexpr (!RelTy::IsCrel) {
14881500 if (i == end) {
1489- Err (ctx) << " R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "
1490- " relocation"
1491- << getLocation (ctx, *sec, sym, offset);
1501+ auto diag = Err (ctx);
1502+ diag << " R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "
1503+ " relocation" ;
1504+ printLocation (diag, *sec, sym, offset);
14921505 return ;
14931506 }
14941507 }
0 commit comments