1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 
8 #ifndef LLVM_TOOLS_LLVM_OBJDUMP_LLVM_OBJDUMP_H
9 #define LLVM_TOOLS_LLVM_OBJDUMP_LLVM_OBJDUMP_H
10 
11 #include "llvm/DebugInfo/DIContext.h"
12 #include "llvm/Support/CommandLine.h"
13 #include "llvm/Support/Compiler.h"
14 #include "llvm/Support/DataTypes.h"
15 #include "llvm/Object/Archive.h"
16 
17 namespace llvm {
18 class StringRef;
19 
20 namespace object {
21 class ELFObjectFileBase;
22 class ELFSectionRef;
23 class MachOObjectFile;
24 class MachOUniversalBinary;
25 class RelocationRef;
26 }
27 
28 extern cl::opt<bool> Demangle;
29 
30 typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
31 
32 /// A filtered iterator for SectionRefs that skips sections based on some given
33 /// predicate.
34 class SectionFilterIterator {
35 public:
36   SectionFilterIterator(FilterPredicate P,
37                         llvm::object::section_iterator const &I,
38                         llvm::object::section_iterator const &E)
39       : Predicate(std::move(P)), Iterator(I), End(E) {
40     ScanPredicate();
41   }
42   const llvm::object::SectionRef &operator*() const { return *Iterator; }
43   SectionFilterIterator &operator++() {
44     ++Iterator;
45     ScanPredicate();
46     return *this;
47   }
48   bool operator!=(SectionFilterIterator const &Other) const {
49     return Iterator != Other.Iterator;
50   }
51 
52 private:
53   void ScanPredicate() {
54     while (Iterator != End && !Predicate(*Iterator)) {
55       ++Iterator;
56     }
57   }
58   FilterPredicate Predicate;
59   llvm::object::section_iterator Iterator;
60   llvm::object::section_iterator End;
61 };
62 
63 /// Creates an iterator range of SectionFilterIterators for a given Object and
64 /// predicate.
65 class SectionFilter {
66 public:
67   SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
68       : Predicate(std::move(P)), Object(O) {}
69   SectionFilterIterator begin() {
70     return SectionFilterIterator(Predicate, Object.section_begin(),
71                                  Object.section_end());
72   }
73   SectionFilterIterator end() {
74     return SectionFilterIterator(Predicate, Object.section_end(),
75                                  Object.section_end());
76   }
77 
78 private:
79   FilterPredicate Predicate;
80   llvm::object::ObjectFile const &Object;
81 };
82 
83 // Various helper functions.
84 
85 /// Creates a SectionFilter with a standard predicate that conditionally skips
86 /// sections when the --section objdump flag is provided.
87 ///
88 /// Idx is an optional output parameter that keeps track of which section index
89 /// this is. This may be different than the actual section number, as some
90 /// sections may be filtered (e.g. symbol tables).
91 SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O,
92                                 uint64_t *Idx = nullptr);
93 
94 Error getELFRelocationValueString(const object::ELFObjectFileBase *Obj,
95                                   const object::RelocationRef &Rel,
96                                   llvm::SmallVectorImpl<char> &Result);
97 Error getWasmRelocationValueString(const object::WasmObjectFile *Obj,
98                                    const object::RelocationRef &RelRef,
99                                    llvm::SmallVectorImpl<char> &Result);
100 Error getMachORelocationValueString(const object::MachOObjectFile *Obj,
101                                     const object::RelocationRef &RelRef,
102                                     llvm::SmallVectorImpl<char> &Result);
103 
104 uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec);
105 
106 bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
107 void parseInputMachO(StringRef Filename);
108 void parseInputMachO(object::MachOUniversalBinary *UB);
109 void printMachOUnwindInfo(const object::MachOObjectFile *O);
110 void printMachOExportsTrie(const object::MachOObjectFile *O);
111 void printMachORebaseTable(object::MachOObjectFile *O);
112 void printMachOBindTable(object::MachOObjectFile *O);
113 void printMachOLazyBindTable(object::MachOObjectFile *O);
114 void printMachOWeakBindTable(object::MachOObjectFile *O);
115 void printELFFileHeader(const object::ObjectFile *O);
116 void printELFDynamicSection(const object::ObjectFile *Obj);
117 void printELFSymbolVersionInfo(const object::ObjectFile *Obj);
118 void printMachOFileHeader(const object::ObjectFile *O);
119 void printMachOLoadCommands(const object::ObjectFile *O);
120 void printWasmFileHeader(const object::ObjectFile *O);
121 void printExportsTrie(const object::ObjectFile *O);
122 void printRebaseTable(object::ObjectFile *O);
123 void printBindTable(object::ObjectFile *O);
124 void printLazyBindTable(object::ObjectFile *O);
125 void printWeakBindTable(object::ObjectFile *O);
126 void printRawClangAST(const object::ObjectFile *O);
127 void printRelocations(const object::ObjectFile *O);
128 void printDynamicRelocations(const object::ObjectFile *O);
129 void printSectionHeaders(const object::ObjectFile *O);
130 void printSectionContents(const object::ObjectFile *O);
131 void printSymbolTable(const object::ObjectFile *O, StringRef ArchiveName,
132                       StringRef ArchitectureName = StringRef(),
133                       bool DumpDynamic = false);
134 void printSymbol(const object::ObjectFile *O, const object::SymbolRef &Symbol,
135                  StringRef FileName, StringRef ArchiveName,
136                  StringRef ArchitectureName, bool DumpDynamic);
137 LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Twine Message);
138 LLVM_ATTRIBUTE_NORETURN void reportError(Error E, StringRef FileName,
139                                          StringRef ArchiveName = "",
140                                          StringRef ArchitectureName = "");
141 void reportWarning(Twine Message, StringRef File);
142 
143 template <typename T, typename... Ts>
144 T unwrapOrError(Expected<T> EO, Ts &&... Args) {
145   if (EO)
146     return std::move(*EO);
147   reportError(EO.takeError(), std::forward<Ts>(Args)...);
148 }
149 
150 std::string getFileNameForError(const object::Archive::Child &C,
151                                 unsigned Index);
152 
153 } // end namespace llvm
154 
155 #endif
156