Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:20

0001 //===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares a file format independent ObjectFile class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_OBJECT_OBJECTFILE_H
0014 #define LLVM_OBJECT_OBJECTFILE_H
0015 
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/Hashing.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include "llvm/BinaryFormat/Magic.h"
0021 #include "llvm/BinaryFormat/Swift.h"
0022 #include "llvm/Object/Binary.h"
0023 #include "llvm/Object/Error.h"
0024 #include "llvm/Object/SymbolicFile.h"
0025 #include "llvm/Support/Casting.h"
0026 #include "llvm/Support/Error.h"
0027 #include "llvm/Support/MemoryBufferRef.h"
0028 #include "llvm/TargetParser/Triple.h"
0029 #include <cassert>
0030 #include <cstdint>
0031 #include <memory>
0032 
0033 namespace llvm {
0034 
0035 class SubtargetFeatures;
0036 
0037 namespace object {
0038 
0039 class COFFObjectFile;
0040 class MachOObjectFile;
0041 class ObjectFile;
0042 class SectionRef;
0043 class SymbolRef;
0044 class symbol_iterator;
0045 class WasmObjectFile;
0046 
0047 using section_iterator = content_iterator<SectionRef>;
0048 
0049 typedef std::function<bool(const SectionRef &)> SectionFilterPredicate;
0050 /// This is a value type class that represents a single relocation in the list
0051 /// of relocations in the object file.
0052 class RelocationRef {
0053   DataRefImpl RelocationPimpl;
0054   const ObjectFile *OwningObject = nullptr;
0055 
0056 public:
0057   RelocationRef() = default;
0058   RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
0059 
0060   bool operator==(const RelocationRef &Other) const;
0061 
0062   void moveNext();
0063 
0064   uint64_t getOffset() const;
0065   symbol_iterator getSymbol() const;
0066   uint64_t getType() const;
0067 
0068   /// Get a string that represents the type of this relocation.
0069   ///
0070   /// This is for display purposes only.
0071   void getTypeName(SmallVectorImpl<char> &Result) const;
0072 
0073   DataRefImpl getRawDataRefImpl() const;
0074   const ObjectFile *getObject() const;
0075 };
0076 
0077 using relocation_iterator = content_iterator<RelocationRef>;
0078 
0079 /// This is a value type class that represents a single section in the list of
0080 /// sections in the object file.
0081 class SectionRef {
0082   friend class SymbolRef;
0083 
0084   DataRefImpl SectionPimpl;
0085   const ObjectFile *OwningObject = nullptr;
0086 
0087 public:
0088   SectionRef() = default;
0089   SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
0090 
0091   bool operator==(const SectionRef &Other) const;
0092   bool operator!=(const SectionRef &Other) const;
0093   bool operator<(const SectionRef &Other) const;
0094 
0095   void moveNext();
0096 
0097   Expected<StringRef> getName() const;
0098   uint64_t getAddress() const;
0099   uint64_t getIndex() const;
0100   uint64_t getSize() const;
0101   Expected<StringRef> getContents() const;
0102 
0103   /// Get the alignment of this section.
0104   Align getAlignment() const;
0105 
0106   bool isCompressed() const;
0107   /// Whether this section contains instructions.
0108   bool isText() const;
0109   /// Whether this section contains data, not instructions.
0110   bool isData() const;
0111   /// Whether this section contains BSS uninitialized data.
0112   bool isBSS() const;
0113   bool isVirtual() const;
0114   bool isBitcode() const;
0115   bool isStripped() const;
0116 
0117   /// Whether this section will be placed in the text segment, according to the
0118   /// Berkeley size format. This is true if the section is allocatable, and
0119   /// contains either code or readonly data.
0120   bool isBerkeleyText() const;
0121   /// Whether this section will be placed in the data segment, according to the
0122   /// Berkeley size format. This is true if the section is allocatable and
0123   /// contains data (e.g. PROGBITS), but is not text.
0124   bool isBerkeleyData() const;
0125 
0126   /// Whether this section is a debug section.
0127   bool isDebugSection() const;
0128 
0129   bool containsSymbol(SymbolRef S) const;
0130 
0131   relocation_iterator relocation_begin() const;
0132   relocation_iterator relocation_end() const;
0133   iterator_range<relocation_iterator> relocations() const {
0134     return make_range(relocation_begin(), relocation_end());
0135   }
0136 
0137   /// Returns the related section if this section contains relocations. The
0138   /// returned section may or may not have applied its relocations.
0139   Expected<section_iterator> getRelocatedSection() const;
0140 
0141   DataRefImpl getRawDataRefImpl() const;
0142   const ObjectFile *getObject() const;
0143 };
0144 
0145 struct SectionedAddress {
0146   const static uint64_t UndefSection = UINT64_MAX;
0147 
0148   uint64_t Address = 0;
0149   uint64_t SectionIndex = UndefSection;
0150 };
0151 
0152 inline bool operator<(const SectionedAddress &LHS,
0153                       const SectionedAddress &RHS) {
0154   return std::tie(LHS.SectionIndex, LHS.Address) <
0155          std::tie(RHS.SectionIndex, RHS.Address);
0156 }
0157 
0158 inline bool operator==(const SectionedAddress &LHS,
0159                        const SectionedAddress &RHS) {
0160   return std::tie(LHS.SectionIndex, LHS.Address) ==
0161          std::tie(RHS.SectionIndex, RHS.Address);
0162 }
0163 
0164 raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
0165 
0166 /// This is a value type class that represents a single symbol in the list of
0167 /// symbols in the object file.
0168 class SymbolRef : public BasicSymbolRef {
0169   friend class SectionRef;
0170 
0171 public:
0172   enum Type {
0173     ST_Unknown, // Type not specified
0174     ST_Other,
0175     ST_Data,
0176     ST_Debug,
0177     ST_File,
0178     ST_Function,
0179   };
0180 
0181   SymbolRef() = default;
0182   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
0183   SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
0184     assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
0185   }
0186 
0187   Expected<StringRef> getName() const;
0188   /// Returns the symbol virtual address (i.e. address at which it will be
0189   /// mapped).
0190   Expected<uint64_t> getAddress() const;
0191 
0192   /// Return the value of the symbol depending on the object this can be an
0193   /// offset or a virtual address.
0194   Expected<uint64_t> getValue() const;
0195 
0196   /// Get the alignment of this symbol as the actual value (not log 2).
0197   uint32_t getAlignment() const;
0198   uint64_t getCommonSize() const;
0199   Expected<SymbolRef::Type> getType() const;
0200 
0201   /// Get section this symbol is defined in reference to. Result is
0202   /// section_end() if it is undefined or is an absolute symbol.
0203   Expected<section_iterator> getSection() const;
0204 
0205   const ObjectFile *getObject() const;
0206 };
0207 
0208 class symbol_iterator : public basic_symbol_iterator {
0209 public:
0210   symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
0211   symbol_iterator(const basic_symbol_iterator &B)
0212       : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
0213                                         cast<ObjectFile>(B->getObject()))) {}
0214 
0215   const SymbolRef *operator->() const {
0216     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
0217     return static_cast<const SymbolRef*>(&P);
0218   }
0219 
0220   const SymbolRef &operator*() const {
0221     const BasicSymbolRef &P = basic_symbol_iterator::operator *();
0222     return static_cast<const SymbolRef&>(P);
0223   }
0224 };
0225 
0226 /// This class is the base class for all object file types. Concrete instances
0227 /// of this object are created by createObjectFile, which figures out which type
0228 /// to create.
0229 class ObjectFile : public SymbolicFile {
0230   virtual void anchor();
0231 
0232 protected:
0233   ObjectFile(unsigned int Type, MemoryBufferRef Source);
0234 
0235   const uint8_t *base() const {
0236     return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
0237   }
0238 
0239   // These functions are for SymbolRef to call internally. The main goal of
0240   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
0241   // entry in the memory mapped object file. SymbolPimpl cannot contain any
0242   // virtual functions because then it could not point into the memory mapped
0243   // file.
0244   //
0245   // Implementations assume that the DataRefImpl is valid and has not been
0246   // modified externally. It's UB otherwise.
0247   friend class SymbolRef;
0248 
0249   virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
0250   Error printSymbolName(raw_ostream &OS,
0251                                   DataRefImpl Symb) const override;
0252   virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
0253   virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
0254   virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
0255   virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
0256   virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
0257   virtual Expected<section_iterator>
0258   getSymbolSection(DataRefImpl Symb) const = 0;
0259 
0260   // Same as above for SectionRef.
0261   friend class SectionRef;
0262 
0263   virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
0264   virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
0265   virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
0266   virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
0267   virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
0268   virtual Expected<ArrayRef<uint8_t>>
0269   getSectionContents(DataRefImpl Sec) const = 0;
0270   virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
0271   virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
0272   virtual bool isSectionText(DataRefImpl Sec) const = 0;
0273   virtual bool isSectionData(DataRefImpl Sec) const = 0;
0274   virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
0275   // A section is 'virtual' if its contents aren't present in the object image.
0276   virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
0277   virtual bool isSectionBitcode(DataRefImpl Sec) const;
0278   virtual bool isSectionStripped(DataRefImpl Sec) const;
0279   virtual bool isBerkeleyText(DataRefImpl Sec) const;
0280   virtual bool isBerkeleyData(DataRefImpl Sec) const;
0281   virtual bool isDebugSection(DataRefImpl Sec) const;
0282   virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
0283   virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
0284   virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
0285 
0286   // Same as above for RelocationRef.
0287   friend class RelocationRef;
0288   virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
0289   virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
0290   virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
0291   virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
0292   virtual void getRelocationTypeName(DataRefImpl Rel,
0293                                      SmallVectorImpl<char> &Result) const = 0;
0294 
0295   virtual llvm::binaryformat::Swift5ReflectionSectionKind
0296   mapReflectionSectionNameToEnumValue(StringRef SectionName) const {
0297     return llvm::binaryformat::Swift5ReflectionSectionKind::unknown;
0298   };
0299 
0300   Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
0301 
0302 public:
0303   ObjectFile() = delete;
0304   ObjectFile(const ObjectFile &other) = delete;
0305   ObjectFile &operator=(const ObjectFile &other) = delete;
0306 
0307   uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
0308     Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
0309     if (!SymbolFlagsOrErr)
0310       // TODO: Actually report errors helpfully.
0311       report_fatal_error(SymbolFlagsOrErr.takeError());
0312     assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
0313     return getCommonSymbolSizeImpl(Symb);
0314   }
0315 
0316   virtual std::vector<SectionRef> dynamic_relocation_sections() const {
0317     return std::vector<SectionRef>();
0318   }
0319 
0320   using symbol_iterator_range = iterator_range<symbol_iterator>;
0321   symbol_iterator_range symbols() const {
0322     return symbol_iterator_range(symbol_begin(), symbol_end());
0323   }
0324 
0325   virtual section_iterator section_begin() const = 0;
0326   virtual section_iterator section_end() const = 0;
0327 
0328   using section_iterator_range = iterator_range<section_iterator>;
0329   section_iterator_range sections() const {
0330     return section_iterator_range(section_begin(), section_end());
0331   }
0332 
0333   virtual bool hasDebugInfo() const;
0334 
0335   /// The number of bytes used to represent an address in this object
0336   ///        file format.
0337   virtual uint8_t getBytesInAddress() const = 0;
0338 
0339   virtual StringRef getFileFormatName() const = 0;
0340   virtual Triple::ArchType getArch() const = 0;
0341   virtual Triple::OSType getOS() const { return Triple::UnknownOS; }
0342   virtual Expected<SubtargetFeatures> getFeatures() const = 0;
0343   virtual std::optional<StringRef> tryGetCPUName() const {
0344     return std::nullopt;
0345   };
0346   virtual void setARMSubArch(Triple &TheTriple) const { }
0347   virtual Expected<uint64_t> getStartAddress() const {
0348     return errorCodeToError(object_error::parse_failed);
0349   };
0350 
0351   /// Create a triple from the data in this object file.
0352   Triple makeTriple() const;
0353 
0354   /// Maps a debug section name to a standard DWARF section name.
0355   virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
0356 
0357   /// True if this is a relocatable object (.o/.obj).
0358   virtual bool isRelocatableObject() const = 0;
0359 
0360   /// True if the reflection section can be stripped by the linker.
0361   bool isReflectionSectionStrippable(
0362       llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
0363       const;
0364 
0365   /// @returns Pointer to ObjectFile subclass to handle this type of object.
0366   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
0367   ///        return true.
0368   /// Create ObjectFile from path.
0369   static Expected<OwningBinary<ObjectFile>>
0370   createObjectFile(StringRef ObjectPath);
0371 
0372   static Expected<std::unique_ptr<ObjectFile>>
0373   createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
0374                    bool InitContent = true);
0375   static Expected<std::unique_ptr<ObjectFile>>
0376   createObjectFile(MemoryBufferRef Object) {
0377     return createObjectFile(Object, llvm::file_magic::unknown);
0378   }
0379 
0380   static bool classof(const Binary *v) {
0381     return v->isObject();
0382   }
0383 
0384   static Expected<std::unique_ptr<COFFObjectFile>>
0385   createCOFFObjectFile(MemoryBufferRef Object);
0386 
0387   static Expected<std::unique_ptr<ObjectFile>>
0388   createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
0389 
0390   static Expected<std::unique_ptr<ObjectFile>>
0391   createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
0392 
0393   static Expected<std::unique_ptr<MachOObjectFile>>
0394   createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype = 0,
0395                         uint32_t UniversalIndex = 0,
0396                         size_t MachOFilesetEntryOffset = 0);
0397 
0398   static Expected<std::unique_ptr<ObjectFile>>
0399   createGOFFObjectFile(MemoryBufferRef Object);
0400 
0401   static Expected<std::unique_ptr<WasmObjectFile>>
0402   createWasmObjectFile(MemoryBufferRef Object);
0403 };
0404 
0405 /// A filtered iterator for SectionRefs that skips sections based on some given
0406 /// predicate.
0407 class SectionFilterIterator {
0408 public:
0409   SectionFilterIterator(SectionFilterPredicate Pred,
0410                         const section_iterator &Begin,
0411                         const section_iterator &End)
0412       : Predicate(std::move(Pred)), Iterator(Begin), End(End) {
0413     scanPredicate();
0414   }
0415   const SectionRef &operator*() const { return *Iterator; }
0416   SectionFilterIterator &operator++() {
0417     ++Iterator;
0418     scanPredicate();
0419     return *this;
0420   }
0421   bool operator!=(const SectionFilterIterator &Other) const {
0422     return Iterator != Other.Iterator;
0423   }
0424 
0425 private:
0426   void scanPredicate() {
0427     while (Iterator != End && !Predicate(*Iterator)) {
0428       ++Iterator;
0429     }
0430   }
0431   SectionFilterPredicate Predicate;
0432   section_iterator Iterator;
0433   section_iterator End;
0434 };
0435 
0436 /// Creates an iterator range of SectionFilterIterators for a given Object and
0437 /// predicate.
0438 class SectionFilter {
0439 public:
0440   SectionFilter(SectionFilterPredicate Pred, const ObjectFile &Obj)
0441       : Predicate(std::move(Pred)), Object(Obj) {}
0442   SectionFilterIterator begin() {
0443     return SectionFilterIterator(Predicate, Object.section_begin(),
0444                                  Object.section_end());
0445   }
0446   SectionFilterIterator end() {
0447     return SectionFilterIterator(Predicate, Object.section_end(),
0448                                  Object.section_end());
0449   }
0450 
0451 private:
0452   SectionFilterPredicate Predicate;
0453   const ObjectFile &Object;
0454 };
0455 
0456 // Inline function definitions.
0457 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
0458     : BasicSymbolRef(SymbolP, Owner) {}
0459 
0460 inline Expected<StringRef> SymbolRef::getName() const {
0461   return getObject()->getSymbolName(getRawDataRefImpl());
0462 }
0463 
0464 inline Expected<uint64_t> SymbolRef::getAddress() const {
0465   return getObject()->getSymbolAddress(getRawDataRefImpl());
0466 }
0467 
0468 inline Expected<uint64_t> SymbolRef::getValue() const {
0469   return getObject()->getSymbolValue(getRawDataRefImpl());
0470 }
0471 
0472 inline uint32_t SymbolRef::getAlignment() const {
0473   return getObject()->getSymbolAlignment(getRawDataRefImpl());
0474 }
0475 
0476 inline uint64_t SymbolRef::getCommonSize() const {
0477   return getObject()->getCommonSymbolSize(getRawDataRefImpl());
0478 }
0479 
0480 inline Expected<section_iterator> SymbolRef::getSection() const {
0481   return getObject()->getSymbolSection(getRawDataRefImpl());
0482 }
0483 
0484 inline Expected<SymbolRef::Type> SymbolRef::getType() const {
0485   return getObject()->getSymbolType(getRawDataRefImpl());
0486 }
0487 
0488 inline const ObjectFile *SymbolRef::getObject() const {
0489   const SymbolicFile *O = BasicSymbolRef::getObject();
0490   return cast<ObjectFile>(O);
0491 }
0492 
0493 /// SectionRef
0494 inline SectionRef::SectionRef(DataRefImpl SectionP,
0495                               const ObjectFile *Owner)
0496   : SectionPimpl(SectionP)
0497   , OwningObject(Owner) {}
0498 
0499 inline bool SectionRef::operator==(const SectionRef &Other) const {
0500   return OwningObject == Other.OwningObject &&
0501          SectionPimpl == Other.SectionPimpl;
0502 }
0503 
0504 inline bool SectionRef::operator!=(const SectionRef &Other) const {
0505   return !(*this == Other);
0506 }
0507 
0508 inline bool SectionRef::operator<(const SectionRef &Other) const {
0509   assert(OwningObject == Other.OwningObject);
0510   return SectionPimpl < Other.SectionPimpl;
0511 }
0512 
0513 inline void SectionRef::moveNext() {
0514   return OwningObject->moveSectionNext(SectionPimpl);
0515 }
0516 
0517 inline Expected<StringRef> SectionRef::getName() const {
0518   return OwningObject->getSectionName(SectionPimpl);
0519 }
0520 
0521 inline uint64_t SectionRef::getAddress() const {
0522   return OwningObject->getSectionAddress(SectionPimpl);
0523 }
0524 
0525 inline uint64_t SectionRef::getIndex() const {
0526   return OwningObject->getSectionIndex(SectionPimpl);
0527 }
0528 
0529 inline uint64_t SectionRef::getSize() const {
0530   return OwningObject->getSectionSize(SectionPimpl);
0531 }
0532 
0533 inline Expected<StringRef> SectionRef::getContents() const {
0534   Expected<ArrayRef<uint8_t>> Res =
0535       OwningObject->getSectionContents(SectionPimpl);
0536   if (!Res)
0537     return Res.takeError();
0538   return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
0539 }
0540 
0541 inline Align SectionRef::getAlignment() const {
0542   return MaybeAlign(OwningObject->getSectionAlignment(SectionPimpl))
0543       .valueOrOne();
0544 }
0545 
0546 inline bool SectionRef::isCompressed() const {
0547   return OwningObject->isSectionCompressed(SectionPimpl);
0548 }
0549 
0550 inline bool SectionRef::isText() const {
0551   return OwningObject->isSectionText(SectionPimpl);
0552 }
0553 
0554 inline bool SectionRef::isData() const {
0555   return OwningObject->isSectionData(SectionPimpl);
0556 }
0557 
0558 inline bool SectionRef::isBSS() const {
0559   return OwningObject->isSectionBSS(SectionPimpl);
0560 }
0561 
0562 inline bool SectionRef::isVirtual() const {
0563   return OwningObject->isSectionVirtual(SectionPimpl);
0564 }
0565 
0566 inline bool SectionRef::isBitcode() const {
0567   return OwningObject->isSectionBitcode(SectionPimpl);
0568 }
0569 
0570 inline bool SectionRef::isStripped() const {
0571   return OwningObject->isSectionStripped(SectionPimpl);
0572 }
0573 
0574 inline bool SectionRef::isBerkeleyText() const {
0575   return OwningObject->isBerkeleyText(SectionPimpl);
0576 }
0577 
0578 inline bool SectionRef::isBerkeleyData() const {
0579   return OwningObject->isBerkeleyData(SectionPimpl);
0580 }
0581 
0582 inline bool SectionRef::isDebugSection() const {
0583   return OwningObject->isDebugSection(SectionPimpl);
0584 }
0585 
0586 inline relocation_iterator SectionRef::relocation_begin() const {
0587   return OwningObject->section_rel_begin(SectionPimpl);
0588 }
0589 
0590 inline relocation_iterator SectionRef::relocation_end() const {
0591   return OwningObject->section_rel_end(SectionPimpl);
0592 }
0593 
0594 inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
0595   return OwningObject->getRelocatedSection(SectionPimpl);
0596 }
0597 
0598 inline DataRefImpl SectionRef::getRawDataRefImpl() const {
0599   return SectionPimpl;
0600 }
0601 
0602 inline const ObjectFile *SectionRef::getObject() const {
0603   return OwningObject;
0604 }
0605 
0606 /// RelocationRef
0607 inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
0608                               const ObjectFile *Owner)
0609   : RelocationPimpl(RelocationP)
0610   , OwningObject(Owner) {}
0611 
0612 inline bool RelocationRef::operator==(const RelocationRef &Other) const {
0613   return RelocationPimpl == Other.RelocationPimpl;
0614 }
0615 
0616 inline void RelocationRef::moveNext() {
0617   return OwningObject->moveRelocationNext(RelocationPimpl);
0618 }
0619 
0620 inline uint64_t RelocationRef::getOffset() const {
0621   return OwningObject->getRelocationOffset(RelocationPimpl);
0622 }
0623 
0624 inline symbol_iterator RelocationRef::getSymbol() const {
0625   return OwningObject->getRelocationSymbol(RelocationPimpl);
0626 }
0627 
0628 inline uint64_t RelocationRef::getType() const {
0629   return OwningObject->getRelocationType(RelocationPimpl);
0630 }
0631 
0632 inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
0633   return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
0634 }
0635 
0636 inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
0637   return RelocationPimpl;
0638 }
0639 
0640 inline const ObjectFile *RelocationRef::getObject() const {
0641   return OwningObject;
0642 }
0643 
0644 } // end namespace object
0645 
0646 template <> struct DenseMapInfo<object::SectionRef> {
0647   static bool isEqual(const object::SectionRef &A,
0648                       const object::SectionRef &B) {
0649     return A == B;
0650   }
0651   static object::SectionRef getEmptyKey() {
0652     return object::SectionRef({}, nullptr);
0653   }
0654   static object::SectionRef getTombstoneKey() {
0655     object::DataRefImpl TS;
0656     TS.p = (uintptr_t)-1;
0657     return object::SectionRef(TS, nullptr);
0658   }
0659   static unsigned getHashValue(const object::SectionRef &Sec) {
0660     object::DataRefImpl Raw = Sec.getRawDataRefImpl();
0661     return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
0662   }
0663 };
0664 
0665 } // end namespace llvm
0666 
0667 #endif // LLVM_OBJECT_OBJECTFILE_H