Skip to content

Commit ae8fe4e

Browse files
author
Sunil Srivastava
committedMar 8, 2019
Improve "llvm-nm -f sysv" output for Elf files
Specifically, compute and Print Type and Section columns. This is a re-commit of rL354833, after fixing the Asan problem found a a buildbot. Differential Revision: https://reviews.llvm.org/D59060 llvm-svn: 355742
1 parent f84083b commit ae8fe4e

File tree

7 files changed

+77
-18
lines changed

7 files changed

+77
-18
lines changed
 

‎llvm/include/llvm/Object/ELFObjectFile.h

+13
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
namespace llvm {
4242
namespace object {
4343

44+
constexpr int NumElfSymbolTypes = 8;
45+
extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
46+
4447
class elf_symbol_iterator;
4548

4649
class ELFObjectFileBase : public ObjectFile {
@@ -148,6 +151,16 @@ class ELFSymbolRef : public SymbolRef {
148151
uint8_t getELFType() const {
149152
return getObject()->getSymbolELFType(getRawDataRefImpl());
150153
}
154+
155+
StringRef getELFTypeName() const {
156+
uint8_t Type = getELFType();
157+
for (auto &EE : ElfSymbolTypes) {
158+
if (EE.Value == Type) {
159+
return EE.AltName;
160+
}
161+
}
162+
return "";
163+
}
151164
};
152165

153166
class elf_symbol_iterator : public symbol_iterator {

‎llvm/lib/Object/ELFObjectFile.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
using namespace llvm;
3636
using namespace object;
3737

38+
const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = {
39+
{"None", "NOTYPE", ELF::STT_NOTYPE},
40+
{"Object", "OBJECT", ELF::STT_OBJECT},
41+
{"Function", "FUNC", ELF::STT_FUNC},
42+
{"Section", "SECTION", ELF::STT_SECTION},
43+
{"File", "FILE", ELF::STT_FILE},
44+
{"Common", "COMMON", ELF::STT_COMMON},
45+
{"TLS", "TLS", ELF::STT_TLS},
46+
{"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
47+
3848
ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
3949
: ObjectFile(Type, Source) {}
4050

‎llvm/test/Object/X86/nm-print-size.s

+6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
// RUN: llvm-mc %s -o %t -filetype=obj -triple=x86_64-pc-linux
22
// RUN: llvm-nm --print-size %t | FileCheck %s
3+
// RUN: llvm-nm -f sysv %t | FileCheck -check-prefix=SYSV %s
34

45
// CHECK: 0000000000000000 ffffffffffffffff n a
56
// CHECK: 0000000000000000 0000000000000000 N b
67
// CHECK: 0000000000000004 0000000000000004 C c
78
// CHECK: ffffffffffffffff 0000000000000000 a d
89

10+
// SYSV: a |0000000000000000| n | NOTYPE|ffffffffffffffff| |foo
11+
// SYSV: b |0000000000000000| N | NOTYPE|0000000000000000| |foo
12+
// SYSV: c |0000000000000004| C | OBJECT|0000000000000004| |*COM*
13+
// SYSV: d |ffffffffffffffff| a | NOTYPE|0000000000000000| |*ABS*
14+
915
.section foo
1016
a:
1117
.size a, 0xffffffffffffffff
+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
RUN: llvm-nm -f sysv %p/Inputs/hello.obj.elf-i386
12
RUN: llvm-nm -f sysv %p/Inputs/hello.obj.elf-i386 | FileCheck %s --strict-whitespace
23

34
CHECK: Name Value Class Type Size Line Section
4-
CHECK: .L.str |00000000| r | |0000000f| |
5-
CHECK: main |00000000| T | |00000015| |
6-
CHECK: puts | | U | | | |
5+
CHECK: .L.str |00000000| r | OBJECT|0000000f| |.rodata.str1.1
6+
CHECK: main |00000000| T | FUNC|00000015| |.text
7+
CHECK: puts | | U | NOTYPE| | |*UND*

‎llvm/test/tools/llvm-nm/X86/sysv-x86_64.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ RUN: llvm-nm -f sysv %p/Inputs/hello.obj.elf-x86_64 | FileCheck %s --check-prefi
22
RUN: llvm-nm -f sysv %p/Inputs/hello.obj.macho-x86_64 2>&1 | FileCheck %s --check-prefix=MACHO --strict-whitespace
33

44
ELF: Name Value Class Type Size Line Section
5-
ELF: main |0000000000000000| T | |0000000000000015| |
6-
ELF: puts | | U | | | |
5+
ELF: main |0000000000000000| T | FUNC|0000000000000015| |.text
6+
ELF: puts | | U | NOTYPE| | |*UND*
77

88
MACHO: Name Value Class Type Size Line Section
99
MACHO: EH_frame0 |0000000000000068| s | |0000000000000000| |

‎llvm/tools/llvm-nm/llvm-nm.cpp

+42-3
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ struct NMSymbol {
262262
uint64_t Size;
263263
char TypeChar;
264264
StringRef Name;
265+
StringRef SectionName;
266+
StringRef TypeName;
265267
BasicSymbolRef Sym;
266268
// The Sym field above points to the native symbol in the object file,
267269
// for Mach-O when we are creating symbols from the dyld info the above
@@ -882,8 +884,12 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
882884
std::string PaddedName(Name);
883885
while (PaddedName.length() < 20)
884886
PaddedName += " ";
887+
std::string TypeName = I->TypeName;
888+
if (TypeName.size() < 18)
889+
TypeName = std::string(18-TypeName.size(), ' ') + TypeName;
885890
outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar
886-
<< " | |" << SymbolSizeStr << "| |\n";
891+
<< " |" << TypeName << "|" << SymbolSizeStr << "| |"
892+
<< I->SectionName << "\n";
887893
}
888894
}
889895

@@ -1078,8 +1084,40 @@ static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
10781084
: elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
10791085
}
10801086

1081-
static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) {
1087+
// For ELF object files, Set TypeName to the symbol typename, to be printed
1088+
// in the 'Type' column of the SYSV format output.
1089+
static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I) {
1090+
if (isa<ELFObjectFileBase>(&Obj)) {
1091+
elf_symbol_iterator SymI(I);
1092+
return SymI->getELFTypeName();
1093+
}
1094+
return "";
1095+
}
1096+
1097+
// Return Posix nm class type tag (single letter), but also set SecName and
1098+
// section and name, to be used in format=sysv output.
1099+
static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
1100+
StringRef &SecName) {
10821101
uint32_t Symflags = I->getFlags();
1102+
if (isa<ELFObjectFileBase>(&Obj)) {
1103+
if (Symflags & object::SymbolRef::SF_Absolute)
1104+
SecName = "*ABS*";
1105+
else if (Symflags & object::SymbolRef::SF_Common)
1106+
SecName = "*COM*";
1107+
else if (Symflags & object::SymbolRef::SF_Undefined)
1108+
SecName = "*UND*";
1109+
else {
1110+
elf_symbol_iterator SymI(I);
1111+
Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
1112+
if (!SecIOrErr) {
1113+
consumeError(SecIOrErr.takeError());
1114+
return '?';
1115+
}
1116+
elf_section_iterator secT = *SecIOrErr;
1117+
secT->getName(SecName);
1118+
}
1119+
}
1120+
10831121
if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) {
10841122
char Ret = isObject(Obj, I) ? 'v' : 'w';
10851123
return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret;
@@ -1201,7 +1239,8 @@ dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
12011239
}
12021240
S.Address = *AddressOrErr;
12031241
}
1204-
S.TypeChar = getNMTypeChar(Obj, Sym);
1242+
S.TypeName = getNMTypeName(Obj, Sym);
1243+
S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName);
12051244
std::error_code EC = Sym.printName(OS);
12061245
if (EC && MachO)
12071246
OS << "bad string index";

‎llvm/tools/llvm-readobj/ELFDumper.cpp

-10
Original file line numberDiff line numberDiff line change
@@ -1114,16 +1114,6 @@ static const EnumEntry<unsigned> ElfSymbolVisibilities[] = {
11141114
{"HIDDEN", "HIDDEN", ELF::STV_HIDDEN},
11151115
{"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};
11161116

1117-
static const EnumEntry<unsigned> ElfSymbolTypes[] = {
1118-
{"None", "NOTYPE", ELF::STT_NOTYPE},
1119-
{"Object", "OBJECT", ELF::STT_OBJECT},
1120-
{"Function", "FUNC", ELF::STT_FUNC},
1121-
{"Section", "SECTION", ELF::STT_SECTION},
1122-
{"File", "FILE", ELF::STT_FILE},
1123-
{"Common", "COMMON", ELF::STT_COMMON},
1124-
{"TLS", "TLS", ELF::STT_TLS},
1125-
{"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
1126-
11271117
static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
11281118
{ "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL }
11291119
};

0 commit comments

Comments
 (0)
Please sign in to comment.