llvm.org GIT mirror llvm / a79c4fe
llvm-nm: Add support for symbol demangling (-C/--demangle) Differential Revision: https://reviews.llvm.org/D34668 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306718 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 2 years ago
4 changed file(s) with 72 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
133133 BUGS
134134 ----
135135
136 * :program:`llvm-nm` cannot demangle C++ mangled names, like GNU :program:`nm`
137 can.
138
139136 * :program:`llvm-nm` does not support the full set of arguments that GNU
140137 :program:`nm` does.
141138
0 ; RUN: llc -filetype=obj -mtriple=x86_64-pc-linux -o %t.o %s
1 ; RUN: llvm-nm %t.o | FileCheck --check-prefix="MANGLED" %s
2 ; RUN: llvm-nm -C %t.o | FileCheck --check-prefix="DEMANGLED" %s
3 ; RUN: llvm-nm --demangle %t.o | FileCheck --check-prefix="DEMANGLED" %s
4
5 ; RUN: llc -filetype=obj -mtriple=x86_64-apple-darwin9 -o %t.macho %s
6 ; RUN: llvm-nm %t.macho | FileCheck --check-prefix="MACHO-MANGLED" %s
7 ; RUN: llvm-nm -C %t.macho | FileCheck --check-prefix="DEMANGLED" %s
8
9 ; RUN: llc -filetype=obj -mtriple=x86_64-pc-win32 -o %t.coff %s
10 ; RUN: llvm-nm %t.coff | FileCheck --check-prefix="COFF-MANGLED" %s
11 ; RUN: llvm-nm -C %t.coff | FileCheck --check-prefix="COFF-DEMANGLED" %s
12
13 define i32 @_Z3fooi(i32) #0 {
14 entry:
15 ret i32 1
16 }
17
18 define float @_Z3barf(float) #0 {
19 entry:
20 ret float 0.000000e+00
21 }
22
23 ; MANGLED: 0000000000000010 T _Z3barf
24 ; MANGLED: 0000000000000000 T _Z3fooi
25
26 ; MACHO-MANGLED: 0000000000000010 T __Z3barf
27 ; MACHO-MANGLED: 0000000000000000 T __Z3fooi
28
29 ; COFF-MANGLED: 00000010 T _Z3barf
30 ; COFF-MANGLED: 00000000 T _Z3fooi
31
32 ; DEMANGLED: 0000000000000010 T bar(float)
33 ; DEMANGLED: 0000000000000000 T foo(int)
34
35 ; COFF-DEMANGLED: 00000010 T bar(float)
36 ; COFF-DEMANGLED: 00000000 T foo(int)
22 AllTargetsDescs
33 AllTargetsInfos
44 Core
5 Demangle
56 Object
67 Support
78 )
1717
1818 #include "llvm/ADT/StringSwitch.h"
1919 #include "llvm/BinaryFormat/COFF.h"
20 #include "llvm/Demangle/Demangle.h"
2021 #include "llvm/IR/Function.h"
2122 #include "llvm/IR/GlobalAlias.h"
2223 #include "llvm/IR/GlobalVariable.h"
122123 cl::opt NoSort("no-sort", cl::desc("Show symbols in order encountered"));
123124 cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort),
124125 cl::Grouping);
126
127 cl::opt Demangle("demangle", cl::desc("Demangle C++ symbol names"));
128 cl::alias DemangleC("C", cl::desc("Alias for --demangle"), cl::aliasopt(Demangle),
129 cl::Grouping);
125130
126131 cl::opt ReverseSort("reverse-sort", cl::desc("Sort in reverse order"));
127132 cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"),
658663 outs() << Str;
659664 }
660665
666 static Optional demangle(StringRef Name, bool StripUnderscore) {
667 if (StripUnderscore && Name.size() > 0 && Name[0] == '_')
668 Name = Name.substr(1);
669
670 if (!Name.startswith("_Z"))
671 return None;
672
673 int Status;
674 std::unique_ptr Undecorated(
675 itaniumDemangle(Name.str().c_str(), nullptr, nullptr, &Status));
676 if (Status != 0)
677 return None;
678
679 return std::string(Undecorated.get());
680 }
681
661682 static bool symbolIsDefined(const NMSymbol &Sym) {
662683 return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v';
663684 }
723744 for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
724745 I != E; ++I) {
725746 uint32_t SymFlags;
747 std::string Name = I->Name.str();
748 MachOObjectFile *MachO = dyn_cast(&Obj);
749 if (Demangle) {
750 if (Optional Opt = demangle(I->Name, MachO))
751 Name = *Opt;
752 }
726753 if (I->Sym.getRawDataRefImpl().p)
727754 SymFlags = I->Sym.getFlags();
728755 else
744771 outs() << CurrentFilename << ": ";
745772 }
746773 }
747 if ((JustSymbolName || (UndefinedOnly && isa(Obj) &&
748 OutputFormat != darwin)) && OutputFormat != posix) {
749 outs() << I->Name << "\n";
774 if ((JustSymbolName ||
775 (UndefinedOnly && MachO && OutputFormat != darwin)) &&
776 OutputFormat != posix) {
777 outs() << Name << "\n";
750778 continue;
751779 }
752780
766794 }
767795 }
768796
769 MachOObjectFile *MachO = dyn_cast(&Obj);
770797 // Otherwise, print the symbol address and size.
771798 if (symbolIsDefined(*I)) {
772799 if (Obj.isIR())
788815 darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes,
789816 printFormat);
790817 } else if (OutputFormat == posix) {
791 outs() << I->Name << " " << I->TypeChar << " ";
818 outs() << Name << " " << I->TypeChar << " ";
792819 if (MachO)
793820 outs() << SymbolAddrStr << " " << "0" /* SymbolSizeStr */ << "\n";
794821 else
803830 outs() << I->TypeChar;
804831 if (I->TypeChar == '-' && MachO)
805832 darwinPrintStab(MachO, I);
806 outs() << " " << I->Name;
833 outs() << " " << Name;
807834 if (I->TypeChar == 'I' && MachO) {
808835 outs() << " (indirect for ";
809836 if (I->Sym.getRawDataRefImpl().p) {
817844 }
818845 outs() << "\n";
819846 } else if (OutputFormat == sysv) {
820 std::string PaddedName(I->Name);
847 std::string PaddedName(Name);
821848 while (PaddedName.length() < 20)
822849 PaddedName += " ";
823850 outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar