LLVM API Documentation

SymbolicFile.h
Go to the documentation of this file.
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