diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 01bdadd70669..6d9fe243b0ff 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -273,7 +273,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))); }; @@ -284,7 +284,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; } @@ -292,7 +293,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>( createFutureForFile(childName)); enqueueTask([=]() { @@ -300,7 +301,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/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index c72fa587a026..d02fedfd178b 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/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/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index c1eb75ff7001..acb3b32203e5 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/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/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 77ae2f157d34..10d2b8149cd8 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -21,6 +21,14 @@ #include 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/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index eeb5845b85c6..95a4de33cda8 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1148,7 +1148,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; @@ -1157,7 +1157,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/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 62c552e04828..22677303c322 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/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 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 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/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index d640495b0e01..9c1eb387c2f4 100644 --- a/lld/ELF/Symbols.h +++ b/lld/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/lld/test/ELF/archive-thin-missing-member.s b/lld/test/ELF/archive-thin-missing-member.s index d96fbc45415b..4db1376cfaf2 100644 --- a/lld/test/ELF/archive-thin-missing-member.s +++ b/lld/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