diff --git a/llvm/test/tools/llvm-nm/format-sysv-type.test b/llvm/test/tools/llvm-nm/format-sysv-type.test --- a/llvm/test/tools/llvm-nm/format-sysv-type.test +++ b/llvm/test/tools/llvm-nm/format-sysv-type.test @@ -1,5 +1,5 @@ # RUN: yaml2obj %s > %t.o -# RUN: llvm-nm %t.o --debug-syms --format=sysv | FileCheck %s +# RUN: llvm-nm %t.o --debug-syms --format=sysv --no-sort | FileCheck %s !ELF FileHeader: @@ -10,35 +10,53 @@ Symbols: - Name: symbol_notype Type: STT_NOTYPE + - Name: symbol_obj + Type: STT_OBJECT + - Name: symbol_function + Type: STT_FUNC + - Name: symbol_section + Type: STT_SECTION + - Name: symbol_file + Type: STT_FILE - Name: symbol_common Type: STT_COMMON - Name: symbol_tls Type: STT_TLS - - Name: symbol_file - Type: STT_FILE - - Name: symbol_obj - Type: STT_OBJECT - - Name: symbol_func - Type: STT_FUNC + - Name: symbol_unknown7 + Type: 7 + - Name: symbol_unknown8 + Type: 8 + - Name: symbol_unknown9 + Type: 9 - Name: symbol_ifunc Type: STT_GNU_IFUNC - - Name: os_specific + - Name: os_specific10 + Type: 10 + - Name: os_specific11 Type: 11 - - Name: proc_specific + - Name: os_specific12 + Type: 12 + - Name: proc_specific13 Type: 13 - - Name: unknown - Type: 7 - -## FIXME: Should not print blank types for unknown, OS-specific and processor- -## specific types. See https://bugs.llvm.org/show_bug.cgi?id=41713. + - Name: proc_specific14 + Type: 14 + - Name: proc_specific15 + Type: 15 -# CHECK: os_specific {{.*}}| | | |*UND* -# CHECK-NEXT: proc_specific {{.*}}| | | |*UND* -# CHECK-NEXT: symbol_common {{.*}}| COMMON| | |*COM* -# CHECK-NEXT: symbol_file {{.*}}| FILE| | |*UND* -# CHECK-NEXT: symbol_func {{.*}}| FUNC| | |*UND* -# CHECK-NEXT: symbol_ifunc {{.*}}| IFUNC| | |*UND* -# CHECK-NEXT: symbol_notype {{.*}}| NOTYPE| | |*UND* -# CHECK-NEXT: symbol_obj {{.*}}| OBJECT| | |*UND* -# CHECK-NEXT: symbol_tls {{.*}}| TLS| | |*UND* -# CHECK-NEXT: unknown {{.*}}| | | |*UND* +# CHECK: symbol_notype {{.*}}| NOTYPE| | |*UND* +# CHECK-NEXT: symbol_obj {{.*}}| OBJECT| | |*UND* +# CHECK-NEXT: symbol_function {{.*}}| FUNC| | |*UND* +# CHECK-NEXT: symbol_section {{.*}}| SECTION| | |*UND* +# CHECK-NEXT: symbol_file {{.*}}| FILE| | |*UND* +# CHECK-NEXT: symbol_common {{.*}}| COMMON| | |*COM* +# CHECK-NEXT: symbol_tls {{.*}}| TLS| | |*UND* +# CHECK-NEXT: symbol_unknown7 {{.*}}| : 7| | |*UND* +# CHECK-NEXT: symbol_unknown8 {{.*}}| : 8| | |*UND* +# CHECK-NEXT: symbol_unknown9 {{.*}}| : 9| | |*UND* +# CHECK-NEXT: symbol_ifunc {{.*}}| : 10| | |*UND* +# CHECK-NEXT: os_specific10 {{.*}}| : 10| | |*UND* +# CHECK-NEXT: os_specific11 {{.*}}| : 11| | |*UND* +# CHECK-NEXT: os_specific12 {{.*}}| : 12| | |*UND* +# CHECK-NEXT: proc_specific13 {{.*}}|: 13| | |*UND* +# CHECK-NEXT: proc_specific14 {{.*}}|: 14| | |*UND* +# CHECK-NEXT: proc_specific15 {{.*}}|: 15| | |*UND* diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -289,6 +289,7 @@ StringRef Name; StringRef SectionName; StringRef TypeName; + std::string GnuTypeName; BasicSymbolRef Sym; // The Sym field above points to the native symbol in the object file, // for Mach-O when we are creating symbols from the dyld info the above @@ -875,7 +876,7 @@ outs() << "\n"; } else if (OutputFormat == sysv) { outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "| " - << S.TypeChar << " |" << right_justify(S.TypeName, 18) << "|" + << S.TypeChar << " |" << right_justify(S.GnuTypeName, 18) << "|" << SymbolSizeStr << "| |" << S.SectionName << "\n"; } } @@ -1063,12 +1064,24 @@ // For ELF object files, Set TypeName to the symbol typename, to be printed // in the 'Type' column of the SYSV format output. -static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I) { +static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I, + std::string &GnuTypeName) { + StringRef TypeName; if (isa(&Obj)) { elf_symbol_iterator SymI(I); - return SymI->getELFTypeName(); + TypeName = SymI->getELFTypeName(); + if (TypeName.empty() || TypeName.equals("IFUNC")) { + uint8_t Type = SymI->getELFType(); + if (Type > ELF::STT_TLS && Type < ELF::STT_GNU_IFUNC) + GnuTypeName = ": " + std::to_string(Type); + else if (Type >= ELF::STT_LOOS && Type <= ELF::STT_HIOS) + GnuTypeName = ": " + std::to_string(Type); + else if (Type >= ELF::STT_LOPROC && Type <= ELF::STT_HIPROC) + GnuTypeName = ": " + std::to_string(Type); + } else + GnuTypeName = TypeName; } - return ""; + return TypeName; } // Return Posix nm class type tag (single letter), but also set SecName and @@ -1218,7 +1231,7 @@ } S.Address = *AddressOrErr; } - S.TypeName = getNMTypeName(Obj, Sym); + S.TypeName = getNMTypeName(Obj, Sym, S.GnuTypeName); S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName); if (Error E = Sym.printName(OS)) { if (MachO) {