@@ -74,27 +74,27 @@ static std::optional<std::string> getLinkerScriptLocation(Ctx &ctx,
74
74
return std::nullopt;
75
75
}
76
76
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 " ;
79
79
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);
84
83
}
85
84
86
85
// Construct a message in the following format.
87
86
//
88
87
// >>> defined in /home/alice/src/foo.o
89
88
// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
90
89
// >>> /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);
95
95
if (!src.empty ())
96
- msg += src + " \n >>> " ;
97
- return msg + s .getObjMsg (off);
96
+ s << src << " \n >>> " ;
97
+ s << sec .getObjMsg (off);
98
98
}
99
99
100
100
void 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,
121
121
if (!errPlace.srcLoc .empty ())
122
122
diag << " \n >>> referenced by " << errPlace.srcLoc ;
123
123
if (rel.sym && !rel.sym ->isSection ())
124
- diag << getDefinedLocation (ctx , *rel.sym );
124
+ printDefinedLocation (diag , *rel.sym );
125
125
126
126
if (errPlace.isec && errPlace.isec ->name .starts_with (" .debug" ))
127
127
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,
133
133
auto diag = Err (ctx);
134
134
diag << getErrorPlace (ctx, loc).loc << msg << " is out of range: " << v
135
135
<< " 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
+ }
138
140
}
139
141
140
142
// 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) {
546
548
StringRef signature = file->getShtGroupSignature (objSections, elfSec);
547
549
if (const InputFile *prevailing =
548
550
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;
551
553
if (sym.nonPrevailing ) {
552
554
msg << " \n >>> or the symbol in the prevailing group had STB_WEAK "
553
555
" binding and the symbol in a non-prevailing group had STB_GLOBAL "
@@ -1013,9 +1015,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
1013
1015
if (sym.scriptDefined )
1014
1016
return true ;
1015
1017
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);
1019
1021
return true ;
1020
1022
}
1021
1023
@@ -1181,18 +1183,21 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1181
1183
if (!ctx.arg .shared && sym.isShared () &&
1182
1184
!(ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
1183
1185
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);
1186
1189
return ;
1187
1190
}
1188
1191
1189
1192
if (sym.isObject ()) {
1190
1193
// Produce a copy relocation.
1191
1194
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
+ }
1196
1201
sym.setFlags (NEEDS_COPY);
1197
1202
}
1198
1203
sec->addReloc ({expr, type, offset, addend, &sym});
@@ -1227,20 +1232,26 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1227
1232
// * If a library definition gets preempted to the executable, it will have
1228
1233
// the wrong ebx value.
1229
1234
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
+ }
1234
1241
sym.setFlags (NEEDS_COPY | NEEDS_PLT);
1235
1242
sec->addReloc ({expr, type, offset, addend, &sym});
1236
1243
return ;
1237
1244
}
1238
1245
}
1239
1246
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);
1244
1255
}
1245
1256
1246
1257
// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -1277,9 +1288,10 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
1277
1288
int64_t addend) {
1278
1289
if (expr == R_TPREL || expr == R_TPREL_NEG) {
1279
1290
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);
1283
1295
return 1 ;
1284
1296
}
1285
1297
return 0 ;
@@ -1486,9 +1498,10 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
1486
1498
// Skip the error check for CREL, which does not set `end`.
1487
1499
if constexpr (!RelTy::IsCrel) {
1488
1500
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);
1492
1505
return ;
1493
1506
}
1494
1507
}
0 commit comments