aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/ELFDump.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2023-07-14 12:44:41 -0700
committerFangrui Song <i@maskray.me>2023-07-14 12:44:41 -0700
commit0af663f80da0009f6fd879cf4d41743d4c88a2db (patch)
treeda617484204f75590d8fc2155d1959312f65c0b7 /llvm/tools/llvm-objdump/ELFDump.cpp
parent21ca892f698ac59e86ede6e4a2d4d747b0a36ae8 (diff)
downloadllvm-0af663f80da0009f6fd879cf4d41743d4c88a2db.zip
llvm-0af663f80da0009f6fd879cf4d41743d4c88a2db.tar.gz
llvm-0af663f80da0009f6fd879cf4d41743d4c88a2db.tar.bz2
[llvm-objdump] Create ObjectFile specific dumpers
We pay the one-off boilerplate overhead to create `*Dumper` classes that derive from objdump::Dumper a la llvm-readobj. This has two primary advantages. First, a lot object file format specific code can be moved from llvm-objdump.cpp to *Dump.cpp files. Refactor `printPrivateHeaders` as an example. Second, with the introduction of ELFDumper<ELFT>, we can simplify a few dispatch functions in ELFDump.cpp. In addition, the ObjectFile specific dumpers contains a ObjectFile specific reference so that we can remove a lot of `cast<*ObjectFile>(Obj)`. Reviewed By: mtrofin Differential Revision: https://reviews.llvm.org/D155045
Diffstat (limited to 'llvm/tools/llvm-objdump/ELFDump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/ELFDump.cpp88
1 files changed, 46 insertions, 42 deletions
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 6e42204..43ab309 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -24,6 +24,38 @@ using namespace llvm;
using namespace llvm::object;
using namespace llvm::objdump;
+namespace {
+template <typename ELFT> class ELFDumper : public Dumper {
+public:
+ ELFDumper(const ELFObjectFile<ELFT> &O) : Dumper(O), Obj(O) {}
+ void printPrivateHeaders(bool MachOOnlyFirst) override;
+
+private:
+ const ELFObjectFile<ELFT> &Obj;
+
+ const ELFFile<ELFT> &getELFFile() const { return Obj.getELFFile(); }
+ void printDynamicSection();
+ void printProgramHeaders();
+ void printSymbolVersion();
+};
+} // namespace
+
+template <class ELFT>
+static std::unique_ptr<Dumper> createDumper(const ELFObjectFile<ELFT> &Obj) {
+ return std::make_unique<ELFDumper<ELFT>>(Obj);
+}
+
+std::unique_ptr<Dumper>
+objdump::createELFDumper(const object::ELFObjectFileBase &Obj) {
+ if (const auto *O = dyn_cast<ELF32LEObjectFile>(&Obj))
+ return createDumper(*O);
+ if (const auto *O = dyn_cast<ELF32BEObjectFile>(&Obj))
+ return createDumper(*O);
+ if (const auto *O = dyn_cast<ELF64LEObjectFile>(&Obj))
+ return createDumper(*O);
+ return createDumper(cast<ELF64BEObjectFile>(Obj));
+}
+
template <class ELFT>
static Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> &Elf) {
auto DynamicEntriesOrError = Elf.dynamicEntries();
@@ -166,11 +198,11 @@ uint64_t objdump::getELFSectionLMA(const object::ELFSectionRef &Sec) {
return getSectionLMA(ELFObj->getELFFile(), Sec);
}
-template <class ELFT>
-static void printDynamicSection(const ELFFile<ELFT> &Elf, StringRef Filename) {
+template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
+ const ELFFile<ELFT> &Elf = getELFFile();
auto DynamicEntriesOrErr = Elf.dynamicEntries();
if (!DynamicEntriesOrErr) {
- reportWarning(toString(DynamicEntriesOrErr.takeError()), Filename);
+ reportWarning(toString(DynamicEntriesOrErr.takeError()), Obj.getFileName());
return;
}
ArrayRef<typename ELFT::Dyn> DynamicEntries = *DynamicEntriesOrErr;
@@ -200,21 +232,20 @@ static void printDynamicSection(const ELFFile<ELFT> &Elf, StringRef Filename) {
outs() << (Data + Dyn.d_un.d_val) << "\n";
continue;
}
- reportWarning(toString(StrTabOrErr.takeError()), Filename);
+ reportWarning(toString(StrTabOrErr.takeError()), Obj.getFileName());
consumeError(StrTabOrErr.takeError());
}
outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
}
}
-template <class ELFT>
-static void printProgramHeaders(const ELFFile<ELFT> &Obj, StringRef FileName) {
+template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
outs() << "\nProgram Header:\n";
- auto ProgramHeaderOrError = Obj.program_headers();
+ auto ProgramHeaderOrError = getELFFile().program_headers();
if (!ProgramHeaderOrError) {
reportWarning("unable to read program headers: " +
toString(ProgramHeaderOrError.takeError()),
- FileName);
+ Obj.getFileName());
return;
}
@@ -338,9 +369,9 @@ static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
}
}
-template <class ELFT>
-static void printSymbolVersionInfo(const ELFFile<ELFT> &Elf,
- StringRef FileName) {
+template <class ELFT> void ELFDumper<ELFT>::printSymbolVersion() {
+ const ELFFile<ELFT> &Elf = getELFFile();
+ StringRef FileName = Obj.getFileName();
ArrayRef<typename ELFT::Shdr> Sections =
unwrapOrError(Elf.sections(), FileName);
for (const typename ELFT::Shdr &Shdr : Sections) {
@@ -361,35 +392,8 @@ static void printSymbolVersionInfo(const ELFFile<ELFT> &Elf,
}
}
-void objdump::printELFFileHeader(const object::ObjectFile *Obj) {
- if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
- printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
- printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
- printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
- printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
-}
-
-void objdump::printELFDynamicSection(const object::ObjectFile *Obj) {
- if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
- printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
- printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
- printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
- printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
-}
-
-void objdump::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
- if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
- printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
- printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
- printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
- else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
- printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+template <class ELFT> void ELFDumper<ELFT>::printPrivateHeaders(bool) {
+ printProgramHeaders();
+ printDynamicSection();
+ printSymbolVersion();
}