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_OBJECTFILE_H
     15 #define LLVM_OBJECT_OBJECTFILE_H
     16 
     17 #include "llvm/ADT/StringRef.h"
     18 #include "llvm/Object/SymbolicFile.h"
     19 #include "llvm/Support/DataTypes.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 #include "llvm/Support/FileSystem.h"
     22 #include "llvm/Support/MemoryBuffer.h"
     23 #include <cstring>
     24 #include <vector>
     25 
     26 namespace llvm {
     27 namespace object {
     28 
     29 class ObjectFile;
     30 class COFFObjectFile;
     31 class MachOObjectFile;
     32 
     33 class SymbolRef;
     34 class symbol_iterator;
     35 class SectionRef;
     36 typedef content_iterator<SectionRef> section_iterator;
     37 
     38 /// This is a value type class that represents a single relocation in the list
     39 /// of relocations in the object file.
     40 class RelocationRef {
     41   DataRefImpl RelocationPimpl;
     42   const ObjectFile *OwningObject;
     43 
     44 public:
     45   RelocationRef() : OwningObject(nullptr) { }
     46 
     47   RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
     48 
     49   bool operator==(const RelocationRef &Other) const;
     50 
     51   void moveNext();
     52 
     53   uint64_t getOffset() const;
     54   symbol_iterator getSymbol() const;
     55   uint64_t getType() const;
     56 
     57   /// @brief Get a string that represents the type of this relocation.
     58   ///
     59   /// This is for display purposes only.
     60   void getTypeName(SmallVectorImpl<char> &Result) const;
     61 
     62   DataRefImpl getRawDataRefImpl() const;
     63   const ObjectFile *getObject() const;
     64 };
     65 typedef content_iterator<RelocationRef> relocation_iterator;
     66 
     67 /// This is a value type class that represents a single section in the list of
     68 /// sections in the object file.
     69 class SectionRef {
     70   friend class SymbolRef;
     71   DataRefImpl SectionPimpl;
     72   const ObjectFile *OwningObject;
     73 
     74 public:
     75   SectionRef() : OwningObject(nullptr) { }
     76 
     77   SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
     78 
     79   bool operator==(const SectionRef &Other) const;
     80   bool operator!=(const SectionRef &Other) const;
     81   bool operator<(const SectionRef &Other) const;
     82 
     83   void moveNext();
     84 
     85   std::error_code getName(StringRef &Result) const;
     86   uint64_t getAddress() const;
     87   uint64_t getSize() const;
     88   std::error_code getContents(StringRef &Result) const;
     89 
     90   /// @brief Get the alignment of this section as the actual value (not log 2).
     91   uint64_t getAlignment() const;
     92 
     93   bool isText() const;
     94   bool isData() const;
     95   bool isBSS() const;
     96   bool isVirtual() const;
     97 
     98   bool containsSymbol(SymbolRef S) const;
     99 
    100   relocation_iterator relocation_begin() const;
    101   relocation_iterator relocation_end() const;
    102   iterator_range<relocation_iterator> relocations() const {
    103     return make_range(relocation_begin(), relocation_end());
    104   }
    105   section_iterator getRelocatedSection() const;
    106 
    107   DataRefImpl getRawDataRefImpl() const;
    108   const ObjectFile *getObject() const;
    109 };
    110 
    111 /// This is a value type class that represents a single symbol in the list of
    112 /// symbols in the object file.
    113 class SymbolRef : public BasicSymbolRef {
    114   friend class SectionRef;
    115 
    116 public:
    117   SymbolRef() : BasicSymbolRef() {}
    118 
    119   enum Type {
    120     ST_Unknown, // Type not specified
    121     ST_Data,
    122     ST_Debug,
    123     ST_File,
    124     ST_Function,
    125     ST_Other
    126   };
    127 
    128   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
    129   SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
    130     assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
    131   }
    132 
    133   ErrorOr<StringRef> getName() const;
    134   /// Returns the symbol virtual address (i.e. address at which it will be
    135   /// mapped).
    136   ErrorOr<uint64_t> getAddress() const;
    137 
    138   /// Return the value of the symbol depending on the object this can be an
    139   /// offset or a virtual address.
    140   uint64_t getValue() const;
    141 
    142   /// @brief Get the alignment of this symbol as the actual value (not log 2).
    143   uint32_t getAlignment() const;
    144   uint64_t getCommonSize() const;
    145   SymbolRef::Type getType() const;
    146 
    147   /// @brief Get section this symbol is defined in reference to. Result is
    148   /// end_sections() if it is undefined or is an absolute symbol.
    149   ErrorOr<section_iterator> getSection() const;
    150 
    151   const ObjectFile *getObject() const;
    152 };
    153 
    154 class symbol_iterator : public basic_symbol_iterator {
    155 public:
    156   symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
    157   symbol_iterator(const basic_symbol_iterator &B)
    158       : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
    159                                         cast<ObjectFile>(B->getObject()))) {}
    160 
    161   const SymbolRef *operator->() const {
    162     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
    163     return static_cast<const SymbolRef*>(&P);
    164   }
    165 
    166   const SymbolRef &operator*() const {
    167     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
    168     return static_cast<const SymbolRef&>(P);
    169   }
    170 };
    171 
    172 /// This class is the base class for all object file types. Concrete instances
    173 /// of this object are created by createObjectFile, which figures out which type
    174 /// to create.
    175 class ObjectFile : public SymbolicFile {
    176   virtual void anchor();
    177   ObjectFile() = delete;
    178   ObjectFile(const ObjectFile &other) = delete;
    179 
    180 protected:
    181   ObjectFile(unsigned int Type, MemoryBufferRef Source);
    182 
    183   const uint8_t *base() const {
    184     return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
    185   }
    186 
    187   // These functions are for SymbolRef to call internally. The main goal of
    188   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
    189   // entry in the memory mapped object file. SymbolPimpl cannot contain any
    190   // virtual functions because then it could not point into the memory mapped
    191   // file.
    192   //
    193   // Implementations assume that the DataRefImpl is valid and has not been
    194   // modified externally. It's UB otherwise.
    195   friend class SymbolRef;
    196   virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
    197   std::error_code printSymbolName(raw_ostream &OS,
    198                                   DataRefImpl Symb) const override;
    199   virtual ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
    200   virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
    201   virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
    202   virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
    203   virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0;
    204   virtual ErrorOr<section_iterator>
    205   getSymbolSection(DataRefImpl Symb) const = 0;
    206 
    207   // Same as above for SectionRef.
    208   friend class SectionRef;
    209   virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
    210   virtual std::error_code getSectionName(DataRefImpl Sec,
    211                                          StringRef &Res) const = 0;
    212   virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
    213   virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
    214   virtual std::error_code getSectionContents(DataRefImpl Sec,
    215                                              StringRef &Res) const = 0;
    216   virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
    217   virtual bool isSectionText(DataRefImpl Sec) const = 0;
    218   virtual bool isSectionData(DataRefImpl Sec) const = 0;
    219   virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
    220   // A section is 'virtual' if its contents aren't present in the object image.
    221   virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
    222   virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
    223   virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
    224   virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
    225 
    226   // Same as above for RelocationRef.
    227   friend class RelocationRef;
    228   virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
    229   virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
    230   virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
    231   virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
    232   virtual void getRelocationTypeName(DataRefImpl Rel,
    233                                      SmallVectorImpl<char> &Result) const = 0;
    234 
    235   uint64_t getSymbolValue(DataRefImpl Symb) const;
    236 
    237 public:
    238   uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
    239     assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
    240     return getCommonSymbolSizeImpl(Symb);
    241   }
    242 
    243   typedef iterator_range<symbol_iterator> symbol_iterator_range;
    244   symbol_iterator_range symbols() const {
    245     return symbol_iterator_range(symbol_begin(), symbol_end());
    246   }
    247 
    248   virtual section_iterator section_begin() const = 0;
    249   virtual section_iterator section_end() const = 0;
    250 
    251   typedef iterator_range<section_iterator> section_iterator_range;
    252   section_iterator_range sections() const {
    253     return section_iterator_range(section_begin(), section_end());
    254   }
    255 
    256   /// @brief The number of bytes used to represent an address in this object
    257   ///        file format.
    258   virtual uint8_t getBytesInAddress() const = 0;
    259 
    260   virtual StringRef getFileFormatName() const = 0;
    261   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
    262 
    263   /// Returns platform-specific object flags, if any.
    264   virtual std::error_code getPlatformFlags(unsigned &Result) const {
    265     Result = 0;
    266     return object_error::invalid_file_type;
    267   }
    268 
    269   /// True if this is a relocatable object (.o/.obj).
    270   virtual bool isRelocatableObject() const = 0;
    271 
    272   /// @returns Pointer to ObjectFile subclass to handle this type of object.
    273   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
    274   ///        return true.
    275   /// @brief Create ObjectFile from path.
    276   static ErrorOr<OwningBinary<ObjectFile>>
    277   createObjectFile(StringRef ObjectPath);
    278 
    279   static ErrorOr<std::unique_ptr<ObjectFile>>
    280   createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type);
    281   static ErrorOr<std::unique_ptr<ObjectFile>>
    282   createObjectFile(MemoryBufferRef Object) {
    283     return createObjectFile(Object, sys::fs::file_magic::unknown);
    284   }
    285 
    286 
    287   static inline bool classof(const Binary *v) {
    288     return v->isObject();
    289   }
    290 
    291   static ErrorOr<std::unique_ptr<COFFObjectFile>>
    292   createCOFFObjectFile(MemoryBufferRef Object);
    293 
    294   static ErrorOr<std::unique_ptr<ObjectFile>>
    295   createELFObjectFile(MemoryBufferRef Object);
    296 
    297   static ErrorOr<std::unique_ptr<MachOObjectFile>>
    298   createMachOObjectFile(MemoryBufferRef Object);
    299 };
    300 
    301 // Inline function definitions.
    302 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
    303     : BasicSymbolRef(SymbolP, Owner) {}
    304 
    305 inline ErrorOr<StringRef> SymbolRef::getName() const {
    306   return getObject()->getSymbolName(getRawDataRefImpl());
    307 }
    308 
    309 inline ErrorOr<uint64_t> SymbolRef::getAddress() const {
    310   return getObject()->getSymbolAddress(getRawDataRefImpl());
    311 }
    312 
    313 inline uint64_t SymbolRef::getValue() const {
    314   return getObject()->getSymbolValue(getRawDataRefImpl());
    315 }
    316 
    317 inline uint32_t SymbolRef::getAlignment() const {
    318   return getObject()->getSymbolAlignment(getRawDataRefImpl());
    319 }
    320 
    321 inline uint64_t SymbolRef::getCommonSize() const {
    322   return getObject()->getCommonSymbolSize(getRawDataRefImpl());
    323 }
    324 
    325 inline ErrorOr<section_iterator> SymbolRef::getSection() const {
    326   return getObject()->getSymbolSection(getRawDataRefImpl());
    327 }
    328 
    329 inline SymbolRef::Type SymbolRef::getType() const {
    330   return getObject()->getSymbolType(getRawDataRefImpl());
    331 }
    332 
    333 inline const ObjectFile *SymbolRef::getObject() const {
    334   const SymbolicFile *O = BasicSymbolRef::getObject();
    335   return cast<ObjectFile>(O);
    336 }
    337 
    338 
    339 /// SectionRef
    340 inline SectionRef::SectionRef(DataRefImpl SectionP,
    341                               const ObjectFile *Owner)
    342   : SectionPimpl(SectionP)
    343   , OwningObject(Owner) {}
    344 
    345 inline bool SectionRef::operator==(const SectionRef &Other) const {
    346   return SectionPimpl == Other.SectionPimpl;
    347 }
    348 
    349 inline bool SectionRef::operator!=(const SectionRef &Other) const {
    350   return SectionPimpl != Other.SectionPimpl;
    351 }
    352 
    353 inline bool SectionRef::operator<(const SectionRef &Other) const {
    354   return SectionPimpl < Other.SectionPimpl;
    355 }
    356 
    357 inline void SectionRef::moveNext() {
    358   return OwningObject->moveSectionNext(SectionPimpl);
    359 }
    360 
    361 inline std::error_code SectionRef::getName(StringRef &Result) const {
    362   return OwningObject->getSectionName(SectionPimpl, Result);
    363 }
    364 
    365 inline uint64_t SectionRef::getAddress() const {
    366   return OwningObject->getSectionAddress(SectionPimpl);
    367 }
    368 
    369 inline uint64_t SectionRef::getSize() const {
    370   return OwningObject->getSectionSize(SectionPimpl);
    371 }
    372 
    373 inline std::error_code SectionRef::getContents(StringRef &Result) const {
    374   return OwningObject->getSectionContents(SectionPimpl, Result);
    375 }
    376 
    377 inline uint64_t SectionRef::getAlignment() const {
    378   return OwningObject->getSectionAlignment(SectionPimpl);
    379 }
    380 
    381 inline bool SectionRef::isText() const {
    382   return OwningObject->isSectionText(SectionPimpl);
    383 }
    384 
    385 inline bool SectionRef::isData() const {
    386   return OwningObject->isSectionData(SectionPimpl);
    387 }
    388 
    389 inline bool SectionRef::isBSS() const {
    390   return OwningObject->isSectionBSS(SectionPimpl);
    391 }
    392 
    393 inline bool SectionRef::isVirtual() const {
    394   return OwningObject->isSectionVirtual(SectionPimpl);
    395 }
    396 
    397 inline relocation_iterator SectionRef::relocation_begin() const {
    398   return OwningObject->section_rel_begin(SectionPimpl);
    399 }
    400 
    401 inline relocation_iterator SectionRef::relocation_end() const {
    402   return OwningObject->section_rel_end(SectionPimpl);
    403 }
    404 
    405 inline section_iterator SectionRef::getRelocatedSection() const {
    406   return OwningObject->getRelocatedSection(SectionPimpl);
    407 }
    408 
    409 inline DataRefImpl SectionRef::getRawDataRefImpl() const {
    410   return SectionPimpl;
    411 }
    412 
    413 inline const ObjectFile *SectionRef::getObject() const {
    414   return OwningObject;
    415 }
    416 
    417 /// RelocationRef
    418 inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
    419                               const ObjectFile *Owner)
    420   : RelocationPimpl(RelocationP)
    421   , OwningObject(Owner) {}
    422 
    423 inline bool RelocationRef::operator==(const RelocationRef &Other) const {
    424   return RelocationPimpl == Other.RelocationPimpl;
    425 }
    426 
    427 inline void RelocationRef::moveNext() {
    428   return OwningObject->moveRelocationNext(RelocationPimpl);
    429 }
    430 
    431 inline uint64_t RelocationRef::getOffset() const {
    432   return OwningObject->getRelocationOffset(RelocationPimpl);
    433 }
    434 
    435 inline symbol_iterator RelocationRef::getSymbol() const {
    436   return OwningObject->getRelocationSymbol(RelocationPimpl);
    437 }
    438 
    439 inline uint64_t RelocationRef::getType() const {
    440   return OwningObject->getRelocationType(RelocationPimpl);
    441 }
    442 
    443 inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
    444   return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
    445 }
    446 
    447 inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
    448   return RelocationPimpl;
    449 }
    450 
    451 inline const ObjectFile *RelocationRef::getObject() const {
    452   return OwningObject;
    453 }
    454 
    455 
    456 } // end namespace object
    457 } // end namespace llvm
    458 
    459 #endif
    460