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