mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[llvm-readobj] Add a flag to dump just the section-to-segment mapping.
Summary: The following patch introduces a new function `printSectionMapping` which is responsible for dumping just the section-to-segment mapping. This patch also introduces a n option `-section-mapping` that outputs that mapping without the program headers. Previously, this functionality was controlled by `printProgramHeaders`, and the output from `-program-headers` has not been changed. I am happy to change the option name, I copied the name that was displayed when outputting the mapping table. Reviewers: khemant, jhenderson, grimar, rupprecht Reviewed By: jhenderson, grimar, rupprecht Subscribers: rupprecht, jhenderson, llvm-commits Differential Revision: https://reviews.llvm.org/D57365 llvm-svn: 352896
This commit is contained in:
parent
1698b137d9
commit
f2d4969a4b
@ -12,8 +12,22 @@
|
||||
|
||||
RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-i386 --elf-output-style=GNU \
|
||||
RUN: | FileCheck %s -check-prefix ELF32
|
||||
RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
|
||||
RUN: --elf-output-style=GNU | FileCheck %s -check-prefix ELF64
|
||||
RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-x86_64 --elf-output-style=GNU \
|
||||
RUN: | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING
|
||||
RUN: llvm-readelf -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
|
||||
RUN: | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING
|
||||
|
||||
# Check that -section-mapping produces a mapping and not the program headers.
|
||||
RUN: llvm-readelf -section-mapping %p/Inputs/phdrs-elf.exe-x86_64 \
|
||||
RUN: | FileCheck %s -check-prefix ELF64-MAPPING -implicit-check-not="Program Headers:"
|
||||
|
||||
# Check that -section-mapping=false -program-headers produces just program headers.
|
||||
RUN: llvm-readelf -section-mapping=false -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
|
||||
RUN: | FileCheck %s -check-prefix ELF64-PHDRS -implicit-check-not="Section to Segment mapping:"
|
||||
|
||||
# Check that only one copy of the section/segment mapping table is produced.
|
||||
RUN: llvm-readelf -section-mapping -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
|
||||
RUN: | FileCheck %s -check-prefix ELF64-ONEMAPPING
|
||||
|
||||
ELF32: Elf file type is EXEC (Executable file)
|
||||
ELF32-NEXT: Entry point 0x8048460
|
||||
@ -46,33 +60,36 @@ ELF32-NEXT: 07 .eh_frame_hdr
|
||||
ELF32-NEXT: 08
|
||||
ELF32-NEXT: 09 .tdata .ctors .dtors .jcr .dynamic .got
|
||||
|
||||
ELF64: Elf file type is EXEC (Executable file)
|
||||
ELF64-NEXT: Entry point 0x400610
|
||||
ELF64-NEXT: There are 10 program headers, starting at offset 64
|
||||
ELF64-PHDRS: Elf file type is EXEC (Executable file)
|
||||
ELF64-PHDRS-NEXT: Entry point 0x400610
|
||||
ELF64-PHDRS-NEXT: There are 10 program headers, starting at offset 64
|
||||
|
||||
ELF64: Program Headers:
|
||||
ELF64-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
ELF64-NEXT: PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000230 0x000230 R E 0x8
|
||||
ELF64-NEXT: INTERP 0x000270 0x0000000000400270 0x0000000000400270 0x00001c 0x00001c R 0x1
|
||||
ELF64-NEXT: [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
|
||||
ELF64-NEXT: LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000924 0x000924 R E 0x200000
|
||||
ELF64-NEXT: LOAD 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000274 0x0002a4 RW 0x200000
|
||||
ELF64-NEXT: DYNAMIC 0x000dd0 0x0000000000600dd0 0x0000000000600dd0 0x000210 0x000210 RW 0x8
|
||||
ELF64-NEXT: NOTE 0x00028c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R 0x4
|
||||
ELF64-NEXT: TLS 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000004 0x000008 R 0x4
|
||||
ELF64-NEXT: GNU_EH_FRAME 0x00083c 0x000000000040083c 0x000000000040083c 0x00002c 0x00002c R 0x4
|
||||
ELF64-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
|
||||
ELF64-NEXT: GNU_RELRO 0x000db4 0x0000000000600db4 0x0000000000600db4 0x00024c 0x00024c R 0x1
|
||||
ELF64-PHDRS: Program Headers:
|
||||
ELF64-PHDRS-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
ELF64-PHDRS-NEXT: PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000230 0x000230 R E 0x8
|
||||
ELF64-PHDRS-NEXT: INTERP 0x000270 0x0000000000400270 0x0000000000400270 0x00001c 0x00001c R 0x1
|
||||
ELF64-PHDRS-NEXT: [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
|
||||
ELF64-PHDRS-NEXT: LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000924 0x000924 R E 0x200000
|
||||
ELF64-PHDRS-NEXT: LOAD 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000274 0x0002a4 RW 0x200000
|
||||
ELF64-PHDRS-NEXT: DYNAMIC 0x000dd0 0x0000000000600dd0 0x0000000000600dd0 0x000210 0x000210 RW 0x8
|
||||
ELF64-PHDRS-NEXT: NOTE 0x00028c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R 0x4
|
||||
ELF64-PHDRS-NEXT: TLS 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000004 0x000008 R 0x4
|
||||
ELF64-PHDRS-NEXT: GNU_EH_FRAME 0x00083c 0x000000000040083c 0x000000000040083c 0x00002c 0x00002c R 0x4
|
||||
ELF64-PHDRS-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
|
||||
ELF64-PHDRS-NEXT: GNU_RELRO 0x000db4 0x0000000000600db4 0x0000000000600db4 0x00024c 0x00024c R 0x1
|
||||
|
||||
ELF64: Section to Segment mapping:
|
||||
ELF64-NEXT: Segment Sections...
|
||||
ELF64-NEXT: 00
|
||||
ELF64-NEXT: 01 .interp
|
||||
ELF64-NEXT: 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
|
||||
ELF64-NEXT: 03 .tdata .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
|
||||
ELF64-NEXT: 04 .dynamic
|
||||
ELF64-NEXT: 05 .note.ABI-tag .note.gnu.build-id
|
||||
ELF64-NEXT: 06 .tdata .tbss
|
||||
ELF64-NEXT: 07 .eh_frame_hdr
|
||||
ELF64-NEXT: 08
|
||||
ELF64-NEXT: 09 .tdata .init_array .fini_array .jcr .dynamic .got
|
||||
ELF64-MAPPING: Section to Segment mapping:
|
||||
ELF64-MAPPING-NEXT: Segment Sections...
|
||||
ELF64-MAPPING-NEXT: 00
|
||||
ELF64-MAPPING-NEXT: 01 .interp
|
||||
ELF64-MAPPING-NEXT: 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
|
||||
ELF64-MAPPING-NEXT: 03 .tdata .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
|
||||
ELF64-MAPPING-NEXT: 04 .dynamic
|
||||
ELF64-MAPPING-NEXT: 05 .note.ABI-tag .note.gnu.build-id
|
||||
ELF64-MAPPING-NEXT: 06 .tdata .tbss
|
||||
ELF64-MAPPING-NEXT: 07 .eh_frame_hdr
|
||||
ELF64-MAPPING-NEXT: 08
|
||||
ELF64-MAPPING-NEXT: 09 .tdata .init_array .fini_array .jcr .dynamic .got
|
||||
|
||||
ELF64-ONEMAPPING: Section to Segment mapping:
|
||||
ELF64-ONEMAPPING-NOT: Section to Segment mapping:
|
||||
|
@ -153,7 +153,8 @@ public:
|
||||
|
||||
void printDynamicTable() override;
|
||||
void printNeededLibraries() override;
|
||||
void printProgramHeaders() override;
|
||||
void printProgramHeaders(bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) override;
|
||||
void printHashTable() override;
|
||||
void printGnuHashTable() override;
|
||||
void printLoadName() override;
|
||||
@ -337,7 +338,9 @@ public:
|
||||
virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol,
|
||||
const Elf_Sym *FirstSym, StringRef StrTable,
|
||||
bool IsDynamic) = 0;
|
||||
virtual void printProgramHeaders(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printProgramHeaders(const ELFFile<ELFT> *Obj,
|
||||
bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) = 0;
|
||||
virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printAddrsig(const ELFFile<ELFT> *Obj) = 0;
|
||||
@ -370,7 +373,8 @@ public:
|
||||
void printDynamicRelocations(const ELFO *Obj) override;
|
||||
void printSymtabMessage(const ELFO *Obj, StringRef Name,
|
||||
size_t Offset) override;
|
||||
void printProgramHeaders(const ELFO *Obj) override;
|
||||
void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) override;
|
||||
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
|
||||
void printCGProfile(const ELFFile<ELFT> *Obj) override;
|
||||
void printAddrsig(const ELFFile<ELFT> *Obj) override;
|
||||
@ -444,6 +448,8 @@ private:
|
||||
bool checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
|
||||
bool checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
|
||||
bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
|
||||
void printProgramHeaders(const ELFO *Obj);
|
||||
void printSectionMapping(const ELFO *Obj);
|
||||
};
|
||||
|
||||
template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
|
||||
@ -461,7 +467,8 @@ public:
|
||||
void printSymbols(const ELFO *Obj, bool PrintSymbols,
|
||||
bool PrintDynamicSymbols) override;
|
||||
void printDynamicRelocations(const ELFO *Obj) override;
|
||||
void printProgramHeaders(const ELFO *Obj) override;
|
||||
void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) override;
|
||||
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
|
||||
void printCGProfile(const ELFFile<ELFT> *Obj) override;
|
||||
void printAddrsig(const ELFFile<ELFT> *Obj) override;
|
||||
@ -477,6 +484,8 @@ private:
|
||||
void printDynamicSymbols(const ELFO *Obj);
|
||||
void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
|
||||
StringRef StrTable, bool IsDynamic) override;
|
||||
void printProgramHeaders(const ELFO *Obj);
|
||||
void printSectionMapping(const ELFO *Obj) {}
|
||||
|
||||
ScopedPrinter &W;
|
||||
};
|
||||
@ -1615,8 +1624,11 @@ void ELFDumper<ELFT>::printRelocations() {
|
||||
ELFDumperStyle->printRelocations(ObjF->getELFFile());
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
|
||||
ELFDumperStyle->printProgramHeaders(ObjF->getELFFile());
|
||||
template <class ELFT>
|
||||
void ELFDumper<ELFT>::printProgramHeaders(
|
||||
bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
|
||||
ELFDumperStyle->printProgramHeaders(ObjF->getELFFile(), PrintProgramHeaders,
|
||||
PrintSectionMapping);
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
|
||||
@ -3248,6 +3260,19 @@ bool GNUStyle<ELFT>::checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) {
|
||||
(Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printProgramHeaders(
|
||||
const ELFO *Obj, bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) {
|
||||
if (PrintProgramHeaders)
|
||||
printProgramHeaders(Obj);
|
||||
|
||||
// Display the section mapping along with the program headers, unless
|
||||
// -section-mapping is explicitly set to false.
|
||||
if (PrintSectionMapping != cl::BOU_FALSE)
|
||||
printSectionMapping(Obj);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
|
||||
unsigned Bias = ELFT::Is64Bits ? 8 : 0;
|
||||
@ -3286,6 +3311,10 @@ void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
|
||||
}
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printSectionMapping(const ELFO *Obj) {
|
||||
OS << "\n Section to Segment mapping:\n Segment Sections...\n";
|
||||
int Phnum = 0;
|
||||
for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
|
||||
@ -4414,6 +4443,16 @@ void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printProgramHeaders(
|
||||
const ELFO *Obj, bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) {
|
||||
if (PrintProgramHeaders)
|
||||
printProgramHeaders(Obj);
|
||||
if (PrintSectionMapping == cl::BOU_TRUE)
|
||||
printSectionMapping(Obj);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
|
||||
ListScope L(W, "ProgramHeaders");
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
@ -40,13 +41,20 @@ public:
|
||||
if (PrintDynamicSymbols)
|
||||
printDynamicSymbols();
|
||||
}
|
||||
virtual void printProgramHeaders(bool PrintProgramHeaders,
|
||||
cl::boolOrDefault PrintSectionMapping) {
|
||||
if (PrintProgramHeaders)
|
||||
printProgramHeaders();
|
||||
if (PrintSectionMapping == cl::BOU_TRUE)
|
||||
printSectionMapping();
|
||||
}
|
||||
|
||||
virtual void printUnwindInfo() = 0;
|
||||
|
||||
// Only implemented for ELF at this time.
|
||||
virtual void printDynamicRelocations() { }
|
||||
virtual void printDynamicTable() { }
|
||||
virtual void printNeededLibraries() { }
|
||||
virtual void printProgramHeaders() { }
|
||||
virtual void printSectionAsHex(StringRef SectionName) {}
|
||||
virtual void printHashTable() { }
|
||||
virtual void printGnuHashTable() { }
|
||||
@ -99,8 +107,10 @@ protected:
|
||||
ScopedPrinter &W;
|
||||
|
||||
private:
|
||||
virtual void printSymbols() {};
|
||||
virtual void printDynamicSymbols() {};
|
||||
virtual void printSymbols() {}
|
||||
virtual void printDynamicSymbols() {}
|
||||
virtual void printProgramHeaders() {}
|
||||
virtual void printSectionMapping() {}
|
||||
};
|
||||
|
||||
std::error_code createCOFFDumper(const object::ObjectFile *Obj,
|
||||
|
@ -106,6 +106,11 @@ namespace opts {
|
||||
cl::opt<bool> SectionData("section-data",
|
||||
cl::desc("Display section data for each section shown."));
|
||||
|
||||
// -section-mapping
|
||||
cl::opt<cl::boolOrDefault>
|
||||
SectionMapping("section-mapping",
|
||||
cl::desc("Display the section to segment mapping."));
|
||||
|
||||
// -relocations, -relocs, -r
|
||||
cl::opt<bool> Relocations("relocations",
|
||||
cl::desc("Display the relocation entries in the file"));
|
||||
@ -474,8 +479,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
|
||||
Dumper->printDynamicTable();
|
||||
if (opts::NeededLibraries)
|
||||
Dumper->printNeededLibraries();
|
||||
if (opts::ProgramHeaders)
|
||||
Dumper->printProgramHeaders();
|
||||
if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)
|
||||
Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);
|
||||
if (!opts::StringDump.empty())
|
||||
llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) {
|
||||
Dumper->printSectionAsString(Obj, SectionName);
|
||||
|
Loading…
Reference in New Issue
Block a user