[lld] r342332 - lld-link: print demangled symbol names for "undefined symbol" diagnostics

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 15 11:27:10 PDT 2018


Author: nico
Date: Sat Sep 15 11:27:09 2018
New Revision: 342332

URL: http://llvm.org/viewvc/llvm-project?rev=342332&view=rev
Log:
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

Modified:
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/Common/Strings.cpp
    lld/trunk/test/COFF/undefined-symbol-cv.s
    lld/trunk/test/COFF/undefined-symbol.s

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=342332&r1=342331&r2=342332&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Sat Sep 15 11:27:09 2018
@@ -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(SectionCh
     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(Ob
         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(Ob
       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::reportRemainingUndefin
 
   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::reportRemainingUndefin
       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]");
     }
   }
 }

Modified: lld/trunk/Common/Strings.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/Common/Strings.cpp?rev=342332&r1=342331&r2=342332&view=diff
==============================================================================
--- lld/trunk/Common/Strings.cpp (original)
+++ lld/trunk/Common/Strings.cpp Sat Sep 15 11:27:09 2018
@@ -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::demangleItani
   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) {

Modified: lld/trunk/test/COFF/undefined-symbol-cv.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/undefined-symbol-cv.s?rev=342332&r1=342331&r2=342332&view=diff
==============================================================================
--- lld/trunk/test/COFF/undefined-symbol-cv.s (original)
+++ lld/trunk/test/COFF/undefined-symbol-cv.s Sat Sep 15 11:27:09 2018
@@ -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)
 

Modified: lld/trunk/test/COFF/undefined-symbol.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/undefined-symbol.s?rev=342332&r1=342331&r2=342332&view=diff
==============================================================================
--- lld/trunk/test/COFF/undefined-symbol.s (original)
+++ lld/trunk/test/COFF/undefined-symbol.s Sat Sep 15 11:27:09 2018
@@ -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




More information about the llvm-commits mailing list