237 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H10#define LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H11 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/Object/OffloadBinary.h"20#include "llvm/Support/CommandLine.h"21 22#include <unordered_set>23 24namespace llvm {25namespace object {26class Archive;27class COFFImportFile;28class ObjectFile;29class XCOFFObjectFile;30class ELFObjectFileBase;31} // namespace object32namespace codeview {33class GlobalTypeTableBuilder;34class MergingTypeTableBuilder;35} // namespace codeview36 37class ScopedPrinter;38 39// Comparator to compare symbols.40// Usage: the caller registers predicates (i.e., how to compare the symbols) by41// calling addPredicate(). The order in which predicates are registered is also42// their priority.43class SymbolComparator {44public:45 using CompPredicate =46 std::function<bool(object::SymbolRef, object::SymbolRef)>;47 48 // Each Obj format has a slightly different way of retrieving a symbol's info49 // So we defer the predicate's impl to each format.50 void addPredicate(CompPredicate Pred) { Predicates.push_back(Pred); }51 52 bool operator()(object::SymbolRef LHS, object::SymbolRef RHS) {53 for (CompPredicate Pred : Predicates) {54 if (Pred(LHS, RHS))55 return true;56 if (Pred(RHS, LHS))57 return false;58 }59 return false;60 }61 62private:63 SmallVector<CompPredicate, 2> Predicates;64};65 66class ObjDumper {67public:68 ObjDumper(ScopedPrinter &Writer, StringRef ObjName);69 virtual ~ObjDumper();70 71 virtual bool canDumpContent() { return true; }72 73 virtual void printFileSummary(StringRef FileStr, object::ObjectFile &Obj,74 ArrayRef<std::string> InputFilenames,75 const object::Archive *A);76 virtual void printFileHeaders() = 0;77 virtual void printSectionHeaders() = 0;78 virtual void printRelocations() = 0;79 virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,80 bool ExtraSymInfo) {81 if (PrintSymbols)82 printSymbols(ExtraSymInfo);83 if (PrintDynamicSymbols)84 printDynamicSymbols();85 }86 virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,87 bool ExtraSymInfo,88 std::optional<SymbolComparator> SymComp) {89 if (SymComp) {90 if (PrintSymbols)91 printSymbols(SymComp);92 if (PrintDynamicSymbols)93 printDynamicSymbols(SymComp);94 } else {95 printSymbols(PrintSymbols, PrintDynamicSymbols, ExtraSymInfo);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 // If PrettyPGOAnalysis is true, prints BFI as relative frequency and BPI as134 // percentage. Otherwise raw values are displayed.135 virtual void printBBAddrMaps(bool PrettyPGOAnalysis) {}136 virtual void printAddrsig() {}137 virtual void printNotes() {}138 virtual void printELFLinkerOptions() {}139 virtual void printStackSizes() {}140 virtual void printSectionDetails() {}141 virtual void printArchSpecificInfo() {}142 virtual void printMemtag() {}143 virtual void printSectionsAsSFrame(ArrayRef<std::string> Sections) {}144 145 // Only implemented for PE/COFF.146 virtual void printCOFFImports() { }147 virtual void printCOFFExports() { }148 virtual void printCOFFDirectives() { }149 virtual void printCOFFBaseReloc() { }150 virtual void printCOFFPseudoReloc() {}151 virtual void printCOFFDebugDirectory() { }152 virtual void printCOFFTLSDirectory() {}153 virtual void printCOFFResources() {}154 virtual void printCOFFLoadConfig() { }155 virtual void printCodeViewDebugInfo() { }156 virtual void157 mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs,158 llvm::codeview::MergingTypeTableBuilder &CVTypes,159 llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs,160 llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes,161 bool GHash) {}162 163 // Only implemented for XCOFF/COFF.164 virtual void printStringTable() {}165 166 // Only implemented for XCOFF.167 virtual void printAuxiliaryHeader() {}168 virtual void printExceptionSection() {}169 virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols,170 bool PrintRelocations) {}171 172 // Only implemented for MachO.173 virtual void printMachODataInCode() { }174 virtual void printMachOVersionMin() { }175 virtual void printMachODysymtab() { }176 virtual void printMachOSegment() { }177 virtual void printMachOIndirectSymbols() { }178 virtual void printMachOLinkerOptions() { }179 180 virtual void printStackMap() const = 0;181 182 void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0);183 184 void printSectionsAsString(const object::ObjectFile &Obj,185 ArrayRef<std::string> Sections, bool Decompress);186 void printSectionsAsHex(const object::ObjectFile &Obj,187 ArrayRef<std::string> Sections, bool Decompress);188 189 std::function<Error(const Twine &Msg)> WarningHandler;190 void reportUniqueWarning(Error Err) const;191 void reportUniqueWarning(const Twine &Msg) const;192 void printOffloading(const object::ObjectFile &Obj);193 194protected:195 ScopedPrinter &W;196 197 static std::vector<object::SectionRef>198 getSectionRefsByNameOrIndex(const object::ObjectFile &Obj,199 ArrayRef<std::string> Sections);200 201private:202 virtual void printSymbols(bool ExtraSymInfo) {}203 virtual void printSymbols(std::optional<SymbolComparator> Comp) {}204 virtual void printDynamicSymbols() {}205 virtual void printDynamicSymbols(std::optional<SymbolComparator> Comp) {}206 virtual void printProgramHeaders() {}207 virtual void printSectionMapping() {}208 209 std::unordered_set<std::string> Warnings;210};211 212std::unique_ptr<ObjDumper> createCOFFDumper(const object::COFFObjectFile &Obj,213 ScopedPrinter &Writer);214 215std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,216 ScopedPrinter &Writer);217 218std::unique_ptr<ObjDumper> createMachODumper(const object::MachOObjectFile &Obj,219 ScopedPrinter &Writer);220 221std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj,222 ScopedPrinter &Writer);223 224std::unique_ptr<ObjDumper> createXCOFFDumper(const object::XCOFFObjectFile &Obj,225 ScopedPrinter &Writer);226 227void dumpCOFFImportFile(const object::COFFImportFile *File,228 ScopedPrinter &Writer);229 230void dumpCodeViewMergedTypes(ScopedPrinter &Writer,231 ArrayRef<ArrayRef<uint8_t>> IpiRecords,232 ArrayRef<ArrayRef<uint8_t>> TpiRecords);233 234} // namespace llvm235 236#endif237