LLVM  8.0.1
SymbolicFile.h
Go to the documentation of this file.
1 //===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the SymbolicFile interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_OBJECT_SYMBOLICFILE_H
15 #define LLVM_OBJECT_SYMBOLICFILE_H
16 
17 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Support/Error.h"
23 #include "llvm/Support/Format.h"
25 #include <cinttypes>
26 #include <cstdint>
27 #include <cstring>
28 #include <iterator>
29 #include <memory>
30 #include <system_error>
31 
32 namespace llvm {
33 namespace object {
34 
35 union DataRefImpl {
36  // This entire union should probably be a
37  // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
38  struct {
40  } d;
41  uintptr_t p;
42 
43  DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
44 };
45 
46 template <typename OStream>
47 OStream& operator<<(OStream &OS, const DataRefImpl &D) {
48  OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
49  << ", " << format("0x%08x", D.d.b) << "))";
50  return OS;
51 }
52 
53 inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
54  // Check bitwise identical. This is the only legal way to compare a union w/o
55  // knowing which member is in use.
56  return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
57 }
58 
59 inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
60  return !operator==(a, b);
61 }
62 
63 inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
64  // Check bitwise identical. This is the only legal way to compare a union w/o
65  // knowing which member is in use.
66  return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
67 }
68 
69 template <class content_type>
71  : public std::iterator<std::forward_iterator_tag, content_type> {
72  content_type Current;
73 
74 public:
75  content_iterator(content_type symb) : Current(std::move(symb)) {}
76 
77  const content_type *operator->() const { return &Current; }
78 
79  const content_type &operator*() const { return Current; }
80 
81  bool operator==(const content_iterator &other) const {
82  return Current == other.Current;
83  }
84 
85  bool operator!=(const content_iterator &other) const {
86  return !(*this == other);
87  }
88 
89  content_iterator &operator++() { // preincrement
90  Current.moveNext();
91  return *this;
92  }
93 };
94 
95 class SymbolicFile;
96 
97 /// This is a value type class that represents a single symbol in the list of
98 /// symbols in the object file.
100  DataRefImpl SymbolPimpl;
101  const SymbolicFile *OwningObject = nullptr;
102 
103 public:
104  enum Flags : unsigned {
105  SF_None = 0,
106  SF_Undefined = 1U << 0, // Symbol is defined in another object file
107  SF_Global = 1U << 1, // Global symbol
108  SF_Weak = 1U << 2, // Weak symbol
109  SF_Absolute = 1U << 3, // Absolute symbol
110  SF_Common = 1U << 4, // Symbol has common linkage
111  SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
112  SF_Exported = 1U << 6, // Symbol is visible to other DSOs
113  SF_FormatSpecific = 1U << 7, // Specific to the object file format
114  // (e.g. section symbols)
115  SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
116  SF_Hidden = 1U << 9, // Symbol has hidden visibility
117  SF_Const = 1U << 10, // Symbol value is constant
118  SF_Executable = 1U << 11, // Symbol points to an executable section
119  // (IR only)
120  };
121 
122  BasicSymbolRef() = default;
123  BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
124 
125  bool operator==(const BasicSymbolRef &Other) const;
126  bool operator<(const BasicSymbolRef &Other) const;
127 
128  void moveNext();
129 
130  std::error_code printName(raw_ostream &OS) const;
131 
132  /// Get symbol flags (bitwise OR of SymbolRef::Flags)
133  uint32_t getFlags() const;
134 
135  DataRefImpl getRawDataRefImpl() const;
136  const SymbolicFile *getObject() const;
137 };
138 
140 
141 class SymbolicFile : public Binary {
142 public:
143  SymbolicFile(unsigned int Type, MemoryBufferRef Source);
144  ~SymbolicFile() override;
145 
146  // virtual interface.
147  virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
148 
149  virtual std::error_code printSymbolName(raw_ostream &OS,
150  DataRefImpl Symb) const = 0;
151 
152  virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
153 
154  virtual basic_symbol_iterator symbol_begin() const = 0;
155 
156  virtual basic_symbol_iterator symbol_end() const = 0;
157 
158  // convenience wrappers.
161  return basic_symbol_iterator_range(symbol_begin(), symbol_end());
162  }
163 
164  // construction aux.
166  createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
168 
171  return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
172  }
174  createSymbolicFile(StringRef ObjectPath);
175 
176  static bool classof(const Binary *v) {
177  return v->isSymbolic();
178  }
179 };
180 
182  const SymbolicFile *Owner)
183  : SymbolPimpl(SymbolP), OwningObject(Owner) {}
184 
185 inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
186  return SymbolPimpl == Other.SymbolPimpl;
187 }
188 
189 inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
190  return SymbolPimpl < Other.SymbolPimpl;
191 }
192 
194  return OwningObject->moveSymbolNext(SymbolPimpl);
195 }
196 
197 inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
198  return OwningObject->printSymbolName(OS, SymbolPimpl);
199 }
200 
202  return OwningObject->getSymbolFlags(SymbolPimpl);
203 }
204 
206  return SymbolPimpl;
207 }
208 
210  return OwningObject;
211 }
212 
213 } // end namespace object
214 } // end namespace llvm
215 
216 #endif // LLVM_OBJECT_SYMBOLICFILE_H
bool operator<(const BasicSymbolRef &Other) const
Definition: SymbolicFile.h:189
std::error_code printName(raw_ostream &OS) const
Definition: SymbolicFile.h:197
const content_type & operator*() const
Definition: SymbolicFile.h:79
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:24
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
static std::error_code getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
bool operator==(const content_iterator &other) const
Definition: SymbolicFile.h:81
static void printName(raw_ostream &OS, StringRef Name)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
bool operator<(const DataRefImpl &a, const DataRefImpl &b)
Definition: SymbolicFile.h:63
bool operator!=(const content_iterator &other) const
Definition: SymbolicFile.h:85
bool isSymbolic() const
Definition: Binary.h:99
Definition: BitVector.h:938
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:205
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
bool operator!=(const DataRefImpl &a, const DataRefImpl &b)
Definition: SymbolicFile.h:59
struct llvm::object::DataRefImpl::@282 d
const content_type * operator->() const
Definition: SymbolicFile.h:77
content_iterator(content_type symb)
Definition: SymbolicFile.h:75
virtual uint32_t getSymbolFlags(DataRefImpl Symb) const =0
bool operator==(const BasicSymbolRef &Other) const
Definition: SymbolicFile.h:185
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
const SymbolicFile * getObject() const
Definition: SymbolicFile.h:209
bool operator==(const DataRefImpl &a, const DataRefImpl &b)
Definition: SymbolicFile.h:53
content_iterator & operator++()
Definition: SymbolicFile.h:89
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
A range adaptor for a pair of iterators.
uint32_t getFlags() const
Get symbol flags (bitwise OR of SymbolRef::Flags)
Definition: SymbolicFile.h:201
Merge contiguous icmps into a memcmp
Definition: MergeICmps.cpp:867
virtual std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const =0
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: SymbolicFile.h:99
virtual void moveSymbolNext(DataRefImpl &Symb) const =0
basic_symbol_iterator_range symbols() const
Definition: SymbolicFile.h:160
OStream & operator<<(OStream &OS, const DataRefImpl &D)
Definition: SymbolicFile.h:47
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static bool classof(const Binary *v)
Definition: SymbolicFile.h:176
Unrecognized file.
Definition: Magic.h:23
static Expected< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object)
Definition: SymbolicFile.h:170
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:21