1 //===--- llvm-objdump.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_OBJDUMP_LLVM_OBJDUMP_H
10 #define LLVM_TOOLS_LLVM_OBJDUMP_LLVM_OBJDUMP_H
11 
12 #include "llvm/ADT/StringSet.h"
13 #include "llvm/DebugInfo/DIContext.h"
14 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
15 #include "llvm/Object/Archive.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/DataTypes.h"
18 
19 namespace llvm {
20 class StringRef;
21 class Twine;
22 
23 namespace object {
24 class RelocationRef;
25 struct VersionEntry;
26 } // namespace object
27 
28 namespace objdump {
29 
30 enum DebugVarsFormat { DVDisabled, DVUnicode, DVASCII, DVInvalid };
31 
32 extern bool ArchiveHeaders;
33 extern int DbgIndent;
34 extern DebugVarsFormat DbgVariables;
35 extern bool Demangle;
36 extern bool Disassemble;
37 extern bool DisassembleAll;
38 extern DIDumpType DwarfDumpType;
39 extern std::vector<std::string> FilterSections;
40 extern bool LeadingAddr;
41 extern std::vector<std::string> MAttrs;
42 extern std::string MCPU;
43 extern std::string Prefix;
44 extern uint32_t PrefixStrip;
45 extern bool PrintImmHex;
46 extern bool PrintLines;
47 extern bool PrintSource;
48 extern bool PrivateHeaders;
49 extern bool Relocations;
50 extern bool SectionHeaders;
51 extern bool SectionContents;
52 extern bool ShowRawInsn;
53 extern bool SymbolDescription;
54 extern bool SymbolTable;
55 extern std::string TripleName;
56 extern bool UnwindInfo;
57 
58 extern StringSet<> FoundSectionSet;
59 
60 typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
61 
62 /// A filtered iterator for SectionRefs that skips sections based on some given
63 /// predicate.
64 class SectionFilterIterator {
65 public:
66   SectionFilterIterator(FilterPredicate P,
67                         llvm::object::section_iterator const &I,
68                         llvm::object::section_iterator const &E)
69       : Predicate(std::move(P)), Iterator(I), End(E) {
70     ScanPredicate();
71   }
72   const llvm::object::SectionRef &operator*() const { return *Iterator; }
73   SectionFilterIterator &operator++() {
74     ++Iterator;
75     ScanPredicate();
76     return *this;
77   }
78   bool operator!=(SectionFilterIterator const &Other) const {
79     return Iterator != Other.Iterator;
80   }
81 
82 private:
83   void ScanPredicate() {
84     while (Iterator != End && !Predicate(*Iterator)) {
85       ++Iterator;
86     }
87   }
88   FilterPredicate Predicate;
89   llvm::object::section_iterator Iterator;
90   llvm::object::section_iterator End;
91 };
92 
93 /// Creates an iterator range of SectionFilterIterators for a given Object and
94 /// predicate.
95 class SectionFilter {
96 public:
97   SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
98       : Predicate(std::move(P)), Object(O) {}
99   SectionFilterIterator begin() {
100     return SectionFilterIterator(Predicate, Object.section_begin(),
101                                  Object.section_end());
102   }
103   SectionFilterIterator end() {
104     return SectionFilterIterator(Predicate, Object.section_end(),
105                                  Object.section_end());
106   }
107 
108 private:
109   FilterPredicate Predicate;
110   llvm::object::ObjectFile const &Object;
111 };
112 
113 // Various helper functions.
114 
115 /// Creates a SectionFilter with a standard predicate that conditionally skips
116 /// sections when the --section objdump flag is provided.
117 ///
118 /// Idx is an optional output parameter that keeps track of which section index
119 /// this is. This may be different than the actual section number, as some
120 /// sections may be filtered (e.g. symbol tables).
121 SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O,
122                                 uint64_t *Idx = nullptr);
123 
124 bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
125 void printRelocations(const object::ObjectFile *O);
126 void printDynamicRelocations(const object::ObjectFile *O);
127 void printSectionHeaders(object::ObjectFile &O);
128 void printSectionContents(const object::ObjectFile *O);
129 void printSymbolTable(const object::ObjectFile &O, StringRef ArchiveName,
130                       StringRef ArchitectureName = StringRef(),
131                       bool DumpDynamic = false);
132 void printSymbol(const object::ObjectFile &O, const object::SymbolRef &Symbol,
133                  ArrayRef<object::VersionEntry> SymbolVersions,
134                  StringRef FileName, StringRef ArchiveName,
135                  StringRef ArchitectureName, bool DumpDynamic);
136 [[noreturn]] void reportError(StringRef File, const Twine &Message);
137 [[noreturn]] void reportError(Error E, StringRef FileName,
138                               StringRef ArchiveName = "",
139                               StringRef ArchitectureName = "");
140 void reportWarning(const Twine &Message, StringRef File);
141 
142 template <typename T, typename... Ts>
143 T unwrapOrError(Expected<T> EO, Ts &&... Args) {
144   if (EO)
145     return std::move(*EO);
146   reportError(EO.takeError(), std::forward<Ts>(Args)...);
147 }
148 
149 std::string getFileNameForError(const object::Archive::Child &C,
150                                 unsigned Index);
151 SymbolInfoTy createSymbolInfo(const object::ObjectFile &Obj,
152                               const object::SymbolRef &Symbol);
153 
154 } // namespace objdump
155 } // end namespace llvm
156 
157 #endif
158