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