aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-08-26 08:35:17 +0000
committerHans Wennborg <hans@hanshq.net>2019-08-26 08:35:17 +0000
commitcc79e7079b75c9cd7e956256798f104f3b51e3d1 (patch)
tree9824e0b048461225dba24e9fe1f0d04dc2cb17df
parent34438eeb1452c44772ea5d279e7f5ba808d54b0a (diff)
Merging r366836:
------------------------------------------------------------------------ r366836 | nico | 2019-07-23 21:00:01 +0200 (Tue, 23 Jul 2019) | 24 lines 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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/lld/branches/release_90@369882 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--COFF/Driver.cpp10
-rw-r--r--COFF/InputFiles.cpp5
-rw-r--r--COFF/Symbols.cpp4
-rw-r--r--COFF/Symbols.h10
-rw-r--r--ELF/InputFiles.cpp4
-rw-r--r--ELF/Symbols.cpp29
-rw-r--r--ELF/Symbols.h6
-rw-r--r--test/ELF/archive-thin-missing-member.s14
8 files changed, 53 insertions, 29 deletions
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 66ed16131..d68760e4b 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -276,7 +276,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
auto reportBufferError = [=](Error &&e, StringRef childName) {
fatal("could not get the buffer for the member defining symbol " +
- toString(sym) + ": " + parentName + "(" + childName + "): " +
+ toCOFFString(sym) + ": " + parentName + "(" + childName + "): " +
toString(std::move(e)));
};
@@ -287,7 +287,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
MemoryBufferRef mb = mbOrErr.get();
enqueueTask([=]() {
- driver->addArchiveBuffer(mb, toString(sym), parentName, offsetInArchive);
+ driver->addArchiveBuffer(mb, toCOFFString(sym), parentName,
+ offsetInArchive);
});
return;
}
@@ -295,7 +296,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
std::string childName = CHECK(
c.getFullName(),
"could not get the filename for the member defining symbol " +
- toString(sym));
+ toCOFFString(sym));
auto future = std::make_shared<std::future<MBErrPair>>(
createFutureForFile(childName));
enqueueTask([=]() {
@@ -303,7 +304,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
if (mbOrErr.second)
reportBufferError(errorCodeToError(mbOrErr.second), childName);
driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
- toString(sym), parentName, /*OffsetInArchive=*/0);
+ toCOFFString(sym), parentName,
+ /*OffsetInArchive=*/0);
});
}
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index c72fa587a..d02fedfd1 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -86,8 +86,9 @@ void ArchiveFile::parse() {
// Returns a buffer pointing to a member file containing a given symbol.
void ArchiveFile::addMember(const Archive::Symbol &sym) {
- const Archive::Child &c = CHECK(
- sym.getMember(), "could not get the member for symbol " + toString(sym));
+ const Archive::Child &c =
+ CHECK(sym.getMember(),
+ "could not get the member for symbol " + toCOFFString(sym));
// Return an empty buffer if we have already returned the same buffer.
if (!seen.insert(c.getChildOffset()).second)
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index c1eb75ff7..acb3b3220 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -33,7 +33,9 @@ static std::string demangle(StringRef symName) {
return symName;
}
std::string toString(coff::Symbol &b) { return demangle(b.getName()); }
-std::string toString(const Archive::Symbol &b) { return demangle(b.getName()); }
+std::string toCOFFString(const Archive::Symbol &b) {
+ return demangle(b.getName());
+}
namespace coff {
diff --git a/COFF/Symbols.h b/COFF/Symbols.h
index 77ae2f157..10d2b8149 100644
--- a/COFF/Symbols.h
+++ b/COFF/Symbols.h
@@ -21,6 +21,14 @@
#include <vector>
namespace lld {
+
+std::string toString(coff::Symbol &b);
+
+// There are two different ways to convert an Archive::Symbol to a string:
+// One for Microsoft name mangling and one for Itanium name mangling.
+// Call the functions toCOFFString and toELFString, not just toString.
+std::string toCOFFString(const coff::Archive::Symbol &b);
+
namespace coff {
using llvm::object::Archive;
@@ -429,8 +437,6 @@ void replaceSymbol(Symbol *s, ArgT &&... arg) {
}
} // namespace coff
-std::string toString(coff::Symbol &b);
-std::string toString(const coff::Archive::Symbol &b);
} // namespace lld
#endif
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index 98b88283c..f9cbf1569 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1144,7 +1144,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
Archive::Child c =
CHECK(sym.getMember(), toString(this) +
": could not get the member for symbol " +
- sym.getName());
+ toELFString(sym));
if (!seen.insert(c.getChildOffset()).second)
return;
@@ -1153,7 +1153,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) {
CHECK(c.getMemoryBufferRef(),
toString(this) +
": could not get the buffer for the member defining symbol " +
- sym.getName());
+ toELFString(sym));
if (tar && c.getParent()->isThin())
tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 62c552e04..22677303c 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -42,6 +42,20 @@ Defined *ElfSym::relaIpltEnd;
Defined *ElfSym::riscvGlobalPointer;
Defined *ElfSym::tlsModuleBase;
+// Returns a symbol for an error message.
+static std::string demangle(StringRef symName) {
+ if (config->demangle)
+ if (Optional<std::string> s = demangleItanium(symName))
+ return *s;
+ return symName;
+}
+namespace lld {
+std::string toString(const Symbol &b) { return demangle(b.getName()); }
+std::string toELFString(const Archive::Symbol &b) {
+ return demangle(b.getName());
+}
+} // namespace lld
+
static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
switch (sym.kind()) {
case Symbol::DefinedKind: {
@@ -250,12 +264,13 @@ void Symbol::fetch() const {
}
MemoryBufferRef LazyArchive::getMemberBuffer() {
- Archive::Child c = CHECK(
- sym.getMember(), "could not get the member for symbol " + sym.getName());
+ Archive::Child c =
+ CHECK(sym.getMember(),
+ "could not get the member for symbol " + toELFString(sym));
return CHECK(c.getMemoryBufferRef(),
"could not get the buffer for the member defining symbol " +
- sym.getName());
+ toELFString(sym));
}
uint8_t Symbol::computeBinding() const {
@@ -331,14 +346,6 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
report(": unable to order discarded symbol: ");
}
-// Returns a symbol for an error message.
-std::string lld::toString(const Symbol &b) {
- if (config->demangle)
- if (Optional<std::string> s = demangleItanium(b.getName()))
- return *s;
- return b.getName();
-}
-
static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
if (va == STV_DEFAULT)
return vb;
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index d640495b0..9c1eb387c 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -33,7 +33,11 @@ class Undefined;
} // namespace elf
std::string toString(const elf::Symbol &);
-std::string toString(const elf::InputFile *);
+
+// There are two different ways to convert an Archive::Symbol to a string:
+// One for Microsoft name mangling and one for Itanium name mangling.
+// Call the functions toCOFFString and toELFString, not just toString.
+std::string toELFString(const elf::Archive::Symbol &);
namespace elf {
diff --git a/test/ELF/archive-thin-missing-member.s b/test/ELF/archive-thin-missing-member.s
index d96fbc454..4db1376cf 100644
--- a/test/ELF/archive-thin-missing-member.s
+++ b/test/ELF/archive-thin-missing-member.s
@@ -8,17 +8,19 @@
# RUN: rm %t.o
# Test error when loading symbols from missing thin archive member.
-# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
+# RUN: not ld.lld --entry=_Z1fi %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
# ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
# Test error when thin archive has symbol table but member is missing.
-# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
-# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
+# RUN: not ld.lld --entry=_Z1fi -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
+# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol f(int): '{{.*}}.o': {{[Nn]}}o such file or directory
+# 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
+# ERR2MANGLE: {{.*}}-syms.a: could not get the buffer for the member defining symbol _Z1fi: '{{.*}}.o': {{[Nn]}}o such file or directory
# Test error when thin archive is linked using --whole-archive but member is missing.
-# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
+# RUN: not ld.lld --entry=_Z1fi --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
# ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
-.global _start
-_start:
+.global _Z1fi
+_Z1fi:
nop