1 //===-- ObjDumper.h ---------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H 10 #define LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H 11 12 #include <functional> 13 #include <memory> 14 #include <system_error> 15 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Object/ObjectFile.h" 19 #include "llvm/Support/CommandLine.h" 20 21 #include <unordered_set> 22 23 namespace llvm { 24 namespace object { 25 class Archive; 26 class COFFImportFile; 27 class ObjectFile; 28 class XCOFFObjectFile; 29 class ELFObjectFileBase; 30 } // namespace object 31 namespace codeview { 32 class GlobalTypeTableBuilder; 33 class MergingTypeTableBuilder; 34 } // namespace codeview 35 36 class ScopedPrinter; 37 38 // Comparator to compare symbols. 39 // Usage: the caller registers predicates (i.e., how to compare the symbols) by 40 // calling addPredicate(). The order in which predicates are registered is also 41 // their priority. 42 class SymbolComparator { 43 public: 44 using CompPredicate = 45 std::function<bool(object::SymbolRef, object::SymbolRef)>; 46 47 // Each Obj format has a slightly different way of retrieving a symbol's info 48 // So we defer the predicate's impl to each format. addPredicate(CompPredicate Pred)49 void addPredicate(CompPredicate Pred) { Predicates.push_back(Pred); } 50 operator()51 bool operator()(object::SymbolRef LHS, object::SymbolRef RHS) { 52 for (CompPredicate Pred : Predicates) { 53 if (Pred(LHS, RHS)) 54 return true; 55 if (Pred(RHS, LHS)) 56 return false; 57 } 58 return false; 59 } 60 61 private: 62 SmallVector<CompPredicate, 2> Predicates; 63 }; 64 65 class ObjDumper { 66 public: 67 ObjDumper(ScopedPrinter &Writer, StringRef ObjName); 68 virtual ~ObjDumper(); 69 canDumpContent()70 virtual bool canDumpContent() { return true; } 71 72 virtual void printFileSummary(StringRef FileStr, object::ObjectFile &Obj, 73 ArrayRef<std::string> InputFilenames, 74 const object::Archive *A); 75 virtual void printFileHeaders() = 0; 76 virtual void printSectionHeaders() = 0; 77 virtual void printRelocations() = 0; printSymbols(bool PrintSymbols,bool PrintDynamicSymbols,bool ExtraSymInfo)78 virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols, 79 bool ExtraSymInfo) { 80 if (PrintSymbols) 81 printSymbols(ExtraSymInfo); 82 if (PrintDynamicSymbols) 83 printDynamicSymbols(); 84 } printSymbols(bool PrintSymbols,bool PrintDynamicSymbols,bool ExtraSymInfo,std::optional<SymbolComparator> SymComp)85 virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols, 86 bool ExtraSymInfo, 87 std::optional<SymbolComparator> SymComp) { 88 if (SymComp) { 89 if (PrintSymbols) 90 printSymbols(SymComp); 91 if (PrintDynamicSymbols) 92 printDynamicSymbols(SymComp); 93 } else { 94 printSymbols(PrintSymbols, PrintDynamicSymbols, ExtraSymInfo); 95 } 96 } printProgramHeaders(bool PrintProgramHeaders,cl::boolOrDefault PrintSectionMapping)97 virtual void printProgramHeaders(bool PrintProgramHeaders, 98 cl::boolOrDefault PrintSectionMapping) { 99 if (PrintProgramHeaders) 100 printProgramHeaders(); 101 if (PrintSectionMapping == cl::BOU_TRUE) 102 printSectionMapping(); 103 } 104 105 virtual void printUnwindInfo() = 0; 106 107 // Symbol comparison functions. canCompareSymbols()108 virtual bool canCompareSymbols() const { return false; } compareSymbolsByName(object::SymbolRef LHS,object::SymbolRef RHS)109 virtual bool compareSymbolsByName(object::SymbolRef LHS, 110 object::SymbolRef RHS) const { 111 return true; 112 } compareSymbolsByType(object::SymbolRef LHS,object::SymbolRef RHS)113 virtual bool compareSymbolsByType(object::SymbolRef LHS, 114 object::SymbolRef RHS) const { 115 return true; 116 } 117 118 // Only implemented for ELF at this time. printDependentLibs()119 virtual void printDependentLibs() {} printDynamicRelocations()120 virtual void printDynamicRelocations() { } printDynamicTable()121 virtual void printDynamicTable() { } printNeededLibraries()122 virtual void printNeededLibraries() { } printSectionAsHex(StringRef SectionName)123 virtual void printSectionAsHex(StringRef SectionName) {} printHashTable()124 virtual void printHashTable() { } printGnuHashTable()125 virtual void printGnuHashTable() {} printHashSymbols()126 virtual void printHashSymbols() {} printLoadName()127 virtual void printLoadName() {} printVersionInfo()128 virtual void printVersionInfo() {} printGroupSections()129 virtual void printGroupSections() {} printHashHistograms()130 virtual void printHashHistograms() {} printCGProfile()131 virtual void printCGProfile() {} 132 // If PrettyPGOAnalysis is true, prints BFI as relative frequency and BPI as 133 // percentage. Otherwise raw values are displayed. printBBAddrMaps(bool PrettyPGOAnalysis)134 virtual void printBBAddrMaps(bool PrettyPGOAnalysis) {} printAddrsig()135 virtual void printAddrsig() {} printNotes()136 virtual void printNotes() {} printELFLinkerOptions()137 virtual void printELFLinkerOptions() {} printStackSizes()138 virtual void printStackSizes() {} printSectionDetails()139 virtual void printSectionDetails() {} printArchSpecificInfo()140 virtual void printArchSpecificInfo() {} printMemtag()141 virtual void printMemtag() {} 142 143 // Only implemented for PE/COFF. printCOFFImports()144 virtual void printCOFFImports() { } printCOFFExports()145 virtual void printCOFFExports() { } printCOFFDirectives()146 virtual void printCOFFDirectives() { } printCOFFBaseReloc()147 virtual void printCOFFBaseReloc() { } printCOFFDebugDirectory()148 virtual void printCOFFDebugDirectory() { } printCOFFTLSDirectory()149 virtual void printCOFFTLSDirectory() {} printCOFFResources()150 virtual void printCOFFResources() {} printCOFFLoadConfig()151 virtual void printCOFFLoadConfig() { } printCodeViewDebugInfo()152 virtual void printCodeViewDebugInfo() { } 153 virtual void mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder & CVIDs,llvm::codeview::MergingTypeTableBuilder & CVTypes,llvm::codeview::GlobalTypeTableBuilder & GlobalCVIDs,llvm::codeview::GlobalTypeTableBuilder & GlobalCVTypes,bool GHash)154 mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs, 155 llvm::codeview::MergingTypeTableBuilder &CVTypes, 156 llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs, 157 llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes, 158 bool GHash) {} 159 160 // Only implemented for XCOFF. printStringTable()161 virtual void printStringTable() {} printAuxiliaryHeader()162 virtual void printAuxiliaryHeader() {} printExceptionSection()163 virtual void printExceptionSection() {} printLoaderSection(bool PrintHeader,bool PrintSymbols,bool PrintRelocations)164 virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols, 165 bool PrintRelocations) {} 166 167 // Only implemented for MachO. printMachODataInCode()168 virtual void printMachODataInCode() { } printMachOVersionMin()169 virtual void printMachOVersionMin() { } printMachODysymtab()170 virtual void printMachODysymtab() { } printMachOSegment()171 virtual void printMachOSegment() { } printMachOIndirectSymbols()172 virtual void printMachOIndirectSymbols() { } printMachOLinkerOptions()173 virtual void printMachOLinkerOptions() { } 174 175 virtual void printStackMap() const = 0; 176 177 void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0); 178 179 void printSectionsAsString(const object::ObjectFile &Obj, 180 ArrayRef<std::string> Sections, bool Decompress); 181 void printSectionsAsHex(const object::ObjectFile &Obj, 182 ArrayRef<std::string> Sections, bool Decompress); 183 184 std::function<Error(const Twine &Msg)> WarningHandler; 185 void reportUniqueWarning(Error Err) const; 186 void reportUniqueWarning(const Twine &Msg) const; 187 188 protected: 189 ScopedPrinter &W; 190 191 private: printSymbols(bool ExtraSymInfo)192 virtual void printSymbols(bool ExtraSymInfo) {} printSymbols(std::optional<SymbolComparator> Comp)193 virtual void printSymbols(std::optional<SymbolComparator> Comp) {} printDynamicSymbols()194 virtual void printDynamicSymbols() {} printDynamicSymbols(std::optional<SymbolComparator> Comp)195 virtual void printDynamicSymbols(std::optional<SymbolComparator> Comp) {} printProgramHeaders()196 virtual void printProgramHeaders() {} printSectionMapping()197 virtual void printSectionMapping() {} 198 199 std::unordered_set<std::string> Warnings; 200 }; 201 202 std::unique_ptr<ObjDumper> createCOFFDumper(const object::COFFObjectFile &Obj, 203 ScopedPrinter &Writer); 204 205 std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj, 206 ScopedPrinter &Writer); 207 208 std::unique_ptr<ObjDumper> createMachODumper(const object::MachOObjectFile &Obj, 209 ScopedPrinter &Writer); 210 211 std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj, 212 ScopedPrinter &Writer); 213 214 std::unique_ptr<ObjDumper> createXCOFFDumper(const object::XCOFFObjectFile &Obj, 215 ScopedPrinter &Writer); 216 217 void dumpCOFFImportFile(const object::COFFImportFile *File, 218 ScopedPrinter &Writer); 219 220 void dumpCodeViewMergedTypes(ScopedPrinter &Writer, 221 ArrayRef<ArrayRef<uint8_t>> IpiRecords, 222 ArrayRef<ArrayRef<uint8_t>> TpiRecords); 223 224 } // namespace llvm 225 226 #endif 227