Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- ELF.h - ELF object file implementation -------------------*- 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 the ELFFile template class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_OBJECT_ELF_H
0014 #define LLVM_OBJECT_ELF_H
0015 
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/SmallString.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/BinaryFormat/ELF.h"
0022 #include "llvm/Object/ELFTypes.h"
0023 #include "llvm/Object/Error.h"
0024 #include "llvm/Support/Compiler.h"
0025 #include "llvm/Support/DataExtractor.h"
0026 #include "llvm/Support/Error.h"
0027 #include <cassert>
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <limits>
0031 #include <type_traits>
0032 #include <utility>
0033 
0034 namespace llvm {
0035 namespace object {
0036 
0037 struct VerdAux {
0038   unsigned Offset;
0039   std::string Name;
0040 };
0041 
0042 struct VerDef {
0043   unsigned Offset;
0044   unsigned Version;
0045   unsigned Flags;
0046   unsigned Ndx;
0047   unsigned Cnt;
0048   unsigned Hash;
0049   std::string Name;
0050   std::vector<VerdAux> AuxV;
0051 };
0052 
0053 struct VernAux {
0054   unsigned Hash;
0055   unsigned Flags;
0056   unsigned Other;
0057   unsigned Offset;
0058   std::string Name;
0059 };
0060 
0061 struct VerNeed {
0062   unsigned Version;
0063   unsigned Cnt;
0064   unsigned Offset;
0065   std::string File;
0066   std::vector<VernAux> AuxV;
0067 };
0068 
0069 struct VersionEntry {
0070   std::string Name;
0071   bool IsVerDef;
0072 };
0073 
0074 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
0075 uint32_t getELFRelativeRelocationType(uint32_t Machine);
0076 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
0077 
0078 // Subclasses of ELFFile may need this for template instantiation
0079 inline std::pair<unsigned char, unsigned char>
0080 getElfArchType(StringRef Object) {
0081   if (Object.size() < ELF::EI_NIDENT)
0082     return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
0083                           (uint8_t)ELF::ELFDATANONE);
0084   return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
0085                         (uint8_t)Object[ELF::EI_DATA]);
0086 }
0087 
0088 enum PPCInstrMasks : uint64_t {
0089   PADDI_R12_NO_DISP = 0x0610000039800000,
0090   ADDIS_R12_TO_R2_NO_DISP = 0x3D820000,
0091   ADDI_R12_TO_R2_NO_DISP = 0x39820000,
0092   ADDI_R12_TO_R12_NO_DISP = 0x398C0000,
0093   PLD_R12_NO_DISP = 0x04100000E5800000,
0094   MTCTR_R12 = 0x7D8903A6,
0095   BCTR = 0x4E800420,
0096 };
0097 
0098 template <class ELFT> class ELFFile;
0099 
0100 template <class T> struct DataRegion {
0101   // This constructor is used when we know the start and the size of a data
0102   // region. We assume that Arr does not go past the end of the file.
0103   DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
0104 
0105   // Sometimes we only know the start of a data region. We still don't want to
0106   // read past the end of the file, so we provide the end of a buffer.
0107   DataRegion(const T *Data, const uint8_t *BufferEnd)
0108       : First(Data), BufEnd(BufferEnd) {}
0109 
0110   Expected<T> operator[](uint64_t N) {
0111     assert(Size || BufEnd);
0112     if (Size) {
0113       if (N >= *Size)
0114         return createError(
0115             "the index is greater than or equal to the number of entries (" +
0116             Twine(*Size) + ")");
0117     } else {
0118       const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
0119       if (EntryStart + sizeof(T) > BufEnd)
0120         return createError("can't read past the end of the file");
0121     }
0122     return *(First + N);
0123   }
0124 
0125   const T *First;
0126   std::optional<uint64_t> Size;
0127   const uint8_t *BufEnd = nullptr;
0128 };
0129 
0130 template <class ELFT>
0131 static std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
0132                                        const typename ELFT::Shdr &Sec) {
0133   auto TableOrErr = Obj.sections();
0134   if (TableOrErr)
0135     return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
0136   // To make this helper be more convenient for error reporting purposes we
0137   // drop the error. But really it should never be triggered. Before this point,
0138   // our code should have called 'sections()' and reported a proper error on
0139   // failure.
0140   llvm::consumeError(TableOrErr.takeError());
0141   return "[unknown index]";
0142 }
0143 
0144 template <class ELFT>
0145 static std::string describe(const ELFFile<ELFT> &Obj,
0146                             const typename ELFT::Shdr &Sec) {
0147   unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
0148   return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
0149                                         Sec.sh_type) +
0150           " section with index " + Twine(SecNdx))
0151       .str();
0152 }
0153 
0154 template <class ELFT>
0155 static std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
0156                                         const typename ELFT::Phdr &Phdr) {
0157   auto Headers = Obj.program_headers();
0158   if (Headers)
0159     return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
0160   // See comment in the getSecIndexForError() above.
0161   llvm::consumeError(Headers.takeError());
0162   return "[unknown index]";
0163 }
0164 
0165 static inline Error defaultWarningHandler(const Twine &Msg) {
0166   return createError(Msg);
0167 }
0168 
0169 template <class ELFT>
0170 static bool checkSectionOffsets(const typename ELFT::Phdr &Phdr,
0171                                 const typename ELFT::Shdr &Sec) {
0172   // SHT_NOBITS sections don't need to have an offset inside the segment.
0173   if (Sec.sh_type == ELF::SHT_NOBITS)
0174     return true;
0175 
0176   if (Sec.sh_offset < Phdr.p_offset)
0177     return false;
0178 
0179   // Only non-empty sections can be at the end of a segment.
0180   if (Sec.sh_size == 0)
0181     return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);
0182   return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;
0183 }
0184 
0185 // Check that an allocatable section belongs to a virtual address
0186 // space of a segment.
0187 template <class ELFT>
0188 static bool checkSectionVMA(const typename ELFT::Phdr &Phdr,
0189                             const typename ELFT::Shdr &Sec) {
0190   if (!(Sec.sh_flags & ELF::SHF_ALLOC))
0191     return true;
0192 
0193   if (Sec.sh_addr < Phdr.p_vaddr)
0194     return false;
0195 
0196   bool IsTbss =
0197       (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
0198   // .tbss is special, it only has memory in PT_TLS and has NOBITS properties.
0199   bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;
0200   // Only non-empty sections can be at the end of a segment.
0201   if (Sec.sh_size == 0 || IsTbssInNonTLS)
0202     return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;
0203   return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;
0204 }
0205 
0206 template <class ELFT>
0207 static bool isSectionInSegment(const typename ELFT::Phdr &Phdr,
0208                                const typename ELFT::Shdr &Sec) {
0209   return checkSectionOffsets<ELFT>(Phdr, Sec) &&
0210          checkSectionVMA<ELFT>(Phdr, Sec);
0211 }
0212 
0213 // HdrHandler is called once with the number of relocations and whether the
0214 // relocations have addends. EntryHandler is called once per decoded relocation.
0215 template <bool Is64>
0216 static Error decodeCrel(
0217     ArrayRef<uint8_t> Content,
0218     function_ref<void(uint64_t /*relocation count*/, bool /*explicit addends*/)>
0219         HdrHandler,
0220     function_ref<void(Elf_Crel_Impl<Is64>)> EntryHandler) {
0221   DataExtractor Data(Content, true, 8); // endian and address size are unused
0222   DataExtractor::Cursor Cur(0);
0223   const uint64_t Hdr = Data.getULEB128(Cur);
0224   size_t Count = Hdr / 8;
0225   const size_t FlagBits = Hdr & ELF::CREL_HDR_ADDEND ? 3 : 2;
0226   const size_t Shift = Hdr % ELF::CREL_HDR_ADDEND;
0227   using uint = typename Elf_Crel_Impl<Is64>::uint;
0228   uint Offset = 0, Addend = 0;
0229   HdrHandler(Count, Hdr & ELF::CREL_HDR_ADDEND);
0230   uint32_t SymIdx = 0, Type = 0;
0231   for (; Count; --Count) {
0232     // The delta offset and flags member may be larger than uint64_t. Special
0233     // case the first byte (2 or 3 flag bits; the rest are offset bits). Other
0234     // ULEB128 bytes encode the remaining delta offset bits.
0235     const uint8_t B = Data.getU8(Cur);
0236     Offset += B >> FlagBits;
0237     if (B >= 0x80)
0238       Offset += (Data.getULEB128(Cur) << (7 - FlagBits)) - (0x80 >> FlagBits);
0239     // Delta symidx/type/addend members (SLEB128).
0240     if (B & 1)
0241       SymIdx += Data.getSLEB128(Cur);
0242     if (B & 2)
0243       Type += Data.getSLEB128(Cur);
0244     if (B & 4 & Hdr)
0245       Addend += Data.getSLEB128(Cur);
0246     if (!Cur)
0247       break;
0248     EntryHandler(
0249         {Offset << Shift, SymIdx, Type, std::make_signed_t<uint>(Addend)});
0250   }
0251   return Cur.takeError();
0252 }
0253 
0254 template <class ELFT>
0255 class ELFFile {
0256 public:
0257   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0258 
0259   // This is a callback that can be passed to a number of functions.
0260   // It can be used to ignore non-critical errors (warnings), which is
0261   // useful for dumpers, like llvm-readobj.
0262   // It accepts a warning message string and returns a success
0263   // when the warning should be ignored or an error otherwise.
0264   using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
0265 
0266   const uint8_t *base() const { return Buf.bytes_begin(); }
0267   const uint8_t *end() const { return base() + getBufSize(); }
0268 
0269   size_t getBufSize() const { return Buf.size(); }
0270 
0271 private:
0272   StringRef Buf;
0273   std::vector<Elf_Shdr> FakeSections;
0274   SmallString<0> FakeSectionStrings;
0275 
0276   ELFFile(StringRef Object);
0277 
0278 public:
0279   const Elf_Ehdr &getHeader() const {
0280     return *reinterpret_cast<const Elf_Ehdr *>(base());
0281   }
0282 
0283   template <typename T>
0284   Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
0285   template <typename T>
0286   Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
0287 
0288   Expected<std::vector<VerDef>>
0289   getVersionDefinitions(const Elf_Shdr &Sec) const;
0290   Expected<std::vector<VerNeed>> getVersionDependencies(
0291       const Elf_Shdr &Sec,
0292       WarningHandler WarnHandler = &defaultWarningHandler) const;
0293   Expected<StringRef> getSymbolVersionByIndex(
0294       uint32_t SymbolVersionIndex, bool &IsDefault,
0295       SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
0296       std::optional<bool> IsSymHidden) const;
0297 
0298   Expected<StringRef>
0299   getStringTable(const Elf_Shdr &Section,
0300                  WarningHandler WarnHandler = &defaultWarningHandler) const;
0301   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
0302   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
0303                                               Elf_Shdr_Range Sections) const;
0304   Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
0305 
0306   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
0307   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
0308                                              Elf_Shdr_Range Sections) const;
0309 
0310   Expected<uint64_t> getDynSymtabSize() const;
0311 
0312   StringRef getRelocationTypeName(uint32_t Type) const;
0313   void getRelocationTypeName(uint32_t Type,
0314                              SmallVectorImpl<char> &Result) const;
0315   uint32_t getRelativeRelocationType() const;
0316 
0317   std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
0318   std::string getDynamicTagAsString(uint64_t Type) const;
0319 
0320   /// Get the symbol for a given relocation.
0321   Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
0322                                                 const Elf_Shdr *SymTab) const;
0323 
0324   Expected<SmallVector<std::optional<VersionEntry>, 0>>
0325   loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
0326 
0327   static Expected<ELFFile> create(StringRef Object);
0328 
0329   bool isLE() const {
0330     return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
0331   }
0332 
0333   bool isMipsELF64() const {
0334     return getHeader().e_machine == ELF::EM_MIPS &&
0335            getHeader().getFileClass() == ELF::ELFCLASS64;
0336   }
0337 
0338   bool isMips64EL() const { return isMipsELF64() && isLE(); }
0339 
0340   Expected<Elf_Shdr_Range> sections() const;
0341 
0342   Expected<Elf_Dyn_Range> dynamicEntries() const;
0343 
0344   Expected<const uint8_t *>
0345   toMappedAddr(uint64_t VAddr,
0346                WarningHandler WarnHandler = &defaultWarningHandler) const;
0347 
0348   Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
0349     if (!Sec)
0350       return ArrayRef<Elf_Sym>(nullptr, nullptr);
0351     return getSectionContentsAsArray<Elf_Sym>(*Sec);
0352   }
0353 
0354   Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
0355     return getSectionContentsAsArray<Elf_Rela>(Sec);
0356   }
0357 
0358   Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
0359     return getSectionContentsAsArray<Elf_Rel>(Sec);
0360   }
0361 
0362   Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
0363     return getSectionContentsAsArray<Elf_Relr>(Sec);
0364   }
0365 
0366   std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
0367 
0368   Expected<uint64_t> getCrelHeader(ArrayRef<uint8_t> Content) const;
0369   using RelsOrRelas = std::pair<std::vector<Elf_Rel>, std::vector<Elf_Rela>>;
0370   Expected<RelsOrRelas> decodeCrel(ArrayRef<uint8_t> Content) const;
0371   Expected<RelsOrRelas> crels(const Elf_Shdr &Sec) const;
0372 
0373   Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
0374 
0375   /// Iterate over program header table.
0376   Expected<Elf_Phdr_Range> program_headers() const {
0377     if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
0378       return createError("invalid e_phentsize: " +
0379                          Twine(getHeader().e_phentsize));
0380 
0381     uint64_t HeadersSize =
0382         (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
0383     uint64_t PhOff = getHeader().e_phoff;
0384     if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
0385       return createError("program headers are longer than binary of size " +
0386                          Twine(getBufSize()) + ": e_phoff = 0x" +
0387                          Twine::utohexstr(getHeader().e_phoff) +
0388                          ", e_phnum = " + Twine(getHeader().e_phnum) +
0389                          ", e_phentsize = " + Twine(getHeader().e_phentsize));
0390 
0391     auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
0392     return ArrayRef(Begin, Begin + getHeader().e_phnum);
0393   }
0394 
0395   /// Get an iterator over notes in a program header.
0396   ///
0397   /// The program header must be of type \c PT_NOTE.
0398   ///
0399   /// \param Phdr the program header to iterate over.
0400   /// \param Err [out] an error to support fallible iteration, which should
0401   ///  be checked after iteration ends.
0402   Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
0403     assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
0404     ErrorAsOutParameter ErrAsOutParam(Err);
0405     if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
0406       Err =
0407           createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
0408                       ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
0409       return Elf_Note_Iterator(Err);
0410     }
0411     // Allow 4, 8, and (for Linux core dumps) 0.
0412     // TODO: Disallow 1 after all tests are fixed.
0413     if (Phdr.p_align != 0 && Phdr.p_align != 1 && Phdr.p_align != 4 &&
0414         Phdr.p_align != 8) {
0415       Err =
0416           createError("alignment (" + Twine(Phdr.p_align) + ") is not 4 or 8");
0417       return Elf_Note_Iterator(Err);
0418     }
0419     return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz,
0420                              std::max<size_t>(Phdr.p_align, 4), Err);
0421   }
0422 
0423   /// Get an iterator over notes in a section.
0424   ///
0425   /// The section must be of type \c SHT_NOTE.
0426   ///
0427   /// \param Shdr the section to iterate over.
0428   /// \param Err [out] an error to support fallible iteration, which should
0429   ///  be checked after iteration ends.
0430   Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
0431     assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
0432     ErrorAsOutParameter ErrAsOutParam(Err);
0433     if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
0434       Err =
0435           createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
0436                       ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
0437       return Elf_Note_Iterator(Err);
0438     }
0439     // TODO: Allow just 4 and 8 after all tests are fixed.
0440     if (Shdr.sh_addralign != 0 && Shdr.sh_addralign != 1 &&
0441         Shdr.sh_addralign != 4 && Shdr.sh_addralign != 8) {
0442       Err = createError("alignment (" + Twine(Shdr.sh_addralign) +
0443                         ") is not 4 or 8");
0444       return Elf_Note_Iterator(Err);
0445     }
0446     return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size,
0447                              std::max<size_t>(Shdr.sh_addralign, 4), Err);
0448   }
0449 
0450   /// Get the end iterator for notes.
0451   Elf_Note_Iterator notes_end() const {
0452     return Elf_Note_Iterator();
0453   }
0454 
0455   /// Get an iterator range over notes of a program header.
0456   ///
0457   /// The program header must be of type \c PT_NOTE.
0458   ///
0459   /// \param Phdr the program header to iterate over.
0460   /// \param Err [out] an error to support fallible iteration, which should
0461   ///  be checked after iteration ends.
0462   iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
0463                                           Error &Err) const {
0464     return make_range(notes_begin(Phdr, Err), notes_end());
0465   }
0466 
0467   /// Get an iterator range over notes of a section.
0468   ///
0469   /// The section must be of type \c SHT_NOTE.
0470   ///
0471   /// \param Shdr the section to iterate over.
0472   /// \param Err [out] an error to support fallible iteration, which should
0473   ///  be checked after iteration ends.
0474   iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
0475                                           Error &Err) const {
0476     return make_range(notes_begin(Shdr, Err), notes_end());
0477   }
0478 
0479   Expected<StringRef> getSectionStringTable(
0480       Elf_Shdr_Range Sections,
0481       WarningHandler WarnHandler = &defaultWarningHandler) const;
0482   Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
0483                                      DataRegion<Elf_Word> ShndxTable) const;
0484   Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
0485                                         const Elf_Shdr *SymTab,
0486                                         DataRegion<Elf_Word> ShndxTable) const;
0487   Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
0488                                         Elf_Sym_Range Symtab,
0489                                         DataRegion<Elf_Word> ShndxTable) const;
0490   Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
0491 
0492   Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
0493                                       uint32_t Index) const;
0494 
0495   Expected<StringRef>
0496   getSectionName(const Elf_Shdr &Section,
0497                  WarningHandler WarnHandler = &defaultWarningHandler) const;
0498   Expected<StringRef> getSectionName(const Elf_Shdr &Section,
0499                                      StringRef DotShstrtab) const;
0500   template <typename T>
0501   Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
0502   Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
0503   Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
0504 
0505   /// Returns a vector of BBAddrMap structs corresponding to each function
0506   /// within the text section that the SHT_LLVM_BB_ADDR_MAP section \p Sec
0507   /// is associated with. If the current ELFFile is relocatable, a corresponding
0508   /// \p RelaSec must be passed in as an argument.
0509   /// Optional out variable to collect all PGO Analyses. New elements are only
0510   /// added if no error occurs. If not provided, the PGO Analyses are decoded
0511   /// then ignored.
0512   Expected<std::vector<BBAddrMap>>
0513   decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr,
0514                   std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr) const;
0515 
0516   /// Returns a map from every section matching \p IsMatch to its relocation
0517   /// section, or \p nullptr if it has no relocation section. This function
0518   /// returns an error if any of the \p IsMatch calls fail or if it fails to
0519   /// retrieve the content section of any relocation section.
0520   Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>>
0521   getSectionAndRelocations(
0522       std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const;
0523 
0524   void createFakeSections();
0525 };
0526 
0527 using ELF32LEFile = ELFFile<ELF32LE>;
0528 using ELF64LEFile = ELFFile<ELF64LE>;
0529 using ELF32BEFile = ELFFile<ELF32BE>;
0530 using ELF64BEFile = ELFFile<ELF64BE>;
0531 
0532 template <class ELFT>
0533 inline Expected<const typename ELFT::Shdr *>
0534 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
0535   if (Index >= Sections.size())
0536     return createError("invalid section index: " + Twine(Index));
0537   return &Sections[Index];
0538 }
0539 
0540 template <class ELFT>
0541 inline Expected<uint32_t>
0542 getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
0543                             DataRegion<typename ELFT::Word> ShndxTable) {
0544   assert(Sym.st_shndx == ELF::SHN_XINDEX);
0545   if (!ShndxTable.First)
0546     return createError(
0547         "found an extended symbol index (" + Twine(SymIndex) +
0548         "), but unable to locate the extended symbol index table");
0549 
0550   Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
0551   if (!TableOrErr)
0552     return createError("unable to read an extended symbol table at index " +
0553                        Twine(SymIndex) + ": " +
0554                        toString(TableOrErr.takeError()));
0555   return *TableOrErr;
0556 }
0557 
0558 template <class ELFT>
0559 Expected<uint32_t>
0560 ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
0561                                DataRegion<Elf_Word> ShndxTable) const {
0562   uint32_t Index = Sym.st_shndx;
0563   if (Index == ELF::SHN_XINDEX) {
0564     Expected<uint32_t> ErrorOrIndex =
0565         getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
0566     if (!ErrorOrIndex)
0567       return ErrorOrIndex.takeError();
0568     return *ErrorOrIndex;
0569   }
0570   if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
0571     return 0;
0572   return Index;
0573 }
0574 
0575 template <class ELFT>
0576 Expected<const typename ELFT::Shdr *>
0577 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
0578                           DataRegion<Elf_Word> ShndxTable) const {
0579   auto SymsOrErr = symbols(SymTab);
0580   if (!SymsOrErr)
0581     return SymsOrErr.takeError();
0582   return getSection(Sym, *SymsOrErr, ShndxTable);
0583 }
0584 
0585 template <class ELFT>
0586 Expected<const typename ELFT::Shdr *>
0587 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
0588                           DataRegion<Elf_Word> ShndxTable) const {
0589   auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
0590   if (!IndexOrErr)
0591     return IndexOrErr.takeError();
0592   uint32_t Index = *IndexOrErr;
0593   if (Index == 0)
0594     return nullptr;
0595   return getSection(Index);
0596 }
0597 
0598 template <class ELFT>
0599 Expected<const typename ELFT::Sym *>
0600 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
0601   auto SymsOrErr = symbols(Sec);
0602   if (!SymsOrErr)
0603     return SymsOrErr.takeError();
0604 
0605   Elf_Sym_Range Symbols = *SymsOrErr;
0606   if (Index >= Symbols.size())
0607     return createError("unable to get symbol from section " +
0608                        getSecIndexForError(*this, *Sec) +
0609                        ": invalid symbol index (" + Twine(Index) + ")");
0610   return &Symbols[Index];
0611 }
0612 
0613 template <class ELFT>
0614 template <typename T>
0615 Expected<ArrayRef<T>>
0616 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
0617   if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
0618     return createError("section " + getSecIndexForError(*this, Sec) +
0619                        " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
0620                        ", but got " + Twine(Sec.sh_entsize));
0621 
0622   uintX_t Offset = Sec.sh_offset;
0623   uintX_t Size = Sec.sh_size;
0624 
0625   if (Size % sizeof(T))
0626     return createError("section " + getSecIndexForError(*this, Sec) +
0627                        " has an invalid sh_size (" + Twine(Size) +
0628                        ") which is not a multiple of its sh_entsize (" +
0629                        Twine(Sec.sh_entsize) + ")");
0630   if (std::numeric_limits<uintX_t>::max() - Offset < Size)
0631     return createError("section " + getSecIndexForError(*this, Sec) +
0632                        " has a sh_offset (0x" + Twine::utohexstr(Offset) +
0633                        ") + sh_size (0x" + Twine::utohexstr(Size) +
0634                        ") that cannot be represented");
0635   if (Offset + Size > Buf.size())
0636     return createError("section " + getSecIndexForError(*this, Sec) +
0637                        " has a sh_offset (0x" + Twine::utohexstr(Offset) +
0638                        ") + sh_size (0x" + Twine::utohexstr(Size) +
0639                        ") that is greater than the file size (0x" +
0640                        Twine::utohexstr(Buf.size()) + ")");
0641 
0642   if (Offset % alignof(T))
0643     // TODO: this error is untested.
0644     return createError("unaligned data");
0645 
0646   const T *Start = reinterpret_cast<const T *>(base() + Offset);
0647   return ArrayRef(Start, Size / sizeof(T));
0648 }
0649 
0650 template <class ELFT>
0651 Expected<ArrayRef<uint8_t>>
0652 ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
0653   uintX_t Offset = Phdr.p_offset;
0654   uintX_t Size = Phdr.p_filesz;
0655 
0656   if (std::numeric_limits<uintX_t>::max() - Offset < Size)
0657     return createError("program header " + getPhdrIndexForError(*this, Phdr) +
0658                        " has a p_offset (0x" + Twine::utohexstr(Offset) +
0659                        ") + p_filesz (0x" + Twine::utohexstr(Size) +
0660                        ") that cannot be represented");
0661   if (Offset + Size > Buf.size())
0662     return createError("program header  " + getPhdrIndexForError(*this, Phdr) +
0663                        " has a p_offset (0x" + Twine::utohexstr(Offset) +
0664                        ") + p_filesz (0x" + Twine::utohexstr(Size) +
0665                        ") that is greater than the file size (0x" +
0666                        Twine::utohexstr(Buf.size()) + ")");
0667   return ArrayRef(base() + Offset, Size);
0668 }
0669 
0670 template <class ELFT>
0671 Expected<ArrayRef<uint8_t>>
0672 ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
0673   return getSectionContentsAsArray<uint8_t>(Sec);
0674 }
0675 
0676 template <class ELFT>
0677 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
0678   return getELFRelocationTypeName(getHeader().e_machine, Type);
0679 }
0680 
0681 template <class ELFT>
0682 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
0683                                           SmallVectorImpl<char> &Result) const {
0684   if (!isMipsELF64()) {
0685     StringRef Name = getRelocationTypeName(Type);
0686     Result.append(Name.begin(), Name.end());
0687   } else {
0688     // The Mips N64 ABI allows up to three operations to be specified per
0689     // relocation record. Unfortunately there's no easy way to test for the
0690     // presence of N64 ELFs as they have no special flag that identifies them
0691     // as being N64. We can safely assume at the moment that all Mips
0692     // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
0693     // information to disambiguate between old vs new ABIs.
0694     uint8_t Type1 = (Type >> 0) & 0xFF;
0695     uint8_t Type2 = (Type >> 8) & 0xFF;
0696     uint8_t Type3 = (Type >> 16) & 0xFF;
0697 
0698     // Concat all three relocation type names.
0699     StringRef Name = getRelocationTypeName(Type1);
0700     Result.append(Name.begin(), Name.end());
0701 
0702     Name = getRelocationTypeName(Type2);
0703     Result.append(1, '/');
0704     Result.append(Name.begin(), Name.end());
0705 
0706     Name = getRelocationTypeName(Type3);
0707     Result.append(1, '/');
0708     Result.append(Name.begin(), Name.end());
0709   }
0710 }
0711 
0712 template <class ELFT>
0713 uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
0714   return getELFRelativeRelocationType(getHeader().e_machine);
0715 }
0716 
0717 template <class ELFT>
0718 Expected<SmallVector<std::optional<VersionEntry>, 0>>
0719 ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
0720                               const Elf_Shdr *VerDefSec) const {
0721   SmallVector<std::optional<VersionEntry>, 0> VersionMap;
0722 
0723   // The first two version indexes are reserved.
0724   // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL.
0725   VersionMap.push_back(VersionEntry());
0726   VersionMap.push_back(VersionEntry());
0727 
0728   auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
0729     if (N >= VersionMap.size())
0730       VersionMap.resize(N + 1);
0731     VersionMap[N] = {std::string(Version), IsVerdef};
0732   };
0733 
0734   if (VerDefSec) {
0735     Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
0736     if (!Defs)
0737       return Defs.takeError();
0738     for (const VerDef &Def : *Defs)
0739       InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
0740   }
0741 
0742   if (VerNeedSec) {
0743     Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
0744     if (!Deps)
0745       return Deps.takeError();
0746     for (const VerNeed &Dep : *Deps)
0747       for (const VernAux &Aux : Dep.AuxV)
0748         InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
0749   }
0750 
0751   return VersionMap;
0752 }
0753 
0754 template <class ELFT>
0755 Expected<const typename ELFT::Sym *>
0756 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
0757                                    const Elf_Shdr *SymTab) const {
0758   uint32_t Index = Rel.getSymbol(isMips64EL());
0759   if (Index == 0)
0760     return nullptr;
0761   return getEntry<Elf_Sym>(*SymTab, Index);
0762 }
0763 
0764 template <class ELFT>
0765 Expected<StringRef>
0766 ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
0767                                      WarningHandler WarnHandler) const {
0768   uint32_t Index = getHeader().e_shstrndx;
0769   if (Index == ELF::SHN_XINDEX) {
0770     // If the section name string table section index is greater than
0771     // or equal to SHN_LORESERVE, then the actual index of the section name
0772     // string table section is contained in the sh_link field of the section
0773     // header at index 0.
0774     if (Sections.empty())
0775       return createError(
0776           "e_shstrndx == SHN_XINDEX, but the section header table is empty");
0777 
0778     Index = Sections[0].sh_link;
0779   }
0780 
0781   // There is no section name string table. Return FakeSectionStrings which
0782   // is non-empty if we have created fake sections.
0783   if (!Index)
0784     return FakeSectionStrings;
0785 
0786   if (Index >= Sections.size())
0787     return createError("section header string table index " + Twine(Index) +
0788                        " does not exist");
0789   return getStringTable(Sections[Index], WarnHandler);
0790 }
0791 
0792 /// This function finds the number of dynamic symbols using a GNU hash table.
0793 ///
0794 /// @param Table The GNU hash table for .dynsym.
0795 template <class ELFT>
0796 static Expected<uint64_t>
0797 getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
0798                             const void *BufEnd) {
0799   using Elf_Word = typename ELFT::Word;
0800   if (Table.nbuckets == 0)
0801     return Table.symndx + 1;
0802   uint64_t LastSymIdx = 0;
0803   // Find the index of the first symbol in the last chain.
0804   for (Elf_Word Val : Table.buckets())
0805     LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
0806   const Elf_Word *It =
0807       reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
0808   // Locate the end of the chain to find the last symbol index.
0809   while (It < BufEnd && (*It & 1) == 0) {
0810     ++LastSymIdx;
0811     ++It;
0812   }
0813   if (It >= BufEnd) {
0814     return createStringError(
0815         object_error::parse_failed,
0816         "no terminator found for GNU hash section before buffer end");
0817   }
0818   return LastSymIdx + 1;
0819 }
0820 
0821 /// This function determines the number of dynamic symbols. It reads section
0822 /// headers first. If section headers are not available, the number of
0823 /// symbols will be inferred by parsing dynamic hash tables.
0824 template <class ELFT>
0825 Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
0826   // Read .dynsym section header first if available.
0827   Expected<Elf_Shdr_Range> SectionsOrError = sections();
0828   if (!SectionsOrError)
0829     return SectionsOrError.takeError();
0830   for (const Elf_Shdr &Sec : *SectionsOrError) {
0831     if (Sec.sh_type == ELF::SHT_DYNSYM) {
0832       if (Sec.sh_size % Sec.sh_entsize != 0) {
0833         return createStringError(object_error::parse_failed,
0834                                  "SHT_DYNSYM section has sh_size (" +
0835                                      Twine(Sec.sh_size) + ") % sh_entsize (" +
0836                                      Twine(Sec.sh_entsize) + ") that is not 0");
0837       }
0838       return Sec.sh_size / Sec.sh_entsize;
0839     }
0840   }
0841 
0842   if (!SectionsOrError->empty()) {
0843     // Section headers are available but .dynsym header is not found.
0844     // Return 0 as .dynsym does not exist.
0845     return 0;
0846   }
0847 
0848   // Section headers do not exist. Falling back to infer
0849   // upper bound of .dynsym from .gnu.hash and .hash.
0850   Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
0851   if (!DynTable)
0852     return DynTable.takeError();
0853   std::optional<uint64_t> ElfHash;
0854   std::optional<uint64_t> ElfGnuHash;
0855   for (const Elf_Dyn &Entry : *DynTable) {
0856     switch (Entry.d_tag) {
0857     case ELF::DT_HASH:
0858       ElfHash = Entry.d_un.d_ptr;
0859       break;
0860     case ELF::DT_GNU_HASH:
0861       ElfGnuHash = Entry.d_un.d_ptr;
0862       break;
0863     }
0864   }
0865   if (ElfGnuHash) {
0866     Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
0867     if (!TablePtr)
0868       return TablePtr.takeError();
0869     const Elf_GnuHash *Table =
0870         reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
0871     return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
0872   }
0873 
0874   // Search SYSV hash table to try to find the upper bound of dynsym.
0875   if (ElfHash) {
0876     Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
0877     if (!TablePtr)
0878       return TablePtr.takeError();
0879     const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
0880     return Table->nchain;
0881   }
0882   return 0;
0883 }
0884 
0885 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
0886 
0887 template <class ELFT>
0888 Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
0889   if (sizeof(Elf_Ehdr) > Object.size())
0890     return createError("invalid buffer: the size (" + Twine(Object.size()) +
0891                        ") is smaller than an ELF header (" +
0892                        Twine(sizeof(Elf_Ehdr)) + ")");
0893   return ELFFile(Object);
0894 }
0895 
0896 /// Used by llvm-objdump -d (which needs sections for disassembly) to
0897 /// disassemble objects without a section header table (e.g. ET_CORE objects
0898 /// analyzed by linux perf or ET_EXEC with llvm-strip --strip-sections).
0899 template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
0900   if (!FakeSections.empty())
0901     return;
0902   auto PhdrsOrErr = program_headers();
0903   if (!PhdrsOrErr)
0904     return;
0905 
0906   FakeSectionStrings += '\0';
0907   for (auto [Idx, Phdr] : llvm::enumerate(*PhdrsOrErr)) {
0908     if (Phdr.p_type != ELF::PT_LOAD || !(Phdr.p_flags & ELF::PF_X))
0909       continue;
0910     Elf_Shdr FakeShdr = {};
0911     FakeShdr.sh_type = ELF::SHT_PROGBITS;
0912     FakeShdr.sh_flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
0913     FakeShdr.sh_addr = Phdr.p_vaddr;
0914     FakeShdr.sh_size = Phdr.p_memsz;
0915     FakeShdr.sh_offset = Phdr.p_offset;
0916     // Create a section name based on the p_type and index.
0917     FakeShdr.sh_name = FakeSectionStrings.size();
0918     FakeSectionStrings += ("PT_LOAD#" + Twine(Idx)).str();
0919     FakeSectionStrings += '\0';
0920     FakeSections.push_back(FakeShdr);
0921   }
0922 }
0923 
0924 template <class ELFT>
0925 Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
0926   const uintX_t SectionTableOffset = getHeader().e_shoff;
0927   if (SectionTableOffset == 0) {
0928     if (!FakeSections.empty())
0929       return ArrayRef(FakeSections.data(), FakeSections.size());
0930     return ArrayRef<Elf_Shdr>();
0931   }
0932 
0933   if (getHeader().e_shentsize != sizeof(Elf_Shdr))
0934     return createError("invalid e_shentsize in ELF header: " +
0935                        Twine(getHeader().e_shentsize));
0936 
0937   const uint64_t FileSize = Buf.size();
0938   if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
0939       SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
0940     return createError(
0941         "section header table goes past the end of the file: e_shoff = 0x" +
0942         Twine::utohexstr(SectionTableOffset));
0943 
0944   // Invalid address alignment of section headers
0945   if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
0946     // TODO: this error is untested.
0947     return createError("invalid alignment of section headers");
0948 
0949   const Elf_Shdr *First =
0950       reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
0951 
0952   uintX_t NumSections = getHeader().e_shnum;
0953   if (NumSections == 0)
0954     NumSections = First->sh_size;
0955 
0956   if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
0957     return createError("invalid number of sections specified in the NULL "
0958                        "section's sh_size field (" +
0959                        Twine(NumSections) + ")");
0960 
0961   const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
0962   if (SectionTableOffset + SectionTableSize < SectionTableOffset)
0963     return createError(
0964         "invalid section header table offset (e_shoff = 0x" +
0965         Twine::utohexstr(SectionTableOffset) +
0966         ") or invalid number of sections specified in the first section "
0967         "header's sh_size field (0x" +
0968         Twine::utohexstr(NumSections) + ")");
0969 
0970   // Section table goes past end of file!
0971   if (SectionTableOffset + SectionTableSize > FileSize)
0972     return createError("section table goes past the end of file");
0973   return ArrayRef(First, NumSections);
0974 }
0975 
0976 template <class ELFT>
0977 template <typename T>
0978 Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
0979                                             uint32_t Entry) const {
0980   auto SecOrErr = getSection(Section);
0981   if (!SecOrErr)
0982     return SecOrErr.takeError();
0983   return getEntry<T>(**SecOrErr, Entry);
0984 }
0985 
0986 template <class ELFT>
0987 template <typename T>
0988 Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
0989                                             uint32_t Entry) const {
0990   Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
0991   if (!EntriesOrErr)
0992     return EntriesOrErr.takeError();
0993 
0994   ArrayRef<T> Arr = *EntriesOrErr;
0995   if (Entry >= Arr.size())
0996     return createError(
0997         "can't read an entry at 0x" +
0998         Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
0999         ": it goes past the end of the section (0x" +
1000         Twine::utohexstr(Section.sh_size) + ")");
1001   return &Arr[Entry];
1002 }
1003 
1004 template <typename ELFT>
1005 Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
1006     uint32_t SymbolVersionIndex, bool &IsDefault,
1007     SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
1008     std::optional<bool> IsSymHidden) const {
1009   size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
1010 
1011   // Special markers for unversioned symbols.
1012   if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
1013       VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
1014     IsDefault = false;
1015     return "";
1016   }
1017 
1018   // Lookup this symbol in the version table.
1019   if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
1020     return createError("SHT_GNU_versym section refers to a version index " +
1021                        Twine(VersionIndex) + " which is missing");
1022 
1023   const VersionEntry &Entry = *VersionMap[VersionIndex];
1024   // A default version (@@) is only available for defined symbols.
1025   if (!Entry.IsVerDef || IsSymHidden.value_or(false))
1026     IsDefault = false;
1027   else
1028     IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
1029   return Entry.Name.c_str();
1030 }
1031 
1032 template <class ELFT>
1033 Expected<std::vector<VerDef>>
1034 ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
1035   Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
1036   if (!StrTabOrErr)
1037     return StrTabOrErr.takeError();
1038 
1039   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
1040   if (!ContentsOrErr)
1041     return createError("cannot read content of " + describe(*this, Sec) + ": " +
1042                        toString(ContentsOrErr.takeError()));
1043 
1044   const uint8_t *Start = ContentsOrErr->data();
1045   const uint8_t *End = Start + ContentsOrErr->size();
1046 
1047   auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
1048                             unsigned VerDefNdx) -> Expected<VerdAux> {
1049     if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
1050       return createError("invalid " + describe(*this, Sec) +
1051                          ": version definition " + Twine(VerDefNdx) +
1052                          " refers to an auxiliary entry that goes past the end "
1053                          "of the section");
1054 
1055     auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
1056     VerdauxBuf += Verdaux->vda_next;
1057 
1058     VerdAux Aux;
1059     Aux.Offset = VerdauxBuf - Start;
1060     if (Verdaux->vda_name <= StrTabOrErr->size())
1061       Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
1062     else
1063       Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
1064     return Aux;
1065   };
1066 
1067   std::vector<VerDef> Ret;
1068   const uint8_t *VerdefBuf = Start;
1069   for (unsigned I = 1; I <= /*VerDefsNum=*/Sec.sh_info; ++I) {
1070     if (VerdefBuf + sizeof(Elf_Verdef) > End)
1071       return createError("invalid " + describe(*this, Sec) +
1072                          ": version definition " + Twine(I) +
1073                          " goes past the end of the section");
1074 
1075     if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
1076       return createError(
1077           "invalid " + describe(*this, Sec) +
1078           ": found a misaligned version definition entry at offset 0x" +
1079           Twine::utohexstr(VerdefBuf - Start));
1080 
1081     unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
1082     if (Version != 1)
1083       return createError("unable to dump " + describe(*this, Sec) +
1084                          ": version " + Twine(Version) +
1085                          " is not yet supported");
1086 
1087     const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
1088     VerDef &VD = *Ret.emplace(Ret.end());
1089     VD.Offset = VerdefBuf - Start;
1090     VD.Version = D->vd_version;
1091     VD.Flags = D->vd_flags;
1092     VD.Ndx = D->vd_ndx;
1093     VD.Cnt = D->vd_cnt;
1094     VD.Hash = D->vd_hash;
1095 
1096     const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
1097     for (unsigned J = 0; J < D->vd_cnt; ++J) {
1098       if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
1099         return createError("invalid " + describe(*this, Sec) +
1100                            ": found a misaligned auxiliary entry at offset 0x" +
1101                            Twine::utohexstr(VerdauxBuf - Start));
1102 
1103       Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
1104       if (!AuxOrErr)
1105         return AuxOrErr.takeError();
1106 
1107       if (J == 0)
1108         VD.Name = AuxOrErr->Name;
1109       else
1110         VD.AuxV.push_back(*AuxOrErr);
1111     }
1112 
1113     VerdefBuf += D->vd_next;
1114   }
1115 
1116   return Ret;
1117 }
1118 
1119 template <class ELFT>
1120 Expected<std::vector<VerNeed>>
1121 ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
1122                                       WarningHandler WarnHandler) const {
1123   StringRef StrTab;
1124   Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
1125   if (!StrTabOrErr) {
1126     if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
1127       return std::move(E);
1128   } else {
1129     StrTab = *StrTabOrErr;
1130   }
1131 
1132   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
1133   if (!ContentsOrErr)
1134     return createError("cannot read content of " + describe(*this, Sec) + ": " +
1135                        toString(ContentsOrErr.takeError()));
1136 
1137   const uint8_t *Start = ContentsOrErr->data();
1138   const uint8_t *End = Start + ContentsOrErr->size();
1139   const uint8_t *VerneedBuf = Start;
1140 
1141   std::vector<VerNeed> Ret;
1142   for (unsigned I = 1; I <= /*VerneedNum=*/Sec.sh_info; ++I) {
1143     if (VerneedBuf + sizeof(Elf_Verdef) > End)
1144       return createError("invalid " + describe(*this, Sec) +
1145                          ": version dependency " + Twine(I) +
1146                          " goes past the end of the section");
1147 
1148     if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
1149       return createError(
1150           "invalid " + describe(*this, Sec) +
1151           ": found a misaligned version dependency entry at offset 0x" +
1152           Twine::utohexstr(VerneedBuf - Start));
1153 
1154     unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
1155     if (Version != 1)
1156       return createError("unable to dump " + describe(*this, Sec) +
1157                          ": version " + Twine(Version) +
1158                          " is not yet supported");
1159 
1160     const Elf_Verneed *Verneed =
1161         reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
1162 
1163     VerNeed &VN = *Ret.emplace(Ret.end());
1164     VN.Version = Verneed->vn_version;
1165     VN.Cnt = Verneed->vn_cnt;
1166     VN.Offset = VerneedBuf - Start;
1167 
1168     if (Verneed->vn_file < StrTab.size())
1169       VN.File = std::string(StrTab.data() + Verneed->vn_file);
1170     else
1171       VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
1172 
1173     const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
1174     for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
1175       if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
1176         return createError("invalid " + describe(*this, Sec) +
1177                            ": found a misaligned auxiliary entry at offset 0x" +
1178                            Twine::utohexstr(VernauxBuf - Start));
1179 
1180       if (VernauxBuf + sizeof(Elf_Vernaux) > End)
1181         return createError(
1182             "invalid " + describe(*this, Sec) + ": version dependency " +
1183             Twine(I) +
1184             " refers to an auxiliary entry that goes past the end "
1185             "of the section");
1186 
1187       const Elf_Vernaux *Vernaux =
1188           reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
1189 
1190       VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
1191       Aux.Hash = Vernaux->vna_hash;
1192       Aux.Flags = Vernaux->vna_flags;
1193       Aux.Other = Vernaux->vna_other;
1194       Aux.Offset = VernauxBuf - Start;
1195       if (StrTab.size() <= Vernaux->vna_name)
1196         Aux.Name = "<corrupt>";
1197       else
1198         Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
1199 
1200       VernauxBuf += Vernaux->vna_next;
1201     }
1202     VerneedBuf += Verneed->vn_next;
1203   }
1204   return Ret;
1205 }
1206 
1207 template <class ELFT>
1208 Expected<const typename ELFT::Shdr *>
1209 ELFFile<ELFT>::getSection(uint32_t Index) const {
1210   auto TableOrErr = sections();
1211   if (!TableOrErr)
1212     return TableOrErr.takeError();
1213   return object::getSection<ELFT>(*TableOrErr, Index);
1214 }
1215 
1216 template <class ELFT>
1217 Expected<StringRef>
1218 ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
1219                               WarningHandler WarnHandler) const {
1220   if (Section.sh_type != ELF::SHT_STRTAB)
1221     if (Error E = WarnHandler("invalid sh_type for string table section " +
1222                               getSecIndexForError(*this, Section) +
1223                               ": expected SHT_STRTAB, but got " +
1224                               object::getELFSectionTypeName(
1225                                   getHeader().e_machine, Section.sh_type)))
1226       return std::move(E);
1227 
1228   auto V = getSectionContentsAsArray<char>(Section);
1229   if (!V)
1230     return V.takeError();
1231   ArrayRef<char> Data = *V;
1232   if (Data.empty())
1233     return createError("SHT_STRTAB string table section " +
1234                        getSecIndexForError(*this, Section) + " is empty");
1235   if (Data.back() != '\0')
1236     return createError("SHT_STRTAB string table section " +
1237                        getSecIndexForError(*this, Section) +
1238                        " is non-null terminated");
1239   return StringRef(Data.begin(), Data.size());
1240 }
1241 
1242 template <class ELFT>
1243 Expected<ArrayRef<typename ELFT::Word>>
1244 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
1245   auto SectionsOrErr = sections();
1246   if (!SectionsOrErr)
1247     return SectionsOrErr.takeError();
1248   return getSHNDXTable(Section, *SectionsOrErr);
1249 }
1250 
1251 template <class ELFT>
1252 Expected<ArrayRef<typename ELFT::Word>>
1253 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
1254                              Elf_Shdr_Range Sections) const {
1255   assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
1256   auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
1257   if (!VOrErr)
1258     return VOrErr.takeError();
1259   ArrayRef<Elf_Word> V = *VOrErr;
1260   auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
1261   if (!SymTableOrErr)
1262     return SymTableOrErr.takeError();
1263   const Elf_Shdr &SymTable = **SymTableOrErr;
1264   if (SymTable.sh_type != ELF::SHT_SYMTAB &&
1265       SymTable.sh_type != ELF::SHT_DYNSYM)
1266     return createError(
1267         "SHT_SYMTAB_SHNDX section is linked with " +
1268         object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
1269         " section (expected SHT_SYMTAB/SHT_DYNSYM)");
1270 
1271   uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
1272   if (V.size() != Syms)
1273     return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
1274                        " entries, but the symbol table associated has " +
1275                        Twine(Syms));
1276 
1277   return V;
1278 }
1279 
1280 template <class ELFT>
1281 Expected<StringRef>
1282 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
1283   auto SectionsOrErr = sections();
1284   if (!SectionsOrErr)
1285     return SectionsOrErr.takeError();
1286   return getStringTableForSymtab(Sec, *SectionsOrErr);
1287 }
1288 
1289 template <class ELFT>
1290 Expected<StringRef>
1291 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
1292                                        Elf_Shdr_Range Sections) const {
1293 
1294   if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
1295     return createError(
1296         "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
1297   Expected<const Elf_Shdr *> SectionOrErr =
1298       object::getSection<ELFT>(Sections, Sec.sh_link);
1299   if (!SectionOrErr)
1300     return SectionOrErr.takeError();
1301   return getStringTable(**SectionOrErr);
1302 }
1303 
1304 template <class ELFT>
1305 Expected<StringRef>
1306 ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
1307   Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
1308       getSection(Sec.sh_link);
1309   if (!StrTabSecOrErr)
1310     return createError("invalid section linked to " + describe(*this, Sec) +
1311                        ": " + toString(StrTabSecOrErr.takeError()));
1312 
1313   Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
1314   if (!StrTabOrErr)
1315     return createError("invalid string table linked to " +
1316                        describe(*this, Sec) + ": " +
1317                        toString(StrTabOrErr.takeError()));
1318   return *StrTabOrErr;
1319 }
1320 
1321 template <class ELFT>
1322 Expected<StringRef>
1323 ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1324                               WarningHandler WarnHandler) const {
1325   auto SectionsOrErr = sections();
1326   if (!SectionsOrErr)
1327     return SectionsOrErr.takeError();
1328   auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
1329   if (!Table)
1330     return Table.takeError();
1331   return getSectionName(Section, *Table);
1332 }
1333 
1334 template <class ELFT>
1335 Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1336                                                   StringRef DotShstrtab) const {
1337   uint32_t Offset = Section.sh_name;
1338   if (Offset == 0)
1339     return StringRef();
1340   if (Offset >= DotShstrtab.size())
1341     return createError("a section " + getSecIndexForError(*this, Section) +
1342                        " has an invalid sh_name (0x" +
1343                        Twine::utohexstr(Offset) +
1344                        ") offset which goes past the end of the "
1345                        "section name string table");
1346   return StringRef(DotShstrtab.data() + Offset);
1347 }
1348 
1349 /// This function returns the hash value for a symbol in the .dynsym section
1350 /// Name of the API remains consistent as specified in the libelf
1351 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
1352 inline uint32_t hashSysV(StringRef SymbolName) {
1353   uint32_t H = 0;
1354   for (uint8_t C : SymbolName) {
1355     H = (H << 4) + C;
1356     H ^= (H >> 24) & 0xf0;
1357   }
1358   return H & 0x0fffffff;
1359 }
1360 
1361 /// This function returns the hash value for a symbol in the .dynsym section
1362 /// for the GNU hash table. The implementation is defined in the GNU hash ABI.
1363 /// REF : https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c#l222
1364 inline uint32_t hashGnu(StringRef Name) {
1365   uint32_t H = 5381;
1366   for (uint8_t C : Name)
1367     H = (H << 5) + H + C;
1368   return H;
1369 }
1370 
1371 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF32LE>;
1372 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF32BE>;
1373 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF64LE>;
1374 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF64BE>;
1375 
1376 } // end namespace object
1377 } // end namespace llvm
1378 
1379 #endif // LLVM_OBJECT_ELF_H