Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file declares a file format independent ObjectFile class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_OBJECT_OBJECTFILE_H
  14. #define LLVM_OBJECT_OBJECTFILE_H
  15.  
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/Hashing.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/ADT/Triple.h"
  20. #include "llvm/ADT/iterator_range.h"
  21. #include "llvm/BinaryFormat/Magic.h"
  22. #include "llvm/BinaryFormat/Swift.h"
  23. #include "llvm/Object/Binary.h"
  24. #include "llvm/Object/Error.h"
  25. #include "llvm/Object/SymbolicFile.h"
  26. #include "llvm/Support/Casting.h"
  27. #include "llvm/Support/Error.h"
  28. #include "llvm/Support/MemoryBufferRef.h"
  29. #include <cassert>
  30. #include <cstdint>
  31. #include <memory>
  32.  
  33. namespace llvm {
  34.  
  35. class SubtargetFeatures;
  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.   /// 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.   Expected<StringRef> getName() const;
  97.   uint64_t getAddress() const;
  98.   uint64_t getIndex() const;
  99.   uint64_t getSize() const;
  100.   Expected<StringRef> getContents() const;
  101.  
  102.   /// Get the alignment of this section.
  103.   Align getAlignment() const;
  104.  
  105.   bool isCompressed() const;
  106.   /// Whether this section contains instructions.
  107.   bool isText() const;
  108.   /// Whether this section contains data, not instructions.
  109.   bool isData() const;
  110.   /// Whether this section contains BSS uninitialized data.
  111.   bool isBSS() const;
  112.   bool isVirtual() const;
  113.   bool isBitcode() const;
  114.   bool isStripped() const;
  115.  
  116.   /// Whether this section will be placed in the text segment, according to the
  117.   /// Berkeley size format. This is true if the section is allocatable, and
  118.   /// contains either code or readonly data.
  119.   bool isBerkeleyText() const;
  120.   /// Whether this section will be placed in the data segment, according to the
  121.   /// Berkeley size format. This is true if the section is allocatable and
  122.   /// contains data (e.g. PROGBITS), but is not text.
  123.   bool isBerkeleyData() const;
  124.  
  125.   /// Whether this section is a debug section.
  126.   bool isDebugSection() const;
  127.  
  128.   bool containsSymbol(SymbolRef S) const;
  129.  
  130.   relocation_iterator relocation_begin() const;
  131.   relocation_iterator relocation_end() const;
  132.   iterator_range<relocation_iterator> relocations() const {
  133.     return make_range(relocation_begin(), relocation_end());
  134.   }
  135.  
  136.   /// Returns the related section if this section contains relocations. The
  137.   /// returned section may or may not have applied its relocations.
  138.   Expected<section_iterator> getRelocatedSection() const;
  139.  
  140.   DataRefImpl getRawDataRefImpl() const;
  141.   const ObjectFile *getObject() const;
  142. };
  143.  
  144. struct SectionedAddress {
  145.   const static uint64_t UndefSection = UINT64_MAX;
  146.  
  147.   uint64_t Address = 0;
  148.   uint64_t SectionIndex = UndefSection;
  149. };
  150.  
  151. inline bool operator<(const SectionedAddress &LHS,
  152.                       const SectionedAddress &RHS) {
  153.   return std::tie(LHS.SectionIndex, LHS.Address) <
  154.          std::tie(RHS.SectionIndex, RHS.Address);
  155. }
  156.  
  157. inline bool operator==(const SectionedAddress &LHS,
  158.                        const SectionedAddress &RHS) {
  159.   return std::tie(LHS.SectionIndex, LHS.Address) ==
  160.          std::tie(RHS.SectionIndex, RHS.Address);
  161. }
  162.  
  163. raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
  164.  
  165. /// This is a value type class that represents a single symbol in the list of
  166. /// symbols in the object file.
  167. class SymbolRef : public BasicSymbolRef {
  168.   friend class SectionRef;
  169.  
  170. public:
  171.   enum Type {
  172.     ST_Unknown, // Type not specified
  173.     ST_Other,
  174.     ST_Data,
  175.     ST_Debug,
  176.     ST_File,
  177.     ST_Function,
  178.   };
  179.  
  180.   SymbolRef() = default;
  181.   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
  182.   SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
  183.     assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
  184.   }
  185.  
  186.   Expected<StringRef> getName() const;
  187.   /// Returns the symbol virtual address (i.e. address at which it will be
  188.   /// mapped).
  189.   Expected<uint64_t> getAddress() const;
  190.  
  191.   /// Return the value of the symbol depending on the object this can be an
  192.   /// offset or a virtual address.
  193.   Expected<uint64_t> getValue() const;
  194.  
  195.   /// Get the alignment of this symbol as the actual value (not log 2).
  196.   uint32_t getAlignment() const;
  197.   uint64_t getCommonSize() const;
  198.   Expected<SymbolRef::Type> getType() const;
  199.  
  200.   /// Get section this symbol is defined in reference to. Result is
  201.   /// end_sections() if it is undefined or is an absolute symbol.
  202.   Expected<section_iterator> getSection() const;
  203.  
  204.   const ObjectFile *getObject() const;
  205. };
  206.  
  207. class symbol_iterator : public basic_symbol_iterator {
  208. public:
  209.   symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
  210.   symbol_iterator(const basic_symbol_iterator &B)
  211.       : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
  212.                                         cast<ObjectFile>(B->getObject()))) {}
  213.  
  214.   const SymbolRef *operator->() const {
  215.     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
  216.     return static_cast<const SymbolRef*>(&P);
  217.   }
  218.  
  219.   const SymbolRef &operator*() const {
  220.     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
  221.     return static_cast<const SymbolRef&>(P);
  222.   }
  223. };
  224.  
  225. /// This class is the base class for all object file types. Concrete instances
  226. /// of this object are created by createObjectFile, which figures out which type
  227. /// to create.
  228. class ObjectFile : public SymbolicFile {
  229.   virtual void anchor();
  230.  
  231. protected:
  232.   ObjectFile(unsigned int Type, MemoryBufferRef Source);
  233.  
  234.   const uint8_t *base() const {
  235.     return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
  236.   }
  237.  
  238.   // These functions are for SymbolRef to call internally. The main goal of
  239.   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
  240.   // entry in the memory mapped object file. SymbolPimpl cannot contain any
  241.   // virtual functions because then it could not point into the memory mapped
  242.   // file.
  243.   //
  244.   // Implementations assume that the DataRefImpl is valid and has not been
  245.   // modified externally. It's UB otherwise.
  246.   friend class SymbolRef;
  247.  
  248.   virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
  249.   Error printSymbolName(raw_ostream &OS,
  250.                                   DataRefImpl Symb) const override;
  251.   virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
  252.   virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
  253.   virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
  254.   virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
  255.   virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
  256.   virtual Expected<section_iterator>
  257.   getSymbolSection(DataRefImpl Symb) const = 0;
  258.  
  259.   // Same as above for SectionRef.
  260.   friend class SectionRef;
  261.  
  262.   virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
  263.   virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
  264.   virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
  265.   virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
  266.   virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
  267.   virtual Expected<ArrayRef<uint8_t>>
  268.   getSectionContents(DataRefImpl Sec) const = 0;
  269.   virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
  270.   virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
  271.   virtual bool isSectionText(DataRefImpl Sec) const = 0;
  272.   virtual bool isSectionData(DataRefImpl Sec) const = 0;
  273.   virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
  274.   // A section is 'virtual' if its contents aren't present in the object image.
  275.   virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
  276.   virtual bool isSectionBitcode(DataRefImpl Sec) const;
  277.   virtual bool isSectionStripped(DataRefImpl Sec) const;
  278.   virtual bool isBerkeleyText(DataRefImpl Sec) const;
  279.   virtual bool isBerkeleyData(DataRefImpl Sec) const;
  280.   virtual bool isDebugSection(DataRefImpl Sec) const;
  281.   virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
  282.   virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
  283.   virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
  284.  
  285.   // Same as above for RelocationRef.
  286.   friend class RelocationRef;
  287.   virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
  288.   virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
  289.   virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
  290.   virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
  291.   virtual void getRelocationTypeName(DataRefImpl Rel,
  292.                                      SmallVectorImpl<char> &Result) const = 0;
  293.  
  294.   virtual llvm::binaryformat::Swift5ReflectionSectionKind
  295.   mapReflectionSectionNameToEnumValue(StringRef SectionName) const {
  296.     return llvm::binaryformat::Swift5ReflectionSectionKind::unknown;
  297.   };
  298.  
  299.   Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
  300.  
  301. public:
  302.   ObjectFile() = delete;
  303.   ObjectFile(const ObjectFile &other) = delete;
  304.  
  305.   uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
  306.     Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
  307.     if (!SymbolFlagsOrErr)
  308.       // TODO: Actually report errors helpfully.
  309.       report_fatal_error(SymbolFlagsOrErr.takeError());
  310.     assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
  311.     return getCommonSymbolSizeImpl(Symb);
  312.   }
  313.  
  314.   virtual std::vector<SectionRef> dynamic_relocation_sections() const {
  315.     return std::vector<SectionRef>();
  316.   }
  317.  
  318.   using symbol_iterator_range = iterator_range<symbol_iterator>;
  319.   symbol_iterator_range symbols() const {
  320.     return symbol_iterator_range(symbol_begin(), symbol_end());
  321.   }
  322.  
  323.   virtual section_iterator section_begin() const = 0;
  324.   virtual section_iterator section_end() const = 0;
  325.  
  326.   using section_iterator_range = iterator_range<section_iterator>;
  327.   section_iterator_range sections() const {
  328.     return section_iterator_range(section_begin(), section_end());
  329.   }
  330.  
  331.   virtual bool hasDebugInfo() const;
  332.  
  333.   /// The number of bytes used to represent an address in this object
  334.   ///        file format.
  335.   virtual uint8_t getBytesInAddress() const = 0;
  336.  
  337.   virtual StringRef getFileFormatName() const = 0;
  338.   virtual Triple::ArchType getArch() const = 0;
  339.   virtual Expected<SubtargetFeatures> getFeatures() const = 0;
  340.   virtual std::optional<StringRef> tryGetCPUName() const {
  341.     return std::nullopt;
  342.   };
  343.   virtual void setARMSubArch(Triple &TheTriple) const { }
  344.   virtual Expected<uint64_t> getStartAddress() const {
  345.     return errorCodeToError(object_error::parse_failed);
  346.   };
  347.  
  348.   /// Create a triple from the data in this object file.
  349.   Triple makeTriple() const;
  350.  
  351.   /// Maps a debug section name to a standard DWARF section name.
  352.   virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
  353.  
  354.   /// True if this is a relocatable object (.o/.obj).
  355.   virtual bool isRelocatableObject() const = 0;
  356.  
  357.   /// True if the reflection section can be stripped by the linker.
  358.   bool isReflectionSectionStrippable(
  359.       llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
  360.       const;
  361.  
  362.   /// @returns Pointer to ObjectFile subclass to handle this type of object.
  363.   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
  364.   ///        return true.
  365.   /// Create ObjectFile from path.
  366.   static Expected<OwningBinary<ObjectFile>>
  367.   createObjectFile(StringRef ObjectPath);
  368.  
  369.   static Expected<std::unique_ptr<ObjectFile>>
  370.   createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
  371.                    bool InitContent = true);
  372.   static Expected<std::unique_ptr<ObjectFile>>
  373.   createObjectFile(MemoryBufferRef Object) {
  374.     return createObjectFile(Object, llvm::file_magic::unknown);
  375.   }
  376.  
  377.   static bool classof(const Binary *v) {
  378.     return v->isObject();
  379.   }
  380.  
  381.   static Expected<std::unique_ptr<COFFObjectFile>>
  382.   createCOFFObjectFile(MemoryBufferRef Object);
  383.  
  384.   static Expected<std::unique_ptr<ObjectFile>>
  385.   createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
  386.  
  387.   static Expected<std::unique_ptr<ObjectFile>>
  388.   createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
  389.  
  390.   static Expected<std::unique_ptr<MachOObjectFile>>
  391.   createMachOObjectFile(MemoryBufferRef Object,
  392.                         uint32_t UniversalCputype = 0,
  393.                         uint32_t UniversalIndex = 0);
  394.  
  395.   static Expected<std::unique_ptr<WasmObjectFile>>
  396.   createWasmObjectFile(MemoryBufferRef Object);
  397. };
  398.  
  399. // Inline function definitions.
  400. inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
  401.     : BasicSymbolRef(SymbolP, Owner) {}
  402.  
  403. inline Expected<StringRef> SymbolRef::getName() const {
  404.   return getObject()->getSymbolName(getRawDataRefImpl());
  405. }
  406.  
  407. inline Expected<uint64_t> SymbolRef::getAddress() const {
  408.   return getObject()->getSymbolAddress(getRawDataRefImpl());
  409. }
  410.  
  411. inline Expected<uint64_t> SymbolRef::getValue() const {
  412.   return getObject()->getSymbolValue(getRawDataRefImpl());
  413. }
  414.  
  415. inline uint32_t SymbolRef::getAlignment() const {
  416.   return getObject()->getSymbolAlignment(getRawDataRefImpl());
  417. }
  418.  
  419. inline uint64_t SymbolRef::getCommonSize() const {
  420.   return getObject()->getCommonSymbolSize(getRawDataRefImpl());
  421. }
  422.  
  423. inline Expected<section_iterator> SymbolRef::getSection() const {
  424.   return getObject()->getSymbolSection(getRawDataRefImpl());
  425. }
  426.  
  427. inline Expected<SymbolRef::Type> SymbolRef::getType() const {
  428.   return getObject()->getSymbolType(getRawDataRefImpl());
  429. }
  430.  
  431. inline const ObjectFile *SymbolRef::getObject() const {
  432.   const SymbolicFile *O = BasicSymbolRef::getObject();
  433.   return cast<ObjectFile>(O);
  434. }
  435.  
  436. /// SectionRef
  437. inline SectionRef::SectionRef(DataRefImpl SectionP,
  438.                               const ObjectFile *Owner)
  439.   : SectionPimpl(SectionP)
  440.   , OwningObject(Owner) {}
  441.  
  442. inline bool SectionRef::operator==(const SectionRef &Other) const {
  443.   return OwningObject == Other.OwningObject &&
  444.          SectionPimpl == Other.SectionPimpl;
  445. }
  446.  
  447. inline bool SectionRef::operator!=(const SectionRef &Other) const {
  448.   return !(*this == Other);
  449. }
  450.  
  451. inline bool SectionRef::operator<(const SectionRef &Other) const {
  452.   assert(OwningObject == Other.OwningObject);
  453.   return SectionPimpl < Other.SectionPimpl;
  454. }
  455.  
  456. inline void SectionRef::moveNext() {
  457.   return OwningObject->moveSectionNext(SectionPimpl);
  458. }
  459.  
  460. inline Expected<StringRef> SectionRef::getName() const {
  461.   return OwningObject->getSectionName(SectionPimpl);
  462. }
  463.  
  464. inline uint64_t SectionRef::getAddress() const {
  465.   return OwningObject->getSectionAddress(SectionPimpl);
  466. }
  467.  
  468. inline uint64_t SectionRef::getIndex() const {
  469.   return OwningObject->getSectionIndex(SectionPimpl);
  470. }
  471.  
  472. inline uint64_t SectionRef::getSize() const {
  473.   return OwningObject->getSectionSize(SectionPimpl);
  474. }
  475.  
  476. inline Expected<StringRef> SectionRef::getContents() const {
  477.   Expected<ArrayRef<uint8_t>> Res =
  478.       OwningObject->getSectionContents(SectionPimpl);
  479.   if (!Res)
  480.     return Res.takeError();
  481.   return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
  482. }
  483.  
  484. inline Align SectionRef::getAlignment() const {
  485.   return MaybeAlign(OwningObject->getSectionAlignment(SectionPimpl))
  486.       .valueOrOne();
  487. }
  488.  
  489. inline bool SectionRef::isCompressed() const {
  490.   return OwningObject->isSectionCompressed(SectionPimpl);
  491. }
  492.  
  493. inline bool SectionRef::isText() const {
  494.   return OwningObject->isSectionText(SectionPimpl);
  495. }
  496.  
  497. inline bool SectionRef::isData() const {
  498.   return OwningObject->isSectionData(SectionPimpl);
  499. }
  500.  
  501. inline bool SectionRef::isBSS() const {
  502.   return OwningObject->isSectionBSS(SectionPimpl);
  503. }
  504.  
  505. inline bool SectionRef::isVirtual() const {
  506.   return OwningObject->isSectionVirtual(SectionPimpl);
  507. }
  508.  
  509. inline bool SectionRef::isBitcode() const {
  510.   return OwningObject->isSectionBitcode(SectionPimpl);
  511. }
  512.  
  513. inline bool SectionRef::isStripped() const {
  514.   return OwningObject->isSectionStripped(SectionPimpl);
  515. }
  516.  
  517. inline bool SectionRef::isBerkeleyText() const {
  518.   return OwningObject->isBerkeleyText(SectionPimpl);
  519. }
  520.  
  521. inline bool SectionRef::isBerkeleyData() const {
  522.   return OwningObject->isBerkeleyData(SectionPimpl);
  523. }
  524.  
  525. inline bool SectionRef::isDebugSection() const {
  526.   return OwningObject->isDebugSection(SectionPimpl);
  527. }
  528.  
  529. inline relocation_iterator SectionRef::relocation_begin() const {
  530.   return OwningObject->section_rel_begin(SectionPimpl);
  531. }
  532.  
  533. inline relocation_iterator SectionRef::relocation_end() const {
  534.   return OwningObject->section_rel_end(SectionPimpl);
  535. }
  536.  
  537. inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
  538.   return OwningObject->getRelocatedSection(SectionPimpl);
  539. }
  540.  
  541. inline DataRefImpl SectionRef::getRawDataRefImpl() const {
  542.   return SectionPimpl;
  543. }
  544.  
  545. inline const ObjectFile *SectionRef::getObject() const {
  546.   return OwningObject;
  547. }
  548.  
  549. /// RelocationRef
  550. inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
  551.                               const ObjectFile *Owner)
  552.   : RelocationPimpl(RelocationP)
  553.   , OwningObject(Owner) {}
  554.  
  555. inline bool RelocationRef::operator==(const RelocationRef &Other) const {
  556.   return RelocationPimpl == Other.RelocationPimpl;
  557. }
  558.  
  559. inline void RelocationRef::moveNext() {
  560.   return OwningObject->moveRelocationNext(RelocationPimpl);
  561. }
  562.  
  563. inline uint64_t RelocationRef::getOffset() const {
  564.   return OwningObject->getRelocationOffset(RelocationPimpl);
  565. }
  566.  
  567. inline symbol_iterator RelocationRef::getSymbol() const {
  568.   return OwningObject->getRelocationSymbol(RelocationPimpl);
  569. }
  570.  
  571. inline uint64_t RelocationRef::getType() const {
  572.   return OwningObject->getRelocationType(RelocationPimpl);
  573. }
  574.  
  575. inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
  576.   return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
  577. }
  578.  
  579. inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
  580.   return RelocationPimpl;
  581. }
  582.  
  583. inline const ObjectFile *RelocationRef::getObject() const {
  584.   return OwningObject;
  585. }
  586.  
  587. } // end namespace object
  588.  
  589. template <> struct DenseMapInfo<object::SectionRef> {
  590.   static bool isEqual(const object::SectionRef &A,
  591.                       const object::SectionRef &B) {
  592.     return A == B;
  593.   }
  594.   static object::SectionRef getEmptyKey() {
  595.     return object::SectionRef({}, nullptr);
  596.   }
  597.   static object::SectionRef getTombstoneKey() {
  598.     object::DataRefImpl TS;
  599.     TS.p = (uintptr_t)-1;
  600.     return object::SectionRef(TS, nullptr);
  601.   }
  602.   static unsigned getHashValue(const object::SectionRef &Sec) {
  603.     object::DataRefImpl Raw = Sec.getRawDataRefImpl();
  604.     return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
  605.   }
  606. };
  607.  
  608. } // end namespace llvm
  609.  
  610. #endif // LLVM_OBJECT_OBJECTFILE_H
  611.