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_SYMBOLIC_FILE_H 15#define LLVM_OBJECT_SYMBOLIC_FILE_H 16 17#include "llvm/Object/Binary.h" 18 19namespace llvm { 20namespace object { 21 22union DataRefImpl { 23 // This entire union should probably be a 24 // char[max(8, sizeof(uintptr_t))] and require the impl to cast. 25 struct { 26 uint32_t a, b; 27 } d; 28 uintptr_t p; 29 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); } 30}; 31 32inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) { 33 // Check bitwise identical. This is the only legal way to compare a union w/o 34 // knowing which member is in use. 35 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; 36} 37 38inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) { 39 return !operator==(a, b); 40} 41 42inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { 43 // Check bitwise identical. This is the only legal way to compare a union w/o 44 // knowing which member is in use. 45 return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; 46} 47 48template <class content_type> class content_iterator { 49 content_type Current; 50 51public: 52 content_iterator(content_type symb) : Current(symb) {} 53 54 const content_type *operator->() const { return &Current; } 55 56 const content_type &operator*() const { return Current; } 57 58 bool operator==(const content_iterator &other) const { 59 return Current == other.Current; 60 } 61 62 bool operator!=(const content_iterator &other) const { 63 return !(*this == other); 64 } 65 66 content_iterator &operator++() { // preincrement 67 Current.moveNext(); 68 return *this; 69 } 70}; 71 72class SymbolicFile; 73 74/// This is a value type class that represents a single symbol in the list of 75/// symbols in the object file. 76class BasicSymbolRef { 77 DataRefImpl SymbolPimpl; 78 const SymbolicFile *OwningObject; 79 80public: 81 // FIXME: should we add a SF_Text? 82 enum Flags : unsigned { 83 SF_None = 0, 84 SF_Undefined = 1U << 0, // Symbol is defined in another object file 85 SF_Global = 1U << 1, // Global symbol 86 SF_Weak = 1U << 2, // Weak symbol 87 SF_Absolute = 1U << 3, // Absolute symbol 88 SF_Common = 1U << 4, // Symbol has common linkage 89 SF_Indirect = 1U << 5, // Symbol is an alias to another symbol 90 SF_FormatSpecific = 1U << 6 // Specific to the object file format 91 // (e.g. section symbols) 92 }; 93 94 BasicSymbolRef() : OwningObject(nullptr) { } 95 BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner); 96 97 bool operator==(const BasicSymbolRef &Other) const; 98 bool operator<(const BasicSymbolRef &Other) const; 99 100 void moveNext(); 101 102 std::error_code printName(raw_ostream &OS) const; 103 104 /// Get symbol flags (bitwise OR of SymbolRef::Flags) 105 uint32_t getFlags() const; 106 107 DataRefImpl getRawDataRefImpl() const; 108 const SymbolicFile *getObject() const; 109}; 110 111typedef content_iterator<BasicSymbolRef> basic_symbol_iterator; 112 113const uint64_t UnknownAddressOrSize = ~0ULL; 114 115class SymbolicFile : public Binary { 116public: 117 virtual ~SymbolicFile(); 118 SymbolicFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); 119 120 // virtual interface. 121 virtual void moveSymbolNext(DataRefImpl &Symb) const = 0; 122 123 virtual std::error_code printSymbolName(raw_ostream &OS, 124 DataRefImpl Symb) const = 0; 125 126 virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0; 127 128 virtual basic_symbol_iterator symbol_begin_impl() const = 0; 129 130 virtual basic_symbol_iterator symbol_end_impl() const = 0; 131 132 // convenience wrappers. 133 basic_symbol_iterator symbol_begin() const { 134 return symbol_begin_impl(); 135 } 136 basic_symbol_iterator symbol_end() const { 137 return symbol_end_impl(); 138 } 139 typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range; 140 basic_symbol_iterator_range symbols() const { 141 return basic_symbol_iterator_range(symbol_begin(), symbol_end()); 142 } 143 144 // construction aux. 145 static ErrorOr<SymbolicFile *> 146 createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object, 147 sys::fs::file_magic Type, LLVMContext *Context); 148 149 static ErrorOr<SymbolicFile *> 150 createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) { 151 return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr); 152 } 153 static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath); 154 155 static inline bool classof(const Binary *v) { 156 return v->isSymbolic(); 157 } 158}; 159 160inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP, 161 const SymbolicFile *Owner) 162 : SymbolPimpl(SymbolP), OwningObject(Owner) {} 163 164inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const { 165 return SymbolPimpl == Other.SymbolPimpl; 166} 167 168inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const { 169 return SymbolPimpl < Other.SymbolPimpl; 170} 171 172inline void BasicSymbolRef::moveNext() { 173 return OwningObject->moveSymbolNext(SymbolPimpl); 174} 175 176inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const { 177 return OwningObject->printSymbolName(OS, SymbolPimpl); 178} 179 180inline uint32_t BasicSymbolRef::getFlags() const { 181 return OwningObject->getSymbolFlags(SymbolPimpl); 182} 183 184inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const { 185 return SymbolPimpl; 186} 187 188inline const SymbolicFile *BasicSymbolRef::getObject() const { 189 return OwningObject; 190} 191 192} 193} 194 195#endif 196