LLVM API Documentation
00001 //===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the SymbolicFile interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_OBJECT_SYMBOLICFILE_H 00015 #define LLVM_OBJECT_SYMBOLICFILE_H 00016 00017 #include "llvm/Object/Binary.h" 00018 00019 namespace llvm { 00020 namespace object { 00021 00022 union DataRefImpl { 00023 // This entire union should probably be a 00024 // char[max(8, sizeof(uintptr_t))] and require the impl to cast. 00025 struct { 00026 uint32_t a, b; 00027 } d; 00028 uintptr_t p; 00029 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); } 00030 }; 00031 00032 inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) { 00033 // Check bitwise identical. This is the only legal way to compare a union w/o 00034 // knowing which member is in use. 00035 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; 00036 } 00037 00038 inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) { 00039 return !operator==(a, b); 00040 } 00041 00042 inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { 00043 // Check bitwise identical. This is the only legal way to compare a union w/o 00044 // knowing which member is in use. 00045 return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; 00046 } 00047 00048 template <class content_type> class content_iterator { 00049 content_type Current; 00050 00051 public: 00052 content_iterator(content_type symb) : Current(symb) {} 00053 00054 const content_type *operator->() const { return &Current; } 00055 00056 const content_type &operator*() const { return Current; } 00057 00058 bool operator==(const content_iterator &other) const { 00059 return Current == other.Current; 00060 } 00061 00062 bool operator!=(const content_iterator &other) const { 00063 return !(*this == other); 00064 } 00065 00066 content_iterator &operator++() { // preincrement 00067 Current.moveNext(); 00068 return *this; 00069 } 00070 }; 00071 00072 class SymbolicFile; 00073 00074 /// This is a value type class that represents a single symbol in the list of 00075 /// symbols in the object file. 00076 class BasicSymbolRef { 00077 DataRefImpl SymbolPimpl; 00078 const SymbolicFile *OwningObject; 00079 00080 public: 00081 // FIXME: should we add a SF_Text? 00082 enum Flags : unsigned { 00083 SF_None = 0, 00084 SF_Undefined = 1U << 0, // Symbol is defined in another object file 00085 SF_Global = 1U << 1, // Global symbol 00086 SF_Weak = 1U << 2, // Weak symbol 00087 SF_Absolute = 1U << 3, // Absolute symbol 00088 SF_Common = 1U << 4, // Symbol has common linkage 00089 SF_Indirect = 1U << 5, // Symbol is an alias to another symbol 00090 SF_FormatSpecific = 1U << 6, // Specific to the object file format 00091 // (e.g. section symbols) 00092 SF_Thumb = 1U << 7 // Thumb symbol in a 32-bit ARM binary 00093 }; 00094 00095 BasicSymbolRef() : OwningObject(nullptr) { } 00096 BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner); 00097 00098 bool operator==(const BasicSymbolRef &Other) const; 00099 bool operator<(const BasicSymbolRef &Other) const; 00100 00101 void moveNext(); 00102 00103 std::error_code printName(raw_ostream &OS) const; 00104 00105 /// Get symbol flags (bitwise OR of SymbolRef::Flags) 00106 uint32_t getFlags() const; 00107 00108 DataRefImpl getRawDataRefImpl() const; 00109 const SymbolicFile *getObject() const; 00110 }; 00111 00112 typedef content_iterator<BasicSymbolRef> basic_symbol_iterator; 00113 00114 const uint64_t UnknownAddressOrSize = ~0ULL; 00115 00116 class SymbolicFile : public Binary { 00117 public: 00118 virtual ~SymbolicFile(); 00119 SymbolicFile(unsigned int Type, MemoryBufferRef Source); 00120 00121 // virtual interface. 00122 virtual void moveSymbolNext(DataRefImpl &Symb) const = 0; 00123 00124 virtual std::error_code printSymbolName(raw_ostream &OS, 00125 DataRefImpl Symb) const = 0; 00126 00127 virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0; 00128 00129 virtual basic_symbol_iterator symbol_begin_impl() const = 0; 00130 00131 virtual basic_symbol_iterator symbol_end_impl() const = 0; 00132 00133 // convenience wrappers. 00134 basic_symbol_iterator symbol_begin() const { 00135 return symbol_begin_impl(); 00136 } 00137 basic_symbol_iterator symbol_end() const { 00138 return symbol_end_impl(); 00139 } 00140 typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range; 00141 basic_symbol_iterator_range symbols() const { 00142 return basic_symbol_iterator_range(symbol_begin(), symbol_end()); 00143 } 00144 00145 // construction aux. 00146 static ErrorOr<std::unique_ptr<SymbolicFile>> 00147 createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type, 00148 LLVMContext *Context); 00149 00150 static ErrorOr<std::unique_ptr<SymbolicFile>> 00151 createSymbolicFile(MemoryBufferRef Object) { 00152 return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr); 00153 } 00154 static ErrorOr<OwningBinary<SymbolicFile>> 00155 createSymbolicFile(StringRef ObjectPath); 00156 00157 static inline bool classof(const Binary *v) { 00158 return v->isSymbolic(); 00159 } 00160 }; 00161 00162 inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP, 00163 const SymbolicFile *Owner) 00164 : SymbolPimpl(SymbolP), OwningObject(Owner) {} 00165 00166 inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const { 00167 return SymbolPimpl == Other.SymbolPimpl; 00168 } 00169 00170 inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const { 00171 return SymbolPimpl < Other.SymbolPimpl; 00172 } 00173 00174 inline void BasicSymbolRef::moveNext() { 00175 return OwningObject->moveSymbolNext(SymbolPimpl); 00176 } 00177 00178 inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const { 00179 return OwningObject->printSymbolName(OS, SymbolPimpl); 00180 } 00181 00182 inline uint32_t BasicSymbolRef::getFlags() const { 00183 return OwningObject->getSymbolFlags(SymbolPimpl); 00184 } 00185 00186 inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const { 00187 return SymbolPimpl; 00188 } 00189 00190 inline const SymbolicFile *BasicSymbolRef::getObject() const { 00191 return OwningObject; 00192 } 00193 00194 } 00195 } 00196 00197 #endif