Skip to content

Commit 9c0716f

Browse files
committed
ld.lld: Demangle symbols from archives in diagnostics
This ports r366573 from COFF to ELF. There are now to toString(Archive::Symbol), one doing MSVC demangling in COFF and one doing Itanium demangling in ELF, so rename these two to toCOFFString() and to toELFString() to not get a duplicate symbol. Nothing ever passes a raw Archive::Symbol to CHECK(), so these not being part of the normal toString() machinery seems ok. There are two code paths in the ELF linker that emits this type of diagnostic: 1. The "normal" one in InputFiles.cpp. This is covered by the tweaked test. 2. An additional one that's only used for libcalls if there's at least one bitcode in the link, and if the libcall symbol is lazy, and lazily loaded from an archive (i.e. not from a lazy .o file). (This code path was added in r339301.) Since all libcall names so far are C symbols and never mangled, the change there is not observable and hence not covered by tests. Differential Revision: https://reviews.llvm.org/D65095 llvm-svn: 366836
1 parent 76bc3d6 commit 9c0716f

File tree

8 files changed

+53
-29
lines changed

8 files changed

+53
-29
lines changed

lld/COFF/Driver.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
273273

274274
auto reportBufferError = [=](Error &&e, StringRef childName) {
275275
fatal("could not get the buffer for the member defining symbol " +
276-
toString(sym) + ": " + parentName + "(" + childName + "): " +
276+
toCOFFString(sym) + ": " + parentName + "(" + childName + "): " +
277277
toString(std::move(e)));
278278
};
279279

@@ -284,23 +284,25 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
284284
reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
285285
MemoryBufferRef mb = mbOrErr.get();
286286
enqueueTask([=]() {
287-
driver->addArchiveBuffer(mb, toString(sym), parentName, offsetInArchive);
287+
driver->addArchiveBuffer(mb, toCOFFString(sym), parentName,
288+
offsetInArchive);
288289
});
289290
return;
290291
}
291292

292293
std::string childName = CHECK(
293294
c.getFullName(),
294295
"could not get the filename for the member defining symbol " +
295-
toString(sym));
296+
toCOFFString(sym));
296297
auto future = std::make_shared<std::future<MBErrPair>>(
297298
createFutureForFile(childName));
298299
enqueueTask([=]() {
299300
auto mbOrErr = future->get();
300301
if (mbOrErr.second)
301302
reportBufferError(errorCodeToError(mbOrErr.second), childName);
302303
driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
303-
toString(sym), parentName, /*OffsetInArchive=*/0);
304+
toCOFFString(sym), parentName,
305+
/*OffsetInArchive=*/0);
304306
});
305307
}
306308

lld/COFF/InputFiles.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ void ArchiveFile::parse() {
8686

8787
// Returns a buffer pointing to a member file containing a given symbol.
8888
void ArchiveFile::addMember(const Archive::Symbol &sym) {
89-
const Archive::Child &c = CHECK(
90-
sym.getMember(), "could not get the member for symbol " + toString(sym));
89+
const Archive::Child &c =
90+
CHECK(sym.getMember(),
91+
"could not get the member for symbol " + toCOFFString(sym));
9192

9293
// Return an empty buffer if we have already returned the same buffer.
9394
if (!seen.insert(c.getChildOffset()).second)

lld/COFF/Symbols.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ static std::string demangle(StringRef symName) {
3333
return symName;
3434
}
3535
std::string toString(coff::Symbol &b) { return demangle(b.getName()); }
36-
std::string toString(const Archive::Symbol &b) { return demangle(b.getName()); }
36+
std::string toCOFFString(const Archive::Symbol &b) {
37+
return demangle(b.getName());
38+
}
3739

3840
namespace coff {
3941

lld/COFF/Symbols.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
#include <vector>
2222

2323
namespace lld {
24+
25+
std::string toString(coff::Symbol &b);
26+
27+
// There are two different ways to convert an Archive::Symbol to a string:
28+
// One for Microsoft name mangling and one for Itanium name mangling.
29+
// Call the functions toCOFFString and toELFString, not just toString.
30+
std::string toCOFFString(const coff::Archive::Symbol &b);
31+
2432
namespace coff {
2533

2634
using llvm::object::Archive;
@@ -429,8 +437,6 @@ void replaceSymbol(Symbol *s, ArgT &&... arg) {
429437
}
430438
} // namespace coff
431439

432-
std::string toString(coff::Symbol &b);
433-
std::string toString(const coff::Archive::Symbol &b);
434440
} // namespace lld
435441

436442
#endif

lld/ELF/InputFiles.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
11481148
Archive::Child c =
11491149
CHECK(sym.getMember(), toString(this) +
11501150
": could not get the member for symbol " +
1151-
sym.getName());
1151+
toELFString(sym));
11521152

11531153
if (!seen.insert(c.getChildOffset()).second)
11541154
return;
@@ -1157,7 +1157,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
11571157
CHECK(c.getMemoryBufferRef(),
11581158
toString(this) +
11591159
": could not get the buffer for the member defining symbol " +
1160-
sym.getName());
1160+
toELFString(sym));
11611161

11621162
if (tar && c.getParent()->isThin())
11631163
tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());

