aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.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/llvm-objdump.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/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp46
1 files changed, 26 insertions, 20 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 052b7f1..4d2e59d 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -256,6 +256,22 @@ void Dumper::reportUniqueWarning(const Twine &Msg) {
reportWarning(Msg, O.getFileName());
}
+static Expected<std::unique_ptr<Dumper>> createDumper(const ObjectFile &Obj) {
+ if (const auto *O = dyn_cast<COFFObjectFile>(&Obj))
+ return createCOFFDumper(*O);
+ if (const auto *O = dyn_cast<ELFObjectFileBase>(&Obj))
+ return createELFDumper(*O);
+ if (const auto *O = dyn_cast<MachOObjectFile>(&Obj))
+ return createMachODumper(*O);
+ if (const auto *O = dyn_cast<WasmObjectFile>(&Obj))
+ return createWasmDumper(*O);
+ if (const auto *O = dyn_cast<XCOFFObjectFile>(&Obj))
+ return createXCOFFDumper(*O);
+
+ return createStringError(errc::invalid_argument,
+ "unsupported object file format");
+}
+
namespace {
struct FilterResult {
// True if the section should not be skipped.
@@ -2697,24 +2713,8 @@ static void printFaultMaps(const ObjectFile *Obj) {
outs() << FMP;
}
-static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
- if (O->isELF()) {
- printELFFileHeader(O);
- printELFDynamicSection(O);
- printELFSymbolVersionInfo(O);
- return;
- }
- if (O->isCOFF())
- return printCOFFFileHeader(cast<object::COFFObjectFile>(*O));
- if (O->isWasm())
- return printWasmFileHeader(O);
- if (O->isMachO()) {
- printMachOFileHeader(O);
- if (!OnlyFirst)
- printMachOLoadCommands(O);
- return;
- }
- reportError(O->getFileName(), "Invalid/Unsupported object file format");
+void Dumper::printPrivateHeaders(bool) {
+ reportError(O.getFileName(), "Invalid/Unsupported object file format");
}
static void printFileHeaders(const ObjectFile *O) {
@@ -2817,7 +2817,13 @@ static void checkForInvalidStartStopAddress(ObjectFile *Obj,
static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
const Archive::Child *C = nullptr) {
- Dumper D(*O);
+ Expected<std::unique_ptr<Dumper>> DumperOrErr = createDumper(*O);
+ if (!DumperOrErr) {
+ reportError(DumperOrErr.takeError(), O->getFileName(),
+ A ? A->getFileName() : "");
+ return;
+ }
+ Dumper &D = **DumperOrErr;
// Avoid other output when using a raw option.
if (!RawClangAST) {
@@ -2842,7 +2848,7 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
if (FileHeaders)
printFileHeaders(O);
if (PrivateHeaders || FirstPrivateHeader)
- printPrivateFileHeaders(O, FirstPrivateHeader);
+ D.printPrivateHeaders(FirstPrivateHeader);
if (SectionHeaders)
printSectionHeaders(*O);
if (SymbolTable)