xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-readobj/ObjDumper.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- ObjDumper.h ---------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
100b57cec5SDimitry Andric #define LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
110b57cec5SDimitry Andric 
1281ad6265SDimitry Andric #include <functional>
130b57cec5SDimitry Andric #include <memory>
140b57cec5SDimitry Andric #include <system_error>
150b57cec5SDimitry Andric 
1681ad6265SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
180b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
190b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
200b57cec5SDimitry Andric 
21e8d8bef9SDimitry Andric #include <unordered_set>
22e8d8bef9SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric namespace object {
250eae32dcSDimitry Andric class Archive;
260b57cec5SDimitry Andric class COFFImportFile;
270b57cec5SDimitry Andric class ObjectFile;
28e8d8bef9SDimitry Andric class XCOFFObjectFile;
29e8d8bef9SDimitry Andric class ELFObjectFileBase;
3081ad6265SDimitry Andric } // namespace object
310b57cec5SDimitry Andric namespace codeview {
320b57cec5SDimitry Andric class GlobalTypeTableBuilder;
330b57cec5SDimitry Andric class MergingTypeTableBuilder;
340b57cec5SDimitry Andric } // namespace codeview
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric class ScopedPrinter;
370b57cec5SDimitry Andric 
3881ad6265SDimitry Andric // Comparator to compare symbols.
3981ad6265SDimitry Andric // Usage: the caller registers predicates (i.e., how to compare the symbols) by
4081ad6265SDimitry Andric // calling addPredicate(). The order in which predicates are registered is also
4181ad6265SDimitry Andric // their priority.
4281ad6265SDimitry Andric class SymbolComparator {
4381ad6265SDimitry Andric public:
4481ad6265SDimitry Andric   using CompPredicate =
4581ad6265SDimitry Andric       std::function<bool(object::SymbolRef, object::SymbolRef)>;
4681ad6265SDimitry Andric 
4781ad6265SDimitry Andric   // Each Obj format has a slightly different way of retrieving a symbol's info
4881ad6265SDimitry Andric   // So we defer the predicate's impl to each format.
addPredicate(CompPredicate Pred)4981ad6265SDimitry Andric   void addPredicate(CompPredicate Pred) { Predicates.push_back(Pred); }
5081ad6265SDimitry Andric 
operator()5181ad6265SDimitry Andric   bool operator()(object::SymbolRef LHS, object::SymbolRef RHS) {
5281ad6265SDimitry Andric     for (CompPredicate Pred : Predicates) {
5381ad6265SDimitry Andric       if (Pred(LHS, RHS))
5481ad6265SDimitry Andric         return true;
5581ad6265SDimitry Andric       if (Pred(RHS, LHS))
5681ad6265SDimitry Andric         return false;
5781ad6265SDimitry Andric     }
5881ad6265SDimitry Andric     return false;
5981ad6265SDimitry Andric   }
6081ad6265SDimitry Andric 
6181ad6265SDimitry Andric private:
6281ad6265SDimitry Andric   SmallVector<CompPredicate, 2> Predicates;
6381ad6265SDimitry Andric };
6481ad6265SDimitry Andric 
650b57cec5SDimitry Andric class ObjDumper {
660b57cec5SDimitry Andric public:
67e8d8bef9SDimitry Andric   ObjDumper(ScopedPrinter &Writer, StringRef ObjName);
680b57cec5SDimitry Andric   virtual ~ObjDumper();
690b57cec5SDimitry Andric 
canDumpContent()70e8d8bef9SDimitry Andric   virtual bool canDumpContent() { return true; }
71e8d8bef9SDimitry Andric 
720eae32dcSDimitry Andric   virtual void printFileSummary(StringRef FileStr, object::ObjectFile &Obj,
730eae32dcSDimitry Andric                                 ArrayRef<std::string> InputFilenames,
740eae32dcSDimitry Andric                                 const object::Archive *A);
750b57cec5SDimitry Andric   virtual void printFileHeaders() = 0;
760b57cec5SDimitry Andric   virtual void printSectionHeaders() = 0;
770b57cec5SDimitry Andric   virtual void printRelocations() = 0;
printSymbols(bool PrintSymbols,bool PrintDynamicSymbols,bool ExtraSymInfo)785f757f3fSDimitry Andric   virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
795f757f3fSDimitry Andric                             bool ExtraSymInfo) {
800b57cec5SDimitry Andric     if (PrintSymbols)
815f757f3fSDimitry Andric       printSymbols(ExtraSymInfo);
820b57cec5SDimitry Andric     if (PrintDynamicSymbols)
830b57cec5SDimitry Andric       printDynamicSymbols();
840b57cec5SDimitry Andric   }
printSymbols(bool PrintSymbols,bool PrintDynamicSymbols,bool ExtraSymInfo,std::optional<SymbolComparator> SymComp)8581ad6265SDimitry Andric   virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
865f757f3fSDimitry Andric                             bool ExtraSymInfo,
87bdd1243dSDimitry Andric                             std::optional<SymbolComparator> SymComp) {
8881ad6265SDimitry Andric     if (SymComp) {
8981ad6265SDimitry Andric       if (PrintSymbols)
9081ad6265SDimitry Andric         printSymbols(SymComp);
9181ad6265SDimitry Andric       if (PrintDynamicSymbols)
9281ad6265SDimitry Andric         printDynamicSymbols(SymComp);
9381ad6265SDimitry Andric     } else {
945f757f3fSDimitry Andric       printSymbols(PrintSymbols, PrintDynamicSymbols, ExtraSymInfo);
9581ad6265SDimitry Andric     }
9681ad6265SDimitry Andric   }
printProgramHeaders(bool PrintProgramHeaders,cl::boolOrDefault PrintSectionMapping)970b57cec5SDimitry Andric   virtual void printProgramHeaders(bool PrintProgramHeaders,
980b57cec5SDimitry Andric                                    cl::boolOrDefault PrintSectionMapping) {
990b57cec5SDimitry Andric     if (PrintProgramHeaders)
1000b57cec5SDimitry Andric       printProgramHeaders();
1010b57cec5SDimitry Andric     if (PrintSectionMapping == cl::BOU_TRUE)
1020b57cec5SDimitry Andric       printSectionMapping();
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   virtual void printUnwindInfo() = 0;
1060b57cec5SDimitry Andric 
10781ad6265SDimitry Andric   // Symbol comparison functions.
canCompareSymbols()10881ad6265SDimitry Andric   virtual bool canCompareSymbols() const { return false; }
compareSymbolsByName(object::SymbolRef LHS,object::SymbolRef RHS)10981ad6265SDimitry Andric   virtual bool compareSymbolsByName(object::SymbolRef LHS,
11081ad6265SDimitry Andric                                     object::SymbolRef RHS) const {
11181ad6265SDimitry Andric     return true;
11281ad6265SDimitry Andric   }
compareSymbolsByType(object::SymbolRef LHS,object::SymbolRef RHS)11381ad6265SDimitry Andric   virtual bool compareSymbolsByType(object::SymbolRef LHS,
11481ad6265SDimitry Andric                                     object::SymbolRef RHS) const {
11581ad6265SDimitry Andric     return true;
11681ad6265SDimitry Andric   }
11781ad6265SDimitry Andric 
1180b57cec5SDimitry Andric   // Only implemented for ELF at this time.
printDependentLibs()119480093f4SDimitry Andric   virtual void printDependentLibs() {}
printDynamicRelocations()1200b57cec5SDimitry Andric   virtual void printDynamicRelocations() { }
printDynamicTable()1210b57cec5SDimitry Andric   virtual void printDynamicTable() { }
printNeededLibraries()1220b57cec5SDimitry Andric   virtual void printNeededLibraries() { }
printSectionAsHex(StringRef SectionName)1230b57cec5SDimitry Andric   virtual void printSectionAsHex(StringRef SectionName) {}
printHashTable()1240b57cec5SDimitry Andric   virtual void printHashTable() { }
printGnuHashTable()125e8d8bef9SDimitry Andric   virtual void printGnuHashTable() {}
printHashSymbols()1260b57cec5SDimitry Andric   virtual void printHashSymbols() {}
printLoadName()1270b57cec5SDimitry Andric   virtual void printLoadName() {}
printVersionInfo()1280b57cec5SDimitry Andric   virtual void printVersionInfo() {}
printGroupSections()1290b57cec5SDimitry Andric   virtual void printGroupSections() {}
printHashHistograms()1305ffd83dbSDimitry Andric   virtual void printHashHistograms() {}
printCGProfile()1310b57cec5SDimitry Andric   virtual void printCGProfile() {}
132*0fca6ea1SDimitry Andric   // If PrettyPGOAnalysis is true, prints BFI as relative frequency and BPI as
133*0fca6ea1SDimitry Andric   // percentage. Otherwise raw values are displayed.
printBBAddrMaps(bool PrettyPGOAnalysis)134*0fca6ea1SDimitry Andric   virtual void printBBAddrMaps(bool PrettyPGOAnalysis) {}
printAddrsig()1350b57cec5SDimitry Andric   virtual void printAddrsig() {}
printNotes()1360b57cec5SDimitry Andric   virtual void printNotes() {}
printELFLinkerOptions()1370b57cec5SDimitry Andric   virtual void printELFLinkerOptions() {}
printStackSizes()1388bcb0991SDimitry Andric   virtual void printStackSizes() {}
printSectionDetails()139e8d8bef9SDimitry Andric   virtual void printSectionDetails() {}
printArchSpecificInfo()1408bcb0991SDimitry Andric   virtual void printArchSpecificInfo() {}
printMemtag()14106c3fb27SDimitry Andric   virtual void printMemtag() {}
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   // Only implemented for PE/COFF.
printCOFFImports()1440b57cec5SDimitry Andric   virtual void printCOFFImports() { }
printCOFFExports()1450b57cec5SDimitry Andric   virtual void printCOFFExports() { }
printCOFFDirectives()1460b57cec5SDimitry Andric   virtual void printCOFFDirectives() { }
printCOFFBaseReloc()1470b57cec5SDimitry Andric   virtual void printCOFFBaseReloc() { }
printCOFFDebugDirectory()1480b57cec5SDimitry Andric   virtual void printCOFFDebugDirectory() { }
printCOFFTLSDirectory()149e8d8bef9SDimitry Andric   virtual void printCOFFTLSDirectory() {}
printCOFFResources()1500b57cec5SDimitry Andric   virtual void printCOFFResources() {}
printCOFFLoadConfig()1510b57cec5SDimitry Andric   virtual void printCOFFLoadConfig() { }
printCodeViewDebugInfo()1520b57cec5SDimitry Andric   virtual void printCodeViewDebugInfo() { }
1530b57cec5SDimitry Andric   virtual void
mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder & CVIDs,llvm::codeview::MergingTypeTableBuilder & CVTypes,llvm::codeview::GlobalTypeTableBuilder & GlobalCVIDs,llvm::codeview::GlobalTypeTableBuilder & GlobalCVTypes,bool GHash)1540b57cec5SDimitry Andric   mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs,
1550b57cec5SDimitry Andric                      llvm::codeview::MergingTypeTableBuilder &CVTypes,
1560b57cec5SDimitry Andric                      llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs,
1570b57cec5SDimitry Andric                      llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes,
1580b57cec5SDimitry Andric                      bool GHash) {}
1590b57cec5SDimitry Andric 
160bdd1243dSDimitry Andric   // Only implemented for XCOFF.
printStringTable()161bdd1243dSDimitry Andric   virtual void printStringTable() {}
printAuxiliaryHeader()162349cc55cSDimitry Andric   virtual void printAuxiliaryHeader() {}
printExceptionSection()163bdd1243dSDimitry Andric   virtual void printExceptionSection() {}
printLoaderSection(bool PrintHeader,bool PrintSymbols,bool PrintRelocations)164bdd1243dSDimitry Andric   virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols,
165bdd1243dSDimitry Andric                                   bool PrintRelocations) {}
166349cc55cSDimitry Andric 
1670b57cec5SDimitry Andric   // Only implemented for MachO.
printMachODataInCode()1680b57cec5SDimitry Andric   virtual void printMachODataInCode() { }
printMachOVersionMin()1690b57cec5SDimitry Andric   virtual void printMachOVersionMin() { }
printMachODysymtab()1700b57cec5SDimitry Andric   virtual void printMachODysymtab() { }
printMachOSegment()1710b57cec5SDimitry Andric   virtual void printMachOSegment() { }
printMachOIndirectSymbols()1720b57cec5SDimitry Andric   virtual void printMachOIndirectSymbols() { }
printMachOLinkerOptions()1730b57cec5SDimitry Andric   virtual void printMachOLinkerOptions() { }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   virtual void printStackMap() const = 0;
1760b57cec5SDimitry Andric 
177349cc55cSDimitry Andric   void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0);
178fe6060f1SDimitry Andric 
179e8d8bef9SDimitry Andric   void printSectionsAsString(const object::ObjectFile &Obj,
1804c2d3b02SDimitry Andric                              ArrayRef<std::string> Sections, bool Decompress);
181e8d8bef9SDimitry Andric   void printSectionsAsHex(const object::ObjectFile &Obj,
1824c2d3b02SDimitry Andric                           ArrayRef<std::string> Sections, bool Decompress);
1830b57cec5SDimitry Andric 
184e8d8bef9SDimitry Andric   std::function<Error(const Twine &Msg)> WarningHandler;
185e8d8bef9SDimitry Andric   void reportUniqueWarning(Error Err) const;
186e8d8bef9SDimitry Andric   void reportUniqueWarning(const Twine &Msg) const;
187e8d8bef9SDimitry Andric 
1880b57cec5SDimitry Andric protected:
1890b57cec5SDimitry Andric   ScopedPrinter &W;
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric private:
printSymbols(bool ExtraSymInfo)1925f757f3fSDimitry Andric   virtual void printSymbols(bool ExtraSymInfo) {}
printSymbols(std::optional<SymbolComparator> Comp)193bdd1243dSDimitry Andric   virtual void printSymbols(std::optional<SymbolComparator> Comp) {}
printDynamicSymbols()1940b57cec5SDimitry Andric   virtual void printDynamicSymbols() {}
printDynamicSymbols(std::optional<SymbolComparator> Comp)195bdd1243dSDimitry Andric   virtual void printDynamicSymbols(std::optional<SymbolComparator> Comp) {}
printProgramHeaders()1960b57cec5SDimitry Andric   virtual void printProgramHeaders() {}
printSectionMapping()1970b57cec5SDimitry Andric   virtual void printSectionMapping() {}
198e8d8bef9SDimitry Andric 
199e8d8bef9SDimitry Andric   std::unordered_set<std::string> Warnings;
2000b57cec5SDimitry Andric };
2010b57cec5SDimitry Andric 
202e8d8bef9SDimitry Andric std::unique_ptr<ObjDumper> createCOFFDumper(const object::COFFObjectFile &Obj,
203e8d8bef9SDimitry Andric                                             ScopedPrinter &Writer);
2040b57cec5SDimitry Andric 
205e8d8bef9SDimitry Andric std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
206e8d8bef9SDimitry Andric                                            ScopedPrinter &Writer);
2070b57cec5SDimitry Andric 
208e8d8bef9SDimitry Andric std::unique_ptr<ObjDumper> createMachODumper(const object::MachOObjectFile &Obj,
209e8d8bef9SDimitry Andric                                              ScopedPrinter &Writer);
2100b57cec5SDimitry Andric 
211e8d8bef9SDimitry Andric std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj,
212e8d8bef9SDimitry Andric                                             ScopedPrinter &Writer);
2130b57cec5SDimitry Andric 
214e8d8bef9SDimitry Andric std::unique_ptr<ObjDumper> createXCOFFDumper(const object::XCOFFObjectFile &Obj,
215e8d8bef9SDimitry Andric                                              ScopedPrinter &Writer);
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric void dumpCOFFImportFile(const object::COFFImportFile *File,
2180b57cec5SDimitry Andric                         ScopedPrinter &Writer);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric void dumpCodeViewMergedTypes(ScopedPrinter &Writer,
2210b57cec5SDimitry Andric                              ArrayRef<ArrayRef<uint8_t>> IpiRecords,
2220b57cec5SDimitry Andric                              ArrayRef<ArrayRef<uint8_t>> TpiRecords);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric } // namespace llvm
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric #endif
227