lld/ELF/Symbols.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ Defined *ElfSym::relaIpltEnd;
4242
Defined *ElfSym::riscvGlobalPointer;
4343
Defined *ElfSym::tlsModuleBase;
4444

45+
// Returns a symbol for an error message.
46+
static std::string demangle(StringRef symName) {
47+
if (config->demangle)
48+
if (Optional<std::string> s = demangleItanium(symName))
49+
return *s;
50+
return symName;
51+
}
52+
namespace lld {
53+
std::string toString(const Symbol &b) { return demangle(b.getName()); }
54+
std::string toELFString(const Archive::Symbol &b) {
55+
return demangle(b.getName());
56+
}
57+
} // namespace lld
58+
4559
static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
4660
switch (sym.kind()) {
4761
case Symbol::DefinedKind: {
@@ -250,12 +264,13 @@ void Symbol::fetch() const {
250264
}
251265

252266
MemoryBufferRef LazyArchive::getMemberBuffer() {
253-
Archive::Child c = CHECK(
254-
sym.getMember(), "could not get the member for symbol " + sym.getName());
267+
Archive::Child c =
268+
CHECK(sym.getMember(),
269+
"could not get the member for symbol " + toELFString(sym));
255270

256271
return CHECK(c.getMemoryBufferRef(),
257272
"could not get the buffer for the member defining symbol " +
258-
sym.getName());
273+
toELFString(sym));
259274
}
260275

261276
uint8_t Symbol::computeBinding() const {
@@ -331,14 +346,6 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
331346
report(": unable to order discarded symbol: ");
332347
}
333348

334-
// Returns a symbol for an error message.
335-
std::string lld::toString(const Symbol &b) {
336-
if (config->demangle)
337-
if (Optional<std::string> s = demangleItanium(b.getName()))
338-
return *s;
339-
return b.getName();
340-
}
341-
342349
static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
343350
if (va == STV_DEFAULT)
344351
return vb;

lld/ELF/Symbols.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ class Undefined;
3333
} // namespace elf
3434

3535
std::string toString(const elf::Symbol &);
36-
std::string toString(const elf::InputFile *);
36+
37+
// There are two different ways to convert an Archive::Symbol to a string:
38+
// One for Microsoft name mangling and one for Itanium name mangling.
39+
// Call the functions toCOFFString and toELFString, not just toString.
40+
std::string toELFString(const elf::Archive::Symbol &);
3741

3842
namespace elf {
3943

lld/test/ELF/archive-thin-missing-member.s

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@
88
# RUN: rm %t.o
99

1010
# Test error when loading symbols from missing thin archive member.
11-
# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
11+
# RUN: not ld.lld --entry=_Z1fi %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
1212
# ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
1313

1414
# Test error when thin archive has symbol table but member is missing.
15-
# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
16-
# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
15+
# RUN: not ld.lld --entry=_Z1fi -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
16+
# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol f(int): '{{.*}}.o': {{[Nn]}}o such file or directory
17+
# RUN: not ld.lld --entry=_Z1fi --no-demangle -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2MANGLE
18+
# ERR2MANGLE: {{.*}}-syms.a: could not get the buffer for the member defining symbol _Z1fi: '{{.*}}.o': {{[Nn]}}o such file or directory
1719

1820
# Test error when thin archive is linked using --whole-archive but member is missing.
19-
# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
21+
# RUN: not ld.lld --entry=_Z1fi --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
2022
# ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
2123

22-
.global _start
23-
_start:
24+
.global _Z1fi
25+
_Z1fi:
2426
nop

0 commit comments

Comments
 (0)