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
23namespace llvm {
24namespace object {
25class Archive;
26class COFFImportFile;
27class ObjectFile;
28class XCOFFObjectFile;
29class ELFObjectFileBase;
30} // namespace object
31namespace codeview {
32class GlobalTypeTableBuilder;
33class MergingTypeTableBuilder;
34} // namespace codeview
35
36class 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.
42class SymbolComparator {
43public:
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.
49  void addPredicate(CompPredicate Pred) { Predicates.push_back(Pred); }
50
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
61private:
62  SmallVector<CompPredicate, 2> Predicates;
63};
64
65class ObjDumper {
66public:
67  ObjDumper(ScopedPrinter &Writer, StringRef ObjName);
68  virtual ~ObjDumper();
69
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;
78  virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
79                            bool ExtraSymInfo) {
80    if (PrintSymbols)
81      printSymbols(ExtraSymInfo);
82    if (PrintDynamicSymbols)
83      printDynamicSymbols();
84  }
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  }
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.
108  virtual bool canCompareSymbols() const { return false; }
109  virtual bool compareSymbolsByName(object::SymbolRef LHS,
110                                    object::SymbolRef RHS) const {
111    return true;
112  }
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.
119  virtual void printDependentLibs() {}
120  virtual void printDynamicRelocations() { }
121  virtual void printDynamicTable() { }
122  virtual void printNeededLibraries() { }
123  virtual void printSectionAsHex(StringRef SectionName) {}
124  virtual void printHashTable() { }
125  virtual void printGnuHashTable() {}
126  virtual void printHashSymbols() {}
127  virtual void printLoadName() {}
128  virtual void printVersionInfo() {}
129  virtual void printGroupSections() {}
130  virtual void printHashHistograms() {}
131  virtual void printCGProfile() {}
132  virtual void printBBAddrMaps() {}
133  virtual void printAddrsig() {}
134  virtual void printNotes() {}
135  virtual void printELFLinkerOptions() {}
136  virtual void printStackSizes() {}
137  virtual void printSectionDetails() {}
138  virtual void printArchSpecificInfo() {}
139  virtual void printMemtag() {}
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 implemented for XCOFF.
159  virtual void printStringTable() {}
160  virtual void printAuxiliaryHeader() {}
161  virtual void printExceptionSection() {}
162  virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols,
163                                  bool PrintRelocations) {}
164
165  // Only implemented for MachO.
166  virtual void printMachODataInCode() { }
167  virtual void printMachOVersionMin() { }
168  virtual void printMachODysymtab() { }
169  virtual void printMachOSegment() { }
170  virtual void printMachOIndirectSymbols() { }
171  virtual void printMachOLinkerOptions() { }
172
173  virtual void printStackMap() const = 0;
174
175  void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0);
176
177  void printSectionsAsString(const object::ObjectFile &Obj,
178                             ArrayRef<std::string> Sections, bool Decompress);
179  void printSectionsAsHex(const object::ObjectFile &Obj,
180                          ArrayRef<std::string> Sections, bool Decompress);
181
182  std::function<Error(const Twine &Msg)> WarningHandler;
183  void reportUniqueWarning(Error Err) const;
184  void reportUniqueWarning(const Twine &Msg) const;
185
186protected:
187  ScopedPrinter &W;
188
189private:
190  virtual void printSymbols(bool ExtraSymInfo) {}
191  virtual void printSymbols(std::optional<SymbolComparator> Comp) {}
192  virtual void printDynamicSymbols() {}
193  virtual void printDynamicSymbols(std::optional<SymbolComparator> Comp) {}
194  virtual void printProgramHeaders() {}
195  virtual void printSectionMapping() {}
196
197  std::unordered_set<std::string> Warnings;
198};
199
200std::unique_ptr<ObjDumper> createCOFFDumper(const object::COFFObjectFile &Obj,
201                                            ScopedPrinter &Writer);
202
203std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
204                                           ScopedPrinter &Writer);
205
206std::unique_ptr<ObjDumper> createMachODumper(const object::MachOObjectFile &Obj,
207                                             ScopedPrinter &Writer);
208
209std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj,
210                                            ScopedPrinter &Writer);
211
212std::unique_ptr<ObjDumper> createXCOFFDumper(const object::XCOFFObjectFile &Obj,
213                                             ScopedPrinter &Writer);
214
215void dumpCOFFImportFile(const object::COFFImportFile *File,
216                        ScopedPrinter &Writer);
217
218void dumpCodeViewMergedTypes(ScopedPrinter &Writer,
219                             ArrayRef<ArrayRef<uint8_t>> IpiRecords,
220                             ArrayRef<ArrayRef<uint8_t>> TpiRecords);
221
222} // namespace llvm
223
224#endif
225