diff options
author | Nico Weber <nicolasweber@gmx.de> | 2018-09-15 18:27:09 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2018-09-15 18:27:09 +0000 |
commit | da15acbd68cb9c60aef5a4e51a5383641c65147d (patch) | |
tree | 1b11539cb85b25f4bef0396faa8715f420892f05 | |
parent | da01b342b255e6e99580313d7b74753ccb4f6716 (diff) | |
download | bcm5719-llvm-da15acbd68cb9c60aef5a4e51a5383641c65147d.tar.gz bcm5719-llvm-da15acbd68cb9c60aef5a4e51a5383641c65147d.zip |
lld-link: print demangled symbol names for "undefined symbol" diagnostics
For this, add a few toString() calls when printing the "undefined symbol"
diagnostics; toString() already does demangling on Windows hosts.
Also make lld::demangleMSVC() (called by toString(Symbol*)) call LLVM's
microsoftDemangle() instead of UnDecorateSymbolName() so that it works on
non-Windows hosts – this makes both updating tests easier and provides a better
user experience for people doing cross-links.
This doesn't yet do the right thing for symbols starting with __imp_, but that
can be improved in a follow-up.
Differential Revision: https://reviews.llvm.org/D52104
llvm-svn: 342332
-rw-r--r-- | lld/COFF/SymbolTable.cpp | 36 | ||||
-rw-r--r-- | lld/Common/Strings.cpp | 29 | ||||
-rw-r--r-- | lld/test/COFF/undefined-symbol-cv.s | 6 | ||||
-rw-r--r-- | lld/test/COFF/undefined-symbol.s | 6 |
4 files changed, 32 insertions, 45 deletions
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 1e3ebfce982..a64267ffb56 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -66,10 +66,10 @@ static void errorOrWarn(const Twine &S) { error(S); } -// Returns the name of the symbol in SC whose value is <= Addr that is closest -// to Addr. This is generally the name of the global variable or function whose -// definition contains Addr. -static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) { +// Returns the symbol in SC whose value is <= Addr that is closest to Addr. +// This is generally the global variable or function whose definition contains +// Addr. +static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) { DefinedRegular *Candidate = nullptr; for (Symbol *S : SC->File->getSymbols()) { @@ -81,14 +81,12 @@ static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) { Candidate = D; } - if (!Candidate) - return ""; - return Candidate->getName(); + return Candidate; } static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) { struct Location { - StringRef SymName; + Symbol *Sym; std::pair<StringRef, uint32_t> FileLine; }; std::vector<Location> Locations; @@ -102,9 +100,9 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) { continue; std::pair<StringRef, uint32_t> FileLine = getFileLine(SC, R.VirtualAddress); - StringRef SymName = getSymbolName(SC, R.VirtualAddress); - if (!FileLine.first.empty() || !SymName.empty()) - Locations.push_back({SymName, FileLine}); + Symbol *Sym = getSymbol(SC, R.VirtualAddress); + if (!FileLine.first.empty() || Sym) + Locations.push_back({Sym, FileLine}); } } @@ -119,8 +117,8 @@ static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) { OS << Loc.FileLine.first << ":" << Loc.FileLine.second << "\n>>> "; OS << toString(File); - if (!Loc.SymName.empty()) - OS << ":(" << Loc.SymName << ')'; + if (Loc.Sym) + OS << ":(" << toString(*Loc.Sym) << ')'; } return OS.str(); } @@ -247,10 +245,10 @@ void SymbolTable::reportRemainingUndefines() { for (Symbol *B : Config->GCRoot) { if (Undefs.count(B)) - errorOrWarn("<root>: undefined symbol: " + B->getName()); + errorOrWarn("<root>: undefined symbol: " + toString(*B)); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(B)) - warn("<root>: locally defined symbol imported: " + Imp->getName() + + warn("<root>: locally defined symbol imported: " + toString(*Imp) + " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); } @@ -261,13 +259,13 @@ void SymbolTable::reportRemainingUndefines() { if (!Sym) continue; if (Undefs.count(Sym)) - errorOrWarn("undefined symbol: " + Sym->getName() + + errorOrWarn("undefined symbol: " + toString(*Sym) + getSymbolLocations(File, SymIndex)); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(Sym)) - warn(toString(File) + ": locally defined symbol imported: " + - Imp->getName() + " (defined in " + toString(Imp->getFile()) + - ") [LNK4217]"); + warn(toString(File) + + ": locally defined symbol imported: " + toString(*Imp) + + " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); } } } diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp index 36f4f77d847..581a0795482 100644 --- a/lld/Common/Strings.cpp +++ b/lld/Common/Strings.cpp @@ -16,14 +16,6 @@ #include <mutex> #include <vector> -#if defined(_MSC_VER) -#include <Windows.h> - -// DbgHelp.h must be included after Windows.h. -#include <DbgHelp.h> -#pragma comment(lib, "dbghelp.lib") -#endif - using namespace llvm; using namespace lld; @@ -45,18 +37,15 @@ Optional<std::string> lld::demangleItanium(StringRef Name) { return S; } -Optional<std::string> lld::demangleMSVC(StringRef S) { -#if defined(_MSC_VER) - // UnDecorateSymbolName is not thread-safe, so we need a mutex. - static std::mutex Mu; - std::lock_guard<std::mutex> Lock(Mu); - - char Buf[4096]; - if (S.startswith("?")) - if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) - return std::string(Buf, Len); -#endif - return None; +Optional<std::string> lld::demangleMSVC(StringRef Name) { + if (!Name.startswith("?")) + return None; + char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); + if (!Buf) + return None; + std::string S(Buf); + free(Buf); + return S; } StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { diff --git a/lld/test/COFF/undefined-symbol-cv.s b/lld/test/COFF/undefined-symbol-cv.s index e729d5fa96c..e730c5dfc9f 100644 --- a/lld/test/COFF/undefined-symbol-cv.s +++ b/lld/test/COFF/undefined-symbol-cv.s @@ -2,19 +2,19 @@ # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s # RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s -# CHECK: error: undefined symbol: ?foo@@YAHXZ +# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ) # CHECK-NEXT: >>> referenced by file1.cpp:1 # CHECK-NEXT: >>> {{.*}}.obj:(main) # CHECK-NEXT: >>> referenced by file1.cpp:2 # CHECK-NEXT: >>> {{.*}}.obj:(main) # CHECK-EMPTY: -# CHECK-NEXT: error: undefined symbol: ?bar@@YAHXZ +# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ) # CHECK-NEXT: >>> referenced by file2.cpp:3 # CHECK-NEXT: >>> {{.*}}.obj:(main) # CHECK-NEXT: >>> referenced by file1.cpp:4 # CHECK-NEXT: >>> {{.*}}.obj:(f1) # CHECK-EMPTY: -# CHECK-NEXT: error: undefined symbol: ?baz@@YAHXZ +# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ) # CHECK-NEXT: >>> referenced by file1.cpp:5 # CHECK-NEXT: >>> {{.*}}.obj:(f2) diff --git a/lld/test/COFF/undefined-symbol.s b/lld/test/COFF/undefined-symbol.s index 6b64a8e1d3e..bffbcd3395a 100644 --- a/lld/test/COFF/undefined-symbol.s +++ b/lld/test/COFF/undefined-symbol.s @@ -2,15 +2,15 @@ # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s # RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s -# CHECK: error: undefined symbol: ?foo@@YAHXZ +# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ) # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) # CHECK-EMPTY: -# CHECK-NEXT: error: undefined symbol: ?bar@@YAHXZ +# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ) # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1) # CHECK-EMPTY: -# CHECK-NEXT: error: undefined symbol: ?baz@@YAHXZ +# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ) # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2) .section .text,"xr",one_only,main |