[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
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 5dfdc1a..1757fd6 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -153,7 +153,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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() {
@@ -3249,6 +3261,19 @@
}
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;
const Elf_Ehdr *Header = Obj->getHeader();
@@ -3286,6 +3311,10 @@
}
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())) {
@@ -4415,6 +4444,16 @@
}
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");
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 17cc8bb..6d57f4c 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -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 @@
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 @@
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,
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 206b67b..74f21e3 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -106,6 +106,11 @@
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 @@
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);