mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[llvm-objdump] Teach llvm-objdump
dump dynamic symbols.
Summary: This patch is to teach `llvm-objdump` dump dynamic symbols (`-T` and `--dynamic-syms`). Currently, this patch is not fully compatible with `gnu-objdump`, but I would like to continue working on this in next few patches. It has two issues. 1. Some symbols shouldn't be marked as global(g). (`-t/--syms` has same issue as well) (Fixed by D75659) 2. `gnu-objdump` can dump version information and *dynamically* insert before symbol name field. `objdump -T a.out` gives: ``` DYNAMIC SYMBOL TABLE: 0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize ``` `llvm-objdump -T a.out` gives: ``` DYNAMIC SYMBOL TABLE: 0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable 0000000000000000 g DF *UND* 0000000000000000 printf 0000000000000000 g DF *UND* 0000000000000000 __libc_start_main 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable 0000000000000000 w DF *UND* 0000000000000000 __cxa_finalize ``` Reviewers: jhenderson, grimar, MaskRay, espindola Reviewed By: jhenderson, grimar Subscribers: emaste, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75756
This commit is contained in:
parent
b1f5813526
commit
4e26366ac1
@ -85,6 +85,10 @@ combined with other commands:
|
||||
|
||||
Display the symbol table.
|
||||
|
||||
.. option:: -T, --dynamic-syms
|
||||
|
||||
Display the contents of the dynamic symbol table.
|
||||
|
||||
.. option:: -u, --unwind-info
|
||||
|
||||
Display the unwind info of the input(s).
|
||||
|
107
test/tools/llvm-objdump/X86/elf-dynamic-symbols.test
Normal file
107
test/tools/llvm-objdump/X86/elf-dynamic-symbols.test
Normal file
@ -0,0 +1,107 @@
|
||||
## Test that llvm-objdump can dump dynamic symbols.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t1
|
||||
# RUN: llvm-objdump --dynamic-syms %t1 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=DYNSYM
|
||||
# RUN: llvm-objdump -T %t1 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=DYNSYM
|
||||
|
||||
# DYNSYM:DYNAMIC SYMBOL TABLE:
|
||||
# DYNSYM-NEXT:0000000000000000 l DO .data 0000000000000000 localsym
|
||||
# DYNSYM-NEXT:0000000000000000 g DO .data 0000000000000000 globalsym
|
||||
# DYNSYM-NEXT:0000000000000000 u DO .data 0000000000000000 uniqueglobalsym
|
||||
# DYNSYM-NEXT:0000000000000000 w DO .data 0000000000000000 weaksym
|
||||
# DYNSYM-NEXT:0000000000000000 g Df .data 0000000000000000 filesym
|
||||
# DYNSYM-NEXT:0000000000000000 g DF .data 0000000000000000 funcsym
|
||||
# DYNSYM-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
||||
DynamicSymbols:
|
||||
- Name: localsym
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Binding: STB_LOCAL
|
||||
- Name: globalsym
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Binding: STB_GLOBAL
|
||||
- Name: uniqueglobalsym
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Binding: STB_GNU_UNIQUE
|
||||
- Name: weaksym
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Binding: STB_WEAK
|
||||
- Name: filesym
|
||||
Type: STT_FILE
|
||||
Section: .data
|
||||
Binding: STB_GLOBAL
|
||||
- Name: funcsym
|
||||
Type: STT_FUNC
|
||||
Section: .data
|
||||
Binding: STB_GLOBAL
|
||||
|
||||
## Test dumping ELF files with no .dynsym section.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t2
|
||||
# RUN: llvm-objdump --dynamic-syms %t2 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=NODYNSYM
|
||||
# RUN: llvm-objdump -T %t2 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=NODYNSYM
|
||||
|
||||
# NODYNSYM:DYNAMIC SYMBOL TABLE:
|
||||
# NODYNSYM-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
|
||||
## Test dumping ELF files with logically empty .dynsym section (only has a 0-index NULL symbol).
|
||||
# RUN: yaml2obj --docnum=3 %s -o %t3
|
||||
# RUN: llvm-objdump --dynamic-syms %t3 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=ONLY-NULL
|
||||
# RUN: llvm-objdump -T %t3 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=ONLY-NULL
|
||||
|
||||
# ONLY-NULL:DYNAMIC SYMBOL TABLE:
|
||||
# ONLY-NULL-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
DynamicSymbols: []
|
||||
|
||||
## Test dumping ELF files with truly empty .dynsym section (size of .dynsym section is 0).
|
||||
# RUN: yaml2obj --docnum=4 %s -o %t4
|
||||
# RUN: llvm-objdump --dynamic-syms %t4 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=EMPTY
|
||||
# RUN: llvm-objdump -T %t4 | \
|
||||
# RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=EMPTY
|
||||
|
||||
# EMPTY:DYNAMIC SYMBOL TABLE:
|
||||
# EMPTY-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .dynsym
|
||||
Type: SHT_DYNSYM
|
||||
Size: 0
|
31
test/tools/llvm-objdump/unimplemented-features.test
Normal file
31
test/tools/llvm-objdump/unimplemented-features.test
Normal file
@ -0,0 +1,31 @@
|
||||
## Test dumping dynamic symbols reports a warning if the operation is unsupported for the file format.
|
||||
# RUN: yaml2obj %s --docnum=1 -o %t.macho.o
|
||||
# RUN: llvm-objdump --dynamic-syms %t.macho.o 2>&1 | \
|
||||
# RUN: FileCheck %s -DFILE=%t.macho.o
|
||||
# RUN: yaml2obj %s --docnum=2 -o %t.coff.o
|
||||
# RUN: llvm-objdump --dynamic-syms %t.coff.o 2>&1 | \
|
||||
# RUN: FileCheck %s -DFILE=%t.coff.o
|
||||
# RUN: llvm-objdump --dynamic-syms %p/XCOFF/Inputs/xcoff-section-headers.o 2>&1 | \
|
||||
# RUN: FileCheck %s -DFILE=%p/XCOFF/Inputs/xcoff-section-headers.o
|
||||
|
||||
# CHECK:DYNAMIC SYMBOL TABLE:
|
||||
# CHECK-NEXT:{{.*}}llvm-objdump: warning: '[[FILE]]': this operation is not currently supported for this file format
|
||||
# CHECK-EMPTY:
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x80000003
|
||||
filetype: 0x00000002
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00218085
|
||||
reserved: 0x00000000
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: []
|
||||
sections: []
|
||||
symbols: []
|
@ -321,6 +321,15 @@ static cl::alias SymbolTableShort("t", cl::desc("Alias for --syms"),
|
||||
cl::NotHidden, cl::Grouping,
|
||||
cl::aliasopt(SymbolTable));
|
||||
|
||||
cl::opt<bool> DynamicSymbolTable(
|
||||
"dynamic-syms",
|
||||
cl::desc("Display the contents of the dynamic symbol table"),
|
||||
cl::cat(ObjdumpCat));
|
||||
static cl::alias DynamicSymbolTableShort("T",
|
||||
cl::desc("Alias for --dynamic-syms"),
|
||||
cl::NotHidden, cl::Grouping,
|
||||
cl::aliasopt(DynamicSymbolTable));
|
||||
|
||||
cl::opt<std::string> TripleName("triple",
|
||||
cl::desc("Target triple to disassemble for, "
|
||||
"see -version for available targets"),
|
||||
@ -1857,143 +1866,167 @@ void printSectionContents(const ObjectFile *Obj) {
|
||||
}
|
||||
|
||||
void printSymbolTable(const ObjectFile *O, StringRef ArchiveName,
|
||||
StringRef ArchitectureName) {
|
||||
outs() << "SYMBOL TABLE:\n";
|
||||
|
||||
if (const COFFObjectFile *Coff = dyn_cast<const COFFObjectFile>(O)) {
|
||||
printCOFFSymbolTable(Coff);
|
||||
StringRef ArchitectureName, bool DumpDynamic) {
|
||||
if (O->isCOFF() && !DumpDynamic) {
|
||||
outs() << "SYMBOL TABLE:\n";
|
||||
printCOFFSymbolTable(cast<const COFFObjectFile>(O));
|
||||
return;
|
||||
}
|
||||
|
||||
const StringRef FileName = O->getFileName();
|
||||
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(O);
|
||||
for (auto I = O->symbol_begin(), E = O->symbol_end(); I != E; ++I) {
|
||||
const SymbolRef &Symbol = *I;
|
||||
uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName, ArchiveName,
|
||||
ArchitectureName);
|
||||
if ((Address < StartAddress) || (Address > StopAddress))
|
||||
continue;
|
||||
SymbolRef::Type Type = unwrapOrError(Symbol.getType(), FileName,
|
||||
ArchiveName, ArchitectureName);
|
||||
uint32_t Flags = Symbol.getFlags();
|
||||
|
||||
// Don't ask a Mach-O STAB symbol for its section unless you know that
|
||||
// STAB symbol's section field refers to a valid section index. Otherwise
|
||||
// the symbol may error trying to load a section that does not exist.
|
||||
bool isSTAB = false;
|
||||
if (MachO) {
|
||||
DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
|
||||
uint8_t NType = (MachO->is64Bit() ?
|
||||
MachO->getSymbol64TableEntry(SymDRI).n_type:
|
||||
MachO->getSymbolTableEntry(SymDRI).n_type);
|
||||
if (NType & MachO::N_STAB)
|
||||
isSTAB = true;
|
||||
}
|
||||
section_iterator Section = isSTAB ? O->section_end() :
|
||||
unwrapOrError(Symbol.getSection(), FileName,
|
||||
ArchiveName, ArchitectureName);
|
||||
|
||||
StringRef Name;
|
||||
if (Type == SymbolRef::ST_Debug && Section != O->section_end()) {
|
||||
if (Expected<StringRef> NameOrErr = Section->getName())
|
||||
Name = *NameOrErr;
|
||||
else
|
||||
consumeError(NameOrErr.takeError());
|
||||
|
||||
} else {
|
||||
Name = unwrapOrError(Symbol.getName(), FileName, ArchiveName,
|
||||
ArchitectureName);
|
||||
}
|
||||
|
||||
bool Global = Flags & SymbolRef::SF_Global;
|
||||
bool Weak = Flags & SymbolRef::SF_Weak;
|
||||
bool Absolute = Flags & SymbolRef::SF_Absolute;
|
||||
bool Common = Flags & SymbolRef::SF_Common;
|
||||
bool Hidden = Flags & SymbolRef::SF_Hidden;
|
||||
|
||||
char GlobLoc = ' ';
|
||||
if ((Section != O->section_end() || Absolute) && !Weak)
|
||||
GlobLoc = Global ? 'g' : 'l';
|
||||
char IFunc = ' ';
|
||||
if (isa<ELFObjectFileBase>(O)) {
|
||||
if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
|
||||
IFunc = 'i';
|
||||
if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
|
||||
GlobLoc = 'u';
|
||||
}
|
||||
char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
|
||||
? 'd' : ' ';
|
||||
char FileFunc = ' ';
|
||||
if (Type == SymbolRef::ST_File)
|
||||
FileFunc = 'f';
|
||||
else if (Type == SymbolRef::ST_Function)
|
||||
FileFunc = 'F';
|
||||
else if (Type == SymbolRef::ST_Data)
|
||||
FileFunc = 'O';
|
||||
|
||||
const char *Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 :
|
||||
"%08" PRIx64;
|
||||
|
||||
outs() << format(Fmt, Address) << " "
|
||||
<< GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
|
||||
<< (Weak ? 'w' : ' ') // Weak?
|
||||
<< ' ' // Constructor. Not supported yet.
|
||||
<< ' ' // Warning. Not supported yet.
|
||||
<< IFunc
|
||||
<< Debug // Debugging (d) or dynamic (D) symbol.
|
||||
<< FileFunc // Name of function (F), file (f) or object (O).
|
||||
<< ' ';
|
||||
if (Absolute) {
|
||||
outs() << "*ABS*";
|
||||
} else if (Common) {
|
||||
outs() << "*COM*";
|
||||
} else if (Section == O->section_end()) {
|
||||
outs() << "*UND*";
|
||||
} else {
|
||||
if (const MachOObjectFile *MachO =
|
||||
dyn_cast<const MachOObjectFile>(O)) {
|
||||
DataRefImpl DR = Section->getRawDataRefImpl();
|
||||
StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
|
||||
outs() << SegmentName << ",";
|
||||
}
|
||||
StringRef SectionName =
|
||||
unwrapOrError(Section->getName(), O->getFileName());
|
||||
outs() << SectionName;
|
||||
}
|
||||
|
||||
if (Common || isa<ELFObjectFileBase>(O)) {
|
||||
uint64_t Val =
|
||||
Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
|
||||
outs() << '\t' << format(Fmt, Val);
|
||||
}
|
||||
|
||||
if (isa<ELFObjectFileBase>(O)) {
|
||||
uint8_t Other = ELFSymbolRef(Symbol).getOther();
|
||||
switch (Other) {
|
||||
case ELF::STV_DEFAULT:
|
||||
break;
|
||||
case ELF::STV_INTERNAL:
|
||||
outs() << " .internal";
|
||||
break;
|
||||
case ELF::STV_HIDDEN:
|
||||
outs() << " .hidden";
|
||||
break;
|
||||
case ELF::STV_PROTECTED:
|
||||
outs() << " .protected";
|
||||
break;
|
||||
default:
|
||||
outs() << format(" 0x%02x", Other);
|
||||
break;
|
||||
}
|
||||
} else if (Hidden) {
|
||||
outs() << " .hidden";
|
||||
}
|
||||
|
||||
if (Demangle)
|
||||
outs() << ' ' << demangle(std::string(Name)) << '\n';
|
||||
else
|
||||
outs() << ' ' << Name << '\n';
|
||||
if (!DumpDynamic) {
|
||||
outs() << "SYMBOL TABLE:\n";
|
||||
for (auto I = O->symbol_begin(); I != O->symbol_end(); ++I)
|
||||
printSymbol(O, *I, FileName, ArchiveName, ArchitectureName, DumpDynamic);
|
||||
return;
|
||||
}
|
||||
|
||||
outs() << "DYNAMIC SYMBOL TABLE:\n";
|
||||
if (!O->isELF()) {
|
||||
reportWarning(
|
||||
"this operation is not currently supported for this file format",
|
||||
FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
const ELFObjectFileBase *ELF = cast<const ELFObjectFileBase>(O);
|
||||
for (auto I = ELF->getDynamicSymbolIterators().begin();
|
||||
I != ELF->getDynamicSymbolIterators().end(); ++I)
|
||||
printSymbol(O, *I, FileName, ArchiveName, ArchitectureName, DumpDynamic);
|
||||
}
|
||||
|
||||
void printSymbol(const ObjectFile *O, const SymbolRef &Symbol,
|
||||
StringRef FileName, StringRef ArchiveName,
|
||||
StringRef ArchitectureName, bool DumpDynamic) {
|
||||
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(O);
|
||||
uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName, ArchiveName,
|
||||
ArchitectureName);
|
||||
if ((Address < StartAddress) || (Address > StopAddress))
|
||||
return;
|
||||
SymbolRef::Type Type =
|
||||
unwrapOrError(Symbol.getType(), FileName, ArchiveName, ArchitectureName);
|
||||
uint32_t Flags = Symbol.getFlags();
|
||||
|
||||
// Don't ask a Mach-O STAB symbol for its section unless you know that
|
||||
// STAB symbol's section field refers to a valid section index. Otherwise
|
||||
// the symbol may error trying to load a section that does not exist.
|
||||
bool IsSTAB = false;
|
||||
if (MachO) {
|
||||
DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
|
||||
uint8_t NType =
|
||||
(MachO->is64Bit() ? MachO->getSymbol64TableEntry(SymDRI).n_type
|
||||
: MachO->getSymbolTableEntry(SymDRI).n_type);
|
||||
if (NType & MachO::N_STAB)
|
||||
IsSTAB = true;
|
||||
}
|
||||
section_iterator Section = IsSTAB
|
||||
? O->section_end()
|
||||
: unwrapOrError(Symbol.getSection(), FileName,
|
||||
ArchiveName, ArchitectureName);
|
||||
|
||||
StringRef Name;
|
||||
if (Type == SymbolRef::ST_Debug && Section != O->section_end()) {
|
||||
if (Expected<StringRef> NameOrErr = Section->getName())
|
||||
Name = *NameOrErr;
|
||||
else
|
||||
consumeError(NameOrErr.takeError());
|
||||
|
||||
} else {
|
||||
Name = unwrapOrError(Symbol.getName(), FileName, ArchiveName,
|
||||
ArchitectureName);
|
||||
}
|
||||
|
||||
bool Global = Flags & SymbolRef::SF_Global;
|
||||
bool Weak = Flags & SymbolRef::SF_Weak;
|
||||
bool Absolute = Flags & SymbolRef::SF_Absolute;
|
||||
bool Common = Flags & SymbolRef::SF_Common;
|
||||
bool Hidden = Flags & SymbolRef::SF_Hidden;
|
||||
|
||||
char GlobLoc = ' ';
|
||||
if ((Section != O->section_end() || Absolute) && !Weak)
|
||||
GlobLoc = Global ? 'g' : 'l';
|
||||
char IFunc = ' ';
|
||||
if (isa<ELFObjectFileBase>(O)) {
|
||||
if (ELFSymbolRef(Symbol).getELFType() == ELF::STT_GNU_IFUNC)
|
||||
IFunc = 'i';
|
||||
if (ELFSymbolRef(Symbol).getBinding() == ELF::STB_GNU_UNIQUE)
|
||||
GlobLoc = 'u';
|
||||
}
|
||||
|
||||
char Debug = ' ';
|
||||
if (DumpDynamic)
|
||||
Debug = 'D';
|
||||
else if (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
|
||||
Debug = 'd';
|
||||
|
||||
char FileFunc = ' ';
|
||||
if (Type == SymbolRef::ST_File)
|
||||
FileFunc = 'f';
|
||||
else if (Type == SymbolRef::ST_Function)
|
||||
FileFunc = 'F';
|
||||
else if (Type == SymbolRef::ST_Data)
|
||||
FileFunc = 'O';
|
||||
|
||||
const char *Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
|
||||
|
||||
outs() << format(Fmt, Address) << " "
|
||||
<< GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
|
||||
<< (Weak ? 'w' : ' ') // Weak?
|
||||
<< ' ' // Constructor. Not supported yet.
|
||||
<< ' ' // Warning. Not supported yet.
|
||||
<< IFunc // Indirect reference to another symbol.
|
||||
<< Debug // Debugging (d) or dynamic (D) symbol.
|
||||
<< FileFunc // Name of function (F), file (f) or object (O).
|
||||
<< ' ';
|
||||
if (Absolute) {
|
||||
outs() << "*ABS*";
|
||||
} else if (Common) {
|
||||
outs() << "*COM*";
|
||||
} else if (Section == O->section_end()) {
|
||||
outs() << "*UND*";
|
||||
} else {
|
||||
if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(O)) {
|
||||
DataRefImpl DR = Section->getRawDataRefImpl();
|
||||
StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
|
||||
outs() << SegmentName << ",";
|
||||
}
|
||||
StringRef SectionName = unwrapOrError(Section->getName(), FileName);
|
||||
outs() << SectionName;
|
||||
}
|
||||
|
||||
if (Common || isa<ELFObjectFileBase>(O)) {
|
||||
uint64_t Val =
|
||||
Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
|
||||
outs() << '\t' << format(Fmt, Val);
|
||||
}
|
||||
|
||||
if (isa<ELFObjectFileBase>(O)) {
|
||||
uint8_t Other = ELFSymbolRef(Symbol).getOther();
|
||||
switch (Other) {
|
||||
case ELF::STV_DEFAULT:
|
||||
break;
|
||||
case ELF::STV_INTERNAL:
|
||||
outs() << " .internal";
|
||||
break;
|
||||
case ELF::STV_HIDDEN:
|
||||
outs() << " .hidden";
|
||||
break;
|
||||
case ELF::STV_PROTECTED:
|
||||
outs() << " .protected";
|
||||
break;
|
||||
default:
|
||||
outs() << format(" 0x%02x", Other);
|
||||
break;
|
||||
}
|
||||
} else if (Hidden) {
|
||||
outs() << " .hidden";
|
||||
}
|
||||
|
||||
if (Demangle)
|
||||
outs() << ' ' << demangle(std::string(Name)) << '\n';
|
||||
else
|
||||
outs() << ' ' << Name << '\n';
|
||||
}
|
||||
|
||||
static void printUnwindInfo(const ObjectFile *O) {
|
||||
@ -2237,6 +2270,9 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
|
||||
printSectionHeaders(O);
|
||||
if (SymbolTable)
|
||||
printSymbolTable(O, ArchiveName);
|
||||
if (DynamicSymbolTable)
|
||||
printSymbolTable(O, ArchiveName, /*ArchitectureName=*/"",
|
||||
/*DumpDynamic=*/true);
|
||||
if (DwarfDumpType != DIDT_Null) {
|
||||
std::unique_ptr<DIContext> DICtx = DWARFContext::create(*O);
|
||||
// Dump the complete DWARF structure.
|
||||
@ -2378,7 +2414,7 @@ int main(int argc, char **argv) {
|
||||
if (!ArchiveHeaders && !Disassemble && DwarfDumpType == DIDT_Null &&
|
||||
!DynamicRelocations && !FileHeaders && !PrivateHeaders && !RawClangAST &&
|
||||
!Relocations && !SectionHeaders && !SectionContents && !SymbolTable &&
|
||||
!UnwindInfo && !FaultMapSection &&
|
||||
!DynamicSymbolTable && !UnwindInfo && !FaultMapSection &&
|
||||
!(MachOOpt &&
|
||||
(Bind || DataInCode || DylibId || DylibsUsed || ExportsTrie ||
|
||||
FirstPrivateHeader || IndirectSymbols || InfoPlist || LazyBind ||
|
||||
|
@ -133,7 +133,11 @@ void printDynamicRelocations(const object::ObjectFile *O);
|
||||
void printSectionHeaders(const object::ObjectFile *O);
|
||||
void printSectionContents(const object::ObjectFile *O);
|
||||
void printSymbolTable(const object::ObjectFile *O, StringRef ArchiveName,
|
||||
StringRef ArchitectureName = StringRef());
|
||||
StringRef ArchitectureName = StringRef(),
|
||||
bool DumpDynamic = false);
|
||||
void printSymbol(const object::ObjectFile *O, const object::SymbolRef &Symbol,
|
||||
StringRef FileName, StringRef ArchiveName,
|
||||
StringRef ArchitectureName, bool DumpDynamic);
|
||||
LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Twine Message);
|
||||
LLVM_ATTRIBUTE_NORETURN void reportError(Error E, StringRef FileName,
|
||||
StringRef ArchiveName = "",
|
||||
|
Loading…
Reference in New Issue
Block a user