diff options
author | Fangrui Song <i@maskray.me> | 2023-07-14 12:44:41 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2023-07-14 12:44:41 -0700 |
commit | 0af663f80da0009f6fd879cf4d41743d4c88a2db (patch) | |
tree | da617484204f75590d8fc2155d1959312f65c0b7 /llvm/tools/llvm-objdump/llvm-objdump.cpp | |
parent | 21ca892f698ac59e86ede6e4a2d4d747b0a36ae8 (diff) | |
download | llvm-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.cpp | 46 |
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) |