mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-24 14:33:40 +00:00
Teach llvm-readobj to print ELF program headers
llvm-svn: 179363
This commit is contained in:
parent
a1dea0c714
commit
e4564483fb
@ -76,6 +76,10 @@ input. Otherwise, it will read from the specified ``filenames``.
|
||||
|
||||
Display the needed libraries (only for ELF object files).
|
||||
|
||||
.. option:: -program-headers
|
||||
|
||||
Display the ELF program headers (only for ELF object files).
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
|
74
test/tools/llvm-readobj/program-headers.test
Normal file
74
test/tools/llvm-readobj/program-headers.test
Normal file
@ -0,0 +1,74 @@
|
||||
RUN: llvm-readobj -program-headers %p/../../Object/Inputs/program-headers.elf-i386 \
|
||||
RUN: | FileCheck %s -check-prefix ELF-I386
|
||||
RUN: llvm-readobj -program-headers %p/../../Object/Inputs/program-headers.elf-x86-64 \
|
||||
RUN: | FileCheck %s -check-prefix ELF-X86-64
|
||||
|
||||
ELF-I386: ProgramHeaders [
|
||||
ELF-I386-NEXT: ProgramHeader {
|
||||
ELF-I386-NEXT: Type: PT_LOAD (0x1)
|
||||
ELF-I386-NEXT: Offset: 0x0
|
||||
ELF-I386-NEXT: VirtualAddress: 0x8048000
|
||||
ELF-I386-NEXT: PhysicalAddress: 0x8048000
|
||||
ELF-I386-NEXT: FileSize: 308
|
||||
ELF-I386-NEXT: MemSize: 308
|
||||
ELF-I386-NEXT: Flags [ (0x5)
|
||||
ELF-I386-NEXT: PF_R (0x4)
|
||||
ELF-I386-NEXT: PF_X (0x1)
|
||||
ELF-I386-NEXT: ]
|
||||
ELF-I386-NEXT: Alignment: 4096
|
||||
ELF-I386-NEXT: }
|
||||
ELF-I386-NEXT: ProgramHeader {
|
||||
ELF-I386-NEXT: Type: PT_GNU_STACK (0x6474E551)
|
||||
ELF-I386-NEXT: Offset: 0x0
|
||||
ELF-I386-NEXT: VirtualAddress: 0x0
|
||||
ELF-I386-NEXT: PhysicalAddress: 0x0
|
||||
ELF-I386-NEXT: FileSize: 0
|
||||
ELF-I386-NEXT: MemSize: 0
|
||||
ELF-I386-NEXT: Flags [ (0x6)
|
||||
ELF-I386-NEXT: PF_R (0x4)
|
||||
ELF-I386-NEXT: PF_W (0x2)
|
||||
ELF-I386-NEXT: ]
|
||||
ELF-I386-NEXT: Alignment: 4
|
||||
ELF-I386-NEXT: }
|
||||
ELF-I386-NEXT: ]
|
||||
|
||||
ELF-X86-64: ProgramHeaders [
|
||||
ELF-X86-64-NEXT: ProgramHeader {
|
||||
ELF-X86-64-NEXT: Type: PT_LOAD (0x1)
|
||||
ELF-X86-64-NEXT: Offset: 0x0
|
||||
ELF-X86-64-NEXT: VirtualAddress: 0x400000
|
||||
ELF-X86-64-NEXT: PhysicalAddress: 0x400000
|
||||
ELF-X86-64-NEXT: FileSize: 312
|
||||
ELF-X86-64-NEXT: MemSize: 312
|
||||
ELF-X86-64-NEXT: Flags [ (0x5)
|
||||
ELF-X86-64-NEXT: PF_R (0x4)
|
||||
ELF-X86-64-NEXT: PF_X (0x1)
|
||||
ELF-X86-64-NEXT: ]
|
||||
ELF-X86-64-NEXT: Alignment: 2097152
|
||||
ELF-X86-64-NEXT: }
|
||||
ELF-X86-64-NEXT: ProgramHeader {
|
||||
ELF-X86-64-NEXT: Type: PT_GNU_EH_FRAME (0x6474E550)
|
||||
ELF-X86-64-NEXT: Offset: 0xF4
|
||||
ELF-X86-64-NEXT: VirtualAddress: 0x4000F4
|
||||
ELF-X86-64-NEXT: PhysicalAddress: 0x4000F4
|
||||
ELF-X86-64-NEXT: FileSize: 20
|
||||
ELF-X86-64-NEXT: MemSize: 20
|
||||
ELF-X86-64-NEXT: Flags [ (0x4)
|
||||
ELF-X86-64-NEXT: PF_R (0x4)
|
||||
ELF-X86-64-NEXT: ]
|
||||
ELF-X86-64-NEXT: Alignment: 4
|
||||
ELF-X86-64-NEXT: }
|
||||
ELF-X86-64-NEXT: ProgramHeader {
|
||||
ELF-X86-64-NEXT: Type: PT_GNU_STACK (0x6474E551)
|
||||
ELF-X86-64-NEXT: Offset: 0x0
|
||||
ELF-X86-64-NEXT: VirtualAddress: 0x0
|
||||
ELF-X86-64-NEXT: PhysicalAddress: 0x0
|
||||
ELF-X86-64-NEXT: FileSize: 0
|
||||
ELF-X86-64-NEXT: MemSize: 0
|
||||
ELF-X86-64-NEXT: Flags [ (0x6)
|
||||
ELF-X86-64-NEXT: PF_R (0x4)
|
||||
ELF-X86-64-NEXT: PF_W (0x2)
|
||||
ELF-X86-64-NEXT: ]
|
||||
ELF-X86-64-NEXT: Alignment: 8
|
||||
ELF-X86-64-NEXT: }
|
||||
ELF-X86-64-NEXT: ]
|
@ -50,16 +50,18 @@ public:
|
||||
|
||||
virtual void printDynamicTable() LLVM_OVERRIDE;
|
||||
virtual void printNeededLibraries() LLVM_OVERRIDE;
|
||||
virtual void printProgramHeaders() LLVM_OVERRIDE;
|
||||
|
||||
private:
|
||||
typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
|
||||
typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
|
||||
typedef ELFObjectFile<ELFT> ELFO;
|
||||
typedef typename ELFO::Elf_Shdr Elf_Shdr;
|
||||
typedef typename ELFO::Elf_Sym Elf_Sym;
|
||||
|
||||
void printSymbol(symbol_iterator SymI, bool IsDynamic = false);
|
||||
|
||||
void printRelocation(section_iterator SecI, relocation_iterator RelI);
|
||||
|
||||
const ELFObjectFile<ELFT> *Obj;
|
||||
const ELFO *Obj;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@ -399,11 +401,37 @@ static const EnumEntry<unsigned> ElfSectionFlags[] = {
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP )
|
||||
};
|
||||
|
||||
static const EnumEntry<unsigned> ElfSegmentTypes[] = {
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_NULL ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_LOAD ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_DYNAMIC),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_INTERP ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_NOTE ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_SHLIB ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_PHDR ),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_TLS ),
|
||||
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_EH_FRAME),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_EH_FRAME),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_UNWIND),
|
||||
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_STACK),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_RELRO),
|
||||
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_EXIDX),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_UNWIND)
|
||||
};
|
||||
|
||||
static const EnumEntry<unsigned> ElfSegmentFlags[] = {
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
|
||||
LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
|
||||
};
|
||||
|
||||
|
||||
template<class ELFT>
|
||||
void ELFDumper<ELFT>::printFileHeaders() {
|
||||
error_code EC;
|
||||
typedef ELFObjectFile<ELFT> ELFO;
|
||||
|
||||
const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader();
|
||||
|
||||
@ -745,7 +773,6 @@ void ELFDumper<ELFT>::printUnwindInfo() {
|
||||
|
||||
template<class ELFT>
|
||||
void ELFDumper<ELFT>::printDynamicTable() {
|
||||
typedef ELFObjectFile<ELFT> ELFO;
|
||||
typedef typename ELFO::Elf_Dyn_iterator EDI;
|
||||
EDI Start = Obj->begin_dynamic_table(),
|
||||
End = Obj->end_dynamic_table(true);
|
||||
@ -808,3 +835,22 @@ void ELFDumper<ELFT>::printNeededLibraries() {
|
||||
outs() << " " << Path << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void ELFDumper<ELFT>::printProgramHeaders() {
|
||||
ListScope L(W, "ProgramHeaders");
|
||||
|
||||
for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(),
|
||||
PE = Obj->end_program_headers();
|
||||
PI != PE; ++PI) {
|
||||
DictScope P(W, "ProgramHeader");
|
||||
W.printEnum ("Type", PI->p_type, makeArrayRef(ElfSegmentTypes));
|
||||
W.printHex ("Offset", PI->p_offset);
|
||||
W.printHex ("VirtualAddress", PI->p_vaddr);
|
||||
W.printHex ("PhysicalAddress", PI->p_paddr);
|
||||
W.printNumber("FileSize", PI->p_filesz);
|
||||
W.printNumber("MemSize", PI->p_memsz);
|
||||
W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
|
||||
W.printNumber("Alignment", PI->p_align);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
// Only implemented for ELF at this time.
|
||||
virtual void printDynamicTable() { }
|
||||
virtual void printNeededLibraries() { }
|
||||
virtual void printProgramHeaders() { }
|
||||
|
||||
protected:
|
||||
StreamWriter& W;
|
||||
|
@ -121,6 +121,10 @@ namespace opts {
|
||||
cl::opt<bool> NeededLibraries("needed-libs",
|
||||
cl::desc("Display the needed libraries"));
|
||||
|
||||
// -program-headers
|
||||
cl::opt<bool> ProgramHeaders("program-headers",
|
||||
cl::desc("Display ELF program headers"));
|
||||
|
||||
// -expand-relocs
|
||||
cl::opt<bool> ExpandRelocs("expand-relocs",
|
||||
cl::desc("Expand each shown relocation to multiple lines"));
|
||||
@ -215,6 +219,8 @@ static void dumpObject(const ObjectFile *Obj) {
|
||||
Dumper->printDynamicTable();
|
||||
if (opts::NeededLibraries)
|
||||
Dumper->printNeededLibraries();
|
||||
if (opts::ProgramHeaders)
|
||||
Dumper->printProgramHeaders();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user