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