Home | History | Annotate | Download | only in Object
      1 //===- ObjectFile.h - File format independent object file -------*- 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 a file format independent ObjectFile class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_OBJECT_OBJECT_FILE_H
     15 #define LLVM_OBJECT_OBJECT_FILE_H
     16 
     17 #include "llvm/Object/Binary.h"
     18 #include "llvm/ADT/StringRef.h"
     19 #include "llvm/Support/DataTypes.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 #include "llvm/Support/MemoryBuffer.h"
     22 #include <cstring>
     23 
     24 namespace llvm {
     25 namespace object {
     26 
     27 class ObjectFile;
     28 
     29 union DataRefImpl {
     30   struct {
     31     // ELF needs this for relocations. This entire union should probably be a
     32     // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
     33     uint16_t a, b;
     34     uint32_t c;
     35   } w;
     36   struct {
     37     uint32_t a, b;
     38   } d;
     39   uintptr_t p;
     40 };
     41 
     42 template<class content_type>
     43 class content_iterator {
     44   content_type Current;
     45 public:
     46   content_iterator(content_type symb)
     47     : Current(symb) {}
     48 
     49   const content_type* operator->() const {
     50     return &Current;
     51   }
     52 
     53   const content_type &operator*() const {
     54     return Current;
     55   }
     56 
     57   bool operator==(const content_iterator &other) const {
     58     return Current == other.Current;
     59   }
     60 
     61   bool operator!=(const content_iterator &other) const {
     62     return !(*this == other);
     63   }
     64 
     65   content_iterator& increment(error_code &err) {
     66     content_type next;
     67     if (error_code ec = Current.getNext(next))
     68       err = ec;
     69     else
     70       Current = next;
     71     return *this;
     72   }
     73 };
     74 
     75 static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
     76   // Check bitwise identical. This is the only legal way to compare a union w/o
     77   // knowing which member is in use.
     78   return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
     79 }
     80 
     81 /// SymbolRef - This is a value type class that represents a single symbol in
     82 /// the list of symbols in the object file.
     83 class SymbolRef {
     84   friend class SectionRef;
     85   DataRefImpl SymbolPimpl;
     86   const ObjectFile *OwningObject;
     87 
     88 public:
     89   SymbolRef() : OwningObject(NULL) {
     90     std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl));
     91   }
     92 
     93   enum SymbolType {
     94     ST_Function,
     95     ST_Data,
     96     ST_External,    // Defined in another object file
     97     ST_Other
     98   };
     99 
    100   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
    101 
    102   bool operator==(const SymbolRef &Other) const;
    103 
    104   error_code getNext(SymbolRef &Result) const;
    105 
    106   error_code getName(StringRef &Result) const;
    107   error_code getAddress(uint64_t &Result) const;
    108   error_code getOffset(uint64_t &Result) const;
    109   error_code getSize(uint64_t &Result) const;
    110   error_code getSymbolType(SymbolRef::SymbolType &Result) const;
    111 
    112   /// Returns the ascii char that should be displayed in a symbol table dump via
    113   /// nm for this symbol.
    114   error_code getNMTypeChar(char &Result) const;
    115 
    116   /// Returns true for symbols that are internal to the object file format such
    117   /// as section symbols.
    118   error_code isInternal(bool &Result) const;
    119 
    120   /// Returns true for symbols that can be used in another objects,
    121   /// such as library functions
    122   error_code isGlobal(bool &Result) const;
    123 
    124   DataRefImpl getRawDataRefImpl() const;
    125 };
    126 typedef content_iterator<SymbolRef> symbol_iterator;
    127 
    128 /// RelocationRef - This is a value type class that represents a single
    129 /// relocation in the list of relocations in the object file.
    130 class RelocationRef {
    131   DataRefImpl RelocationPimpl;
    132   const ObjectFile *OwningObject;
    133 
    134 public:
    135   RelocationRef() : OwningObject(NULL) {
    136     std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl));
    137   }
    138 
    139   RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
    140 
    141   bool operator==(const RelocationRef &Other) const;
    142 
    143   error_code getNext(RelocationRef &Result) const;
    144 
    145   error_code getAddress(uint64_t &Result) const;
    146   error_code getSymbol(SymbolRef &Result) const;
    147   error_code getType(uint32_t &Result) const;
    148 
    149   /// @brief Get a string that represents the type of this relocation.
    150   ///
    151   /// This is for display purposes only.
    152   error_code getTypeName(SmallVectorImpl<char> &Result) const;
    153   error_code getAdditionalInfo(int64_t &Result) const;
    154 
    155   /// @brief Get a string that represents the calculation of the value of this
    156   ///        relocation.
    157   ///
    158   /// This is for display purposes only.
    159   error_code getValueString(SmallVectorImpl<char> &Result) const;
    160 };
    161 typedef content_iterator<RelocationRef> relocation_iterator;
    162 
    163 /// SectionRef - This is a value type class that represents a single section in
    164 /// the list of sections in the object file.
    165 class SectionRef {
    166   friend class SymbolRef;
    167   DataRefImpl SectionPimpl;
    168   const ObjectFile *OwningObject;
    169 
    170 public:
    171   SectionRef() : OwningObject(NULL) {
    172     std::memset(&SectionPimpl, 0, sizeof(SectionPimpl));
    173   }
    174 
    175   SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
    176 
    177   bool operator==(const SectionRef &Other) const;
    178 
    179   error_code getNext(SectionRef &Result) const;
    180 
    181   error_code getName(StringRef &Result) const;
    182   error_code getAddress(uint64_t &Result) const;
    183   error_code getSize(uint64_t &Result) const;
    184   error_code getContents(StringRef &Result) const;
    185 
    186   /// @brief Get the alignment of this section as the actual value (not log 2).
    187   error_code getAlignment(uint64_t &Result) const;
    188 
    189   // FIXME: Move to the normalization layer when it's created.
    190   error_code isText(bool &Result) const;
    191   error_code isData(bool &Result) const;
    192   error_code isBSS(bool &Result) const;
    193 
    194   error_code containsSymbol(SymbolRef S, bool &Result) const;
    195 
    196   relocation_iterator begin_relocations() const;
    197   relocation_iterator end_relocations() const;
    198 };
    199 typedef content_iterator<SectionRef> section_iterator;
    200 
    201 const uint64_t UnknownAddressOrSize = ~0ULL;
    202 
    203 /// ObjectFile - This class is the base class for all object file types.
    204 /// Concrete instances of this object are created by createObjectFile, which
    205 /// figure out which type to create.
    206 class ObjectFile : public Binary {
    207 private:
    208   ObjectFile(); // = delete
    209   ObjectFile(const ObjectFile &other); // = delete
    210 
    211 protected:
    212   ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
    213 
    214   const uint8_t *base() const {
    215     return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
    216   }
    217 
    218   // These functions are for SymbolRef to call internally. The main goal of
    219   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
    220   // entry in the memory mapped object file. SymbolPimpl cannot contain any
    221   // virtual functions because then it could not point into the memory mapped
    222   // file.
    223   //
    224   // Implementations assume that the DataRefImpl is valid and has not been
    225   // modified externally. It's UB otherwise.
    226   friend class SymbolRef;
    227   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
    228   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
    229   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
    230   virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const =0;
    231   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
    232   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
    233   virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0;
    234   virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const = 0;
    235   virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const = 0;
    236 
    237   // Same as above for SectionRef.
    238   friend class SectionRef;
    239   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
    240   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
    241   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
    242   virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
    243   virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
    244   virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
    245   virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
    246   virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
    247   virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
    248   virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
    249                                            bool &Result) const = 0;
    250   virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0;
    251   virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0;
    252 
    253 
    254   // Same as above for RelocationRef.
    255   friend class RelocationRef;
    256   virtual error_code getRelocationNext(DataRefImpl Rel,
    257                                        RelocationRef &Res) const = 0;
    258   virtual error_code getRelocationAddress(DataRefImpl Rel,
    259                                           uint64_t &Res) const =0;
    260   virtual error_code getRelocationSymbol(DataRefImpl Rel,
    261                                          SymbolRef &Res) const = 0;
    262   virtual error_code getRelocationType(DataRefImpl Rel,
    263                                        uint32_t &Res) const = 0;
    264   virtual error_code getRelocationTypeName(DataRefImpl Rel,
    265                                        SmallVectorImpl<char> &Result) const = 0;
    266   virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
    267                                                  int64_t &Res) const = 0;
    268   virtual error_code getRelocationValueString(DataRefImpl Rel,
    269                                        SmallVectorImpl<char> &Result) const = 0;
    270 
    271 public:
    272 
    273   virtual symbol_iterator begin_symbols() const = 0;
    274   virtual symbol_iterator end_symbols() const = 0;
    275 
    276   virtual section_iterator begin_sections() const = 0;
    277   virtual section_iterator end_sections() const = 0;
    278 
    279   /// @brief The number of bytes used to represent an address in this object
    280   ///        file format.
    281   virtual uint8_t getBytesInAddress() const = 0;
    282 
    283   virtual StringRef getFileFormatName() const = 0;
    284   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
    285 
    286   /// @returns Pointer to ObjectFile subclass to handle this type of object.
    287   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
    288   ///        return true.
    289   /// @brief Create ObjectFile from path.
    290   static ObjectFile *createObjectFile(StringRef ObjectPath);
    291   static ObjectFile *createObjectFile(MemoryBuffer *Object);
    292 
    293   static inline bool classof(const Binary *v) {
    294     return v->getType() >= isObject &&
    295            v->getType() < lastObject;
    296   }
    297   static inline bool classof(const ObjectFile *v) { return true; }
    298 
    299 public:
    300   static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
    301   static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
    302   static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
    303 };
    304 
    305 // Inline function definitions.
    306 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
    307   : SymbolPimpl(SymbolP)
    308   , OwningObject(Owner) {}
    309 
    310 inline bool SymbolRef::operator==(const SymbolRef &Other) const {
    311   return SymbolPimpl == Other.SymbolPimpl;
    312 }
    313 
    314 inline error_code SymbolRef::getNext(SymbolRef &Result) const {
    315   return OwningObject->getSymbolNext(SymbolPimpl, Result);
    316 }
    317 
    318 inline error_code SymbolRef::getName(StringRef &Result) const {
    319   return OwningObject->getSymbolName(SymbolPimpl, Result);
    320 }
    321 
    322 inline error_code SymbolRef::getAddress(uint64_t &Result) const {
    323   return OwningObject->getSymbolAddress(SymbolPimpl, Result);
    324 }
    325 
    326 inline error_code SymbolRef::getOffset(uint64_t &Result) const {
    327   return OwningObject->getSymbolOffset(SymbolPimpl, Result);
    328 }
    329 
    330 inline error_code SymbolRef::getSize(uint64_t &Result) const {
    331   return OwningObject->getSymbolSize(SymbolPimpl, Result);
    332 }
    333 
    334 inline error_code SymbolRef::getNMTypeChar(char &Result) const {
    335   return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
    336 }
    337 
    338 inline error_code SymbolRef::isInternal(bool &Result) const {
    339   return OwningObject->isSymbolInternal(SymbolPimpl, Result);
    340 }
    341 
    342 inline error_code SymbolRef::isGlobal(bool &Result) const {
    343   return OwningObject->isSymbolGlobal(SymbolPimpl, Result);
    344 }
    345 
    346 inline error_code SymbolRef::getSymbolType(SymbolRef::SymbolType &Result) const {
    347   return OwningObject->getSymbolType(SymbolPimpl, Result);
    348 }
    349 
    350 inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
    351   return SymbolPimpl;
    352 }
    353 
    354 
    355 /// SectionRef
    356 inline SectionRef::SectionRef(DataRefImpl SectionP,
    357                               const ObjectFile *Owner)
    358   : SectionPimpl(SectionP)
    359   , OwningObject(Owner) {}
    360 
    361 inline bool SectionRef::operator==(const SectionRef &Other) const {
    362   return SectionPimpl == Other.SectionPimpl;
    363 }
    364 
    365 inline error_code SectionRef::getNext(SectionRef &Result) const {
    366   return OwningObject->getSectionNext(SectionPimpl, Result);
    367 }
    368 
    369 inline error_code SectionRef::getName(StringRef &Result) const {
    370   return OwningObject->getSectionName(SectionPimpl, Result);
    371 }
    372 
    373 inline error_code SectionRef::getAddress(uint64_t &Result) const {
    374   return OwningObject->getSectionAddress(SectionPimpl, Result);
    375 }
    376 
    377 inline error_code SectionRef::getSize(uint64_t &Result) const {
    378   return OwningObject->getSectionSize(SectionPimpl, Result);
    379 }
    380 
    381 inline error_code SectionRef::getContents(StringRef &Result) const {
    382   return OwningObject->getSectionContents(SectionPimpl, Result);
    383 }
    384 
    385 inline error_code SectionRef::getAlignment(uint64_t &Result) const {
    386   return OwningObject->getSectionAlignment(SectionPimpl, Result);
    387 }
    388 
    389 inline error_code SectionRef::isText(bool &Result) const {
    390   return OwningObject->isSectionText(SectionPimpl, Result);
    391 }
    392 
    393 inline error_code SectionRef::isData(bool &Result) const {
    394   return OwningObject->isSectionData(SectionPimpl, Result);
    395 }
    396 
    397 inline error_code SectionRef::isBSS(bool &Result) const {
    398   return OwningObject->isSectionBSS(SectionPimpl, Result);
    399 }
    400 
    401 inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
    402   return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
    403                                              Result);
    404 }
    405 
    406 inline relocation_iterator SectionRef::begin_relocations() const {
    407   return OwningObject->getSectionRelBegin(SectionPimpl);
    408 }
    409 
    410 inline relocation_iterator SectionRef::end_relocations() const {
    411   return OwningObject->getSectionRelEnd(SectionPimpl);
    412 }
    413 
    414 
    415 /// RelocationRef
    416 inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
    417                               const ObjectFile *Owner)
    418   : RelocationPimpl(RelocationP)
    419   , OwningObject(Owner) {}
    420 
    421 inline bool RelocationRef::operator==(const RelocationRef &Other) const {
    422   return RelocationPimpl == Other.RelocationPimpl;
    423 }
    424 
    425 inline error_code RelocationRef::getNext(RelocationRef &Result) const {
    426   return OwningObject->getRelocationNext(RelocationPimpl, Result);
    427 }
    428 
    429 inline error_code RelocationRef::getAddress(uint64_t &Result) const {
    430   return OwningObject->getRelocationAddress(RelocationPimpl, Result);
    431 }
    432 
    433 inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
    434   return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
    435 }
    436 
    437 inline error_code RelocationRef::getType(uint32_t &Result) const {
    438   return OwningObject->getRelocationType(RelocationPimpl, Result);
    439 }
    440 
    441 inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
    442   const {
    443   return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
    444 }
    445 
    446 inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const {
    447   return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result);
    448 }
    449 
    450 inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
    451   const {
    452   return OwningObject->getRelocationValueString(RelocationPimpl, Result);
    453 }
    454 
    455 } // end namespace object
    456 } // end namespace llvm
    457 
    458 #endif
    459