[llvm] r306718 - llvm-nm: Add support for symbol demangling (-C/--demangle)

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 29 11:29:05 PDT 2017


Author: sbc
Date: Thu Jun 29 11:29:05 2017
New Revision: 306718

URL: http://llvm.org/viewvc/llvm-project?rev=306718&view=rev
Log:
llvm-nm: Add support for symbol demangling (-C/--demangle)

Differential Revision: https://reviews.llvm.org/D34668

Added:
    llvm/trunk/test/tools/llvm-nm/X86/demangle.ll
Modified:
    llvm/trunk/docs/CommandGuide/llvm-nm.rst
    llvm/trunk/tools/llvm-nm/CMakeLists.txt
    llvm/trunk/tools/llvm-nm/llvm-nm.cpp

Modified: llvm/trunk/docs/CommandGuide/llvm-nm.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-nm.rst?rev=306718&r1=306717&r2=306718&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-nm.rst (original)
+++ llvm/trunk/docs/CommandGuide/llvm-nm.rst Thu Jun 29 11:29:05 2017
@@ -134,9 +134,6 @@ OPTIONS
 BUGS
 ----
 
- * :program:`llvm-nm` cannot demangle C++ mangled names, like GNU :program:`nm`
-   can.
-
  * :program:`llvm-nm` does not support the full set of arguments that GNU
    :program:`nm` does.
 

Added: llvm/trunk/test/tools/llvm-nm/X86/demangle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/X86/demangle.ll?rev=306718&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/X86/demangle.ll (added)
+++ llvm/trunk/test/tools/llvm-nm/X86/demangle.ll Thu Jun 29 11:29:05 2017
@@ -0,0 +1,37 @@
+; RUN: llc -filetype=obj -mtriple=x86_64-pc-linux -o %t.o %s
+; RUN: llvm-nm %t.o | FileCheck --check-prefix="MANGLED" %s
+; RUN: llvm-nm -C %t.o | FileCheck --check-prefix="DEMANGLED" %s
+; RUN: llvm-nm --demangle %t.o | FileCheck --check-prefix="DEMANGLED" %s
+
+; RUN: llc -filetype=obj -mtriple=x86_64-apple-darwin9 -o %t.macho %s
+; RUN: llvm-nm %t.macho | FileCheck --check-prefix="MACHO-MANGLED" %s
+; RUN: llvm-nm -C %t.macho | FileCheck --check-prefix="DEMANGLED" %s
+
+; RUN: llc -filetype=obj -mtriple=x86_64-pc-win32 -o %t.coff %s
+; RUN: llvm-nm %t.coff | FileCheck --check-prefix="COFF-MANGLED" %s
+; RUN: llvm-nm -C %t.coff | FileCheck --check-prefix="COFF-DEMANGLED" %s
+
+define i32 @_Z3fooi(i32) #0 {
+entry:
+  ret i32 1
+}
+
+define float @_Z3barf(float) #0 {
+entry:
+  ret float 0.000000e+00
+}
+
+; MANGLED:       0000000000000010 T _Z3barf
+; MANGLED:       0000000000000000 T _Z3fooi
+
+; MACHO-MANGLED: 0000000000000010 T __Z3barf
+; MACHO-MANGLED: 0000000000000000 T __Z3fooi
+
+; COFF-MANGLED:          00000010 T _Z3barf
+; COFF-MANGLED:          00000000 T _Z3fooi
+
+; DEMANGLED:     0000000000000010 T bar(float)
+; DEMANGLED:     0000000000000000 T foo(int)
+
+; COFF-DEMANGLED:        00000010 T bar(float)
+; COFF-DEMANGLED:        00000000 T foo(int)

Modified: llvm/trunk/tools/llvm-nm/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/CMakeLists.txt?rev=306718&r1=306717&r2=306718&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-nm/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-nm/CMakeLists.txt Thu Jun 29 11:29:05 2017
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
   AllTargetsDescs
   AllTargetsInfos
   Core
