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