diff options
| author | Nico Weber <nicolasweber@gmx.de> | 2019-07-19 13:29:10 +0000 |
|---|---|---|
| committer | Nico Weber <nicolasweber@gmx.de> | 2019-07-19 13:29:10 +0000 |
| commit | cb2c50028d8ecf748d0f117ddc361058f6315586 (patch) | |
| tree | b26f537e911a73d3b2c6771a8a9107fd9cc290c9 | |
| parent | b288d90b39f4b905c02092a9bfcfd6d78f99b191 (diff) | |
| download | bcm5719-llvm-cb2c50028d8ecf748d0f117ddc361058f6315586.tar.gz bcm5719-llvm-cb2c50028d8ecf748d0f117ddc361058f6315586.zip | |
lld-link: Demangle symbols from archives in diagnostics
Also add test coverage for thin archives (which are the only way I could
come up with to test at least some of the diagnostic changes).
Differential Revision: https://reviews.llvm.org/D64927
llvm-svn: 366573
| -rw-r--r-- | lld/COFF/Driver.cpp | 15 | ||||
| -rw-r--r-- | lld/COFF/Driver.h | 2 | ||||
| -rw-r--r-- | lld/COFF/InputFiles.cpp | 9 | ||||
| -rw-r--r-- | lld/COFF/InputFiles.h | 2 | ||||
| -rw-r--r-- | lld/COFF/SymbolTable.cpp | 8 | ||||
| -rw-r--r-- | lld/COFF/SymbolTable.h | 2 | ||||
| -rw-r--r-- | lld/COFF/Symbols.cpp | 11 | ||||
| -rw-r--r-- | lld/COFF/Symbols.h | 1 | ||||
| -rw-r--r-- | lld/test/COFF/Inputs/mangled-symbol.s | 9 | ||||
| -rw-r--r-- | lld/test/COFF/thin-archive.s | 36 |
10 files changed, 71 insertions, 24 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index d7af50b9318..01bdadd7066 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -268,13 +268,12 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, } void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, - StringRef symName, + const Archive::Symbol &sym, StringRef parentName) { - auto reportBufferError = [=](Error &&e, - StringRef childName) { + auto reportBufferError = [=](Error &&e, StringRef childName) { fatal("could not get the buffer for the member defining symbol " + - symName + ": " + parentName + "(" + childName + "): " + + toString(sym) + ": " + parentName + "(" + childName + "): " + toString(std::move(e))); }; @@ -285,7 +284,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, reportBufferError(mbOrErr.takeError(), check(c.getFullName())); MemoryBufferRef mb = mbOrErr.get(); enqueueTask([=]() { - driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive); + driver->addArchiveBuffer(mb, toString(sym), parentName, offsetInArchive); }); return; } @@ -293,15 +292,15 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, std::string childName = CHECK( c.getFullName(), "could not get the filename for the member defining symbol " + - symName); + toString(sym)); auto future = std::make_shared<std::future<MBErrPair>>( createFutureForFile(childName)); enqueueTask([=]() { auto mbOrErr = future->get(); if (mbOrErr.second) reportBufferError(errorCodeToError(mbOrErr.second), childName); - driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName, - parentName, /* OffsetInArchive */ 0); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), + toString(sym), parentName, /*OffsetInArchive=*/0); }); } diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index 6100c3ca0c9..01bfb02a5c3 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -72,7 +72,7 @@ public: void parseDirectives(InputFile *file); // Used by ArchiveFile to enqueue members. - void enqueueArchiveMember(const Archive::Child &c, StringRef symName, + void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, StringRef parentName); MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb); diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index c00d5c5b494..c72fa587a02 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -85,16 +85,15 @@ 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 " + sym->getName()); +void ArchiveFile::addMember(const Archive::Symbol &sym) { + const Archive::Child &c = CHECK( + sym.getMember(), "could not get the member for symbol " + toString(sym)); // Return an empty buffer if we have already returned the same buffer. if (!seen.insert(c.getChildOffset()).second) return; - driver->enqueueArchiveMember(c, sym->getName(), getName()); + driver->enqueueArchiveMember(c, sym, getName()); } std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) { diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index dfad9814a39..8d3a021a378 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -96,7 +96,7 @@ public: // Enqueues an archive member load for the given symbol. If we've already // enqueued a load for the same archive member, this function does nothing, // which ensures that we don't load the same member more than once. - void addMember(const Archive::Symbol *sym); + void addMember(const Archive::Symbol &sym); private: std::unique_ptr<Archive> file; diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 0aff164ee56..07ebf6ea550 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -179,7 +179,7 @@ void SymbolTable::loadMinGWAutomaticImports() { log("Loading lazy " + l->getName() + " from " + l->file->getName() + " for automatic import"); l->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } @@ -363,13 +363,13 @@ Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f, if (auto *l = dyn_cast<Lazy>(s)) { if (!s->pendingArchiveLoad) { s->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } return s; } -void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { +void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol &sym) { StringRef name = sym.getName(); Symbol *s; bool wasInserted; @@ -382,7 +382,7 @@ void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { if (!u || u->weakAlias || s->pendingArchiveLoad) return; s->pendingArchiveLoad = true; - f->addMember(&sym); + f->addMember(sym); } void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 88f47cbe9e7..50e7e9ba1d5 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -83,7 +83,7 @@ public: Symbol *addAbsolute(StringRef n, uint64_t va); Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias); - void addLazy(ArchiveFile *f, const Archive::Symbol sym); + void addLazy(ArchiveFile *f, const Archive::Symbol &sym); Symbol *addAbsolute(StringRef n, COFFSymbolRef s); Symbol *addRegular(InputFile *f, StringRef n, const llvm::object::coff_symbol_generic *s = nullptr, diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 3583d4cb28c..c1eb75ff700 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -20,18 +20,21 @@ using namespace llvm::object; using namespace lld::coff; +namespace lld { + static_assert(sizeof(SymbolUnion) <= 48, "symbols should be optimized for memory usage"); // Returns a symbol name for an error message. -std::string lld::toString(coff::Symbol &b) { +static std::string demangle(StringRef symName) { if (config->demangle) - if (Optional<std::string> s = lld::demangleMSVC(b.getName())) + if (Optional<std::string> s = demangleMSVC(symName)) return *s; - return b.getName(); + return symName; } +std::string toString(coff::Symbol &b) { return demangle(b.getName()); } +std::string toString(const Archive::Symbol &b) { return demangle(b.getName()); } -namespace lld { namespace coff { StringRef Symbol::getName() { diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 86cd4f585e5..77ae2f157d3 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -430,6 +430,7 @@ 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/test/COFF/Inputs/mangled-symbol.s b/lld/test/COFF/Inputs/mangled-symbol.s new file mode 100644 index 00000000000..d393236768e --- /dev/null +++ b/lld/test/COFF/Inputs/mangled-symbol.s @@ -0,0 +1,9 @@ + .text + + .def "?f@@YAHXZ" + .scl 2 + .type 32 + .endef + .global "?f@@YAHXZ" +"?f@@YAHXZ": + retq $0 diff --git a/lld/test/COFF/thin-archive.s b/lld/test/COFF/thin-archive.s new file mode 100644 index 00000000000..6eb896c57da --- /dev/null +++ b/lld/test/COFF/thin-archive.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.main.obj %s + +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.lib.obj \ +# RUN: %S/Inputs/mangled-symbol.s +# RUN: lld-link /lib /out:%t.lib %t.lib.obj +# RUN: lld-link /lib /llvmlibthin /out:%t_thin.lib %t.lib.obj + +# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s + +# RUN: rm %t.lib.obj +# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --check-prefix=NOOBJ %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe \ +# RUN: /demangle:no 2>&1 | FileCheck --check-prefix=NOOBJNODEMANGLE %s + +# CHECK-NOT: error: could not get the buffer for the member defining +# NOOBJ: error: could not get the buffer for the member defining symbol int __cdecl f(void): {{.*}}.lib({{.*}}.lib.obj): +# NOOBJNODEMANGLE: error: could not get the buffer for the member defining symbol ?f@@YAHXZ: {{.*}}.lib({{.*}}.lib.obj): + + .text + + .def main + .scl 2 + .type 32 + .endef + .global main +main: + call "?f@@YAHXZ" + retq $0 |