+  Demangle
   Object
   Support
   )

Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=306718&r1=306717&r2=306718&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
+++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Thu Jun 29 11:29:05 2017
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Demangle/Demangle.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalVariable.h"
@@ -124,6 +125,10 @@ cl::opt<bool> NoSort("no-sort", cl::desc
 cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort),
                   cl::Grouping);
 
+cl::opt<bool> Demangle("demangle", cl::desc("Demangle C++ symbol names"));
+cl::alias DemangleC("C", cl::desc("Alias for --demangle"), cl::aliasopt(Demangle),
+                    cl::Grouping);
+
 cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order"));
 cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"),
                        cl::aliasopt(ReverseSort), cl::Grouping);
@@ -659,6 +664,22 @@ static void darwinPrintStab(MachOObjectF
   outs() << Str;
 }
 
+static Optional<std::string> demangle(StringRef Name, bool StripUnderscore) {
+  if (StripUnderscore && Name.size() > 0 && Name[0] == '_')
+    Name = Name.substr(1);
+
+  if (!Name.startswith("_Z"))
+    return None;
+
+  int Status;
+  std::unique_ptr<char> Undecorated(
+      itaniumDemangle(Name.str().c_str(), nullptr, nullptr, &Status));
+  if (Status != 0)
+    return None;
+
+  return std::string(Undecorated.get());
+}
+
 static bool symbolIsDefined(const NMSymbol &Sym) {
   return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v';
 }
@@ -724,6 +745,12 @@ static void sortAndPrintSymbolList(Symbo
   for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
        I != E; ++I) {
     uint32_t SymFlags;
+    std::string Name = I->Name.str();
+    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
+    if (Demangle) {
+      if (Optional<std::string> Opt = demangle(I->Name, MachO))
+        Name = *Opt;
+    }
     if (I->Sym.getRawDataRefImpl().p)
       SymFlags = I->Sym.getFlags();
     else
@@ -745,9 +772,10 @@ static void sortAndPrintSymbolList(Symbo
         outs() << CurrentFilename << ": ";
       }
     }
-    if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) &&
-                            OutputFormat != darwin)) && OutputFormat != posix) {
-      outs() << I->Name << "\n";
+    if ((JustSymbolName ||
+         (UndefinedOnly && MachO && OutputFormat != darwin)) &&
+        OutputFormat != posix) {
+      outs() << Name << "\n";
       continue;
     }
 
@@ -767,7 +795,6 @@ static void sortAndPrintSymbolList(Symbo
       }
     }
 
-    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
     // Otherwise, print the symbol address and size.
     if (symbolIsDefined(*I)) {
       if (Obj.isIR())
@@ -789,7 +816,7 @@ static void sortAndPrintSymbolList(Symbo
       darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes,
                         printFormat);
     } else if (OutputFormat == posix) {
-      outs() << I->Name << " " << I->TypeChar << " ";
+      outs() << Name << " " << I->TypeChar << " ";
       if (MachO)
         outs() << SymbolAddrStr << " " << "0" /* SymbolSizeStr */ << "\n";
       else
@@ -804,7 +831,7 @@ static void sortAndPrintSymbolList(Symbo
       outs() << I->TypeChar;
       if (I->TypeChar == '-' && MachO)
         darwinPrintStab(MachO, I);
-      outs() << " " << I->Name;
+      outs() << " " << Name;
       if (I->TypeChar == 'I' && MachO) {
         outs() << " (indirect for ";
         if (I->Sym.getRawDataRefImpl().p) {
@@ -818,7 +845,7 @@ static void sortAndPrintSymbolList(Symbo
       }
       outs() << "\n";
     } else if (OutputFormat == sysv) {
-      std::string PaddedName(I->Name);
+      std::string PaddedName(Name);
       while (PaddedName.length() < 20)
         PaddedName += " ";
       outs() << PaddedName << "|" << SymbolAddrStr << "|   " << I->TypeChar




More information about the llvm-commits mailing list