1 //===- ELF.h - ELF object file implementation -------------------*- 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 the ELFFile template class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_OBJECT_ELF_H
14 #define LLVM_OBJECT_ELF_H
15 
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/MapVector.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/Object/ELFTypes.h"
23 #include "llvm/Object/Error.h"
24 #include "llvm/Support/Error.h"
25 #include <cassert>
26 #include <cstddef>
27 #include <cstdint>
28 #include <limits>
29 #include <utility>
30 
31 namespace llvm {
32 namespace object {
33 
34 struct VerdAux {
35   unsigned Offset;
36   std::string Name;
37 };
38 
39 struct VerDef {
40   unsigned Offset;
41   unsigned Version;
42   unsigned Flags;
43   unsigned Ndx;
44   unsigned Cnt;
45   unsigned Hash;
46   std::string Name;
47   std::vector<VerdAux> AuxV;
48 };
49 
50 struct VernAux {
51   unsigned Hash;
52   unsigned Flags;
53   unsigned Other;
54   unsigned Offset;
55   std::string Name;
56 };
57 
58 struct VerNeed {
59   unsigned Version;
60   unsigned Cnt;
61   unsigned Offset;
62   std::string File;
63   std::vector<VernAux> AuxV;
64 };
65 
66 struct VersionEntry {
67   std::string Name;
68   bool IsVerDef;
69 };
70 
71 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
72 uint32_t getELFRelativeRelocationType(uint32_t Machine);
73 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
74 
75 // Subclasses of ELFFile may need this for template instantiation
76 inline std::pair<unsigned char, unsigned char>
77 getElfArchType(StringRef Object) {
78   if (Object.size() < ELF::EI_NIDENT)
79     return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
80                           (uint8_t)ELF::ELFDATANONE);
81   return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
82                         (uint8_t)Object[ELF::EI_DATA]);
83 }
84 
85 enum PPCInstrMasks : uint64_t {
86   PADDI_R12_NO_DISP = 0x0610000039800000,
87   ADDIS_R12_TO_R2_NO_DISP = 0x3D820000,
88   ADDI_R12_TO_R2_NO_DISP = 0x39820000,
89   ADDI_R12_TO_R12_NO_DISP = 0x398C0000,
90   PLD_R12_NO_DISP = 0x04100000E5800000,
91   MTCTR_R12 = 0x7D8903A6,
92   BCTR = 0x4E800420,
93 };
94 
95 template <class ELFT> class ELFFile;
96 
97 template <class T> struct DataRegion {
98   // This constructor is used when we know the start and the size of a data
99   // region. We assume that Arr does not go past the end of the file.
100   DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
101 
102   // Sometimes we only know the start of a data region. We still don't want to
103   // read past the end of the file, so we provide the end of a buffer.
104   DataRegion(const T *Data, const uint8_t *BufferEnd)
105       : First(Data), BufEnd(BufferEnd) {}
106 
107   Expected<T> operator[](uint64_t N) {
108     assert(Size || BufEnd);
109     if (Size) {
110       if (N >= *Size)
111         return createError(
112             "the index is greater than or equal to the number of entries (" +
113             Twine(*Size) + ")");
114     } else {
115       const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
116       if (EntryStart + sizeof(T) > BufEnd)
117         return createError("can't read past the end of the file");
118     }
119     return *(First + N);
120   }
121 
122   const T *First;
123   std::optional<uint64_t> Size;
124   const uint8_t *BufEnd = nullptr;
125 };
126 
127 template <class ELFT>
128 std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
129                                 const typename ELFT::Shdr &Sec) {
130   auto TableOrErr = Obj.sections();
131   if (TableOrErr)
132     return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
133   // To make this helper be more convenient for error reporting purposes we
134   // drop the error. But really it should never be triggered. Before this point,
135   // our code should have called 'sections()' and reported a proper error on
136   // failure.
137   llvm::consumeError(TableOrErr.takeError());
138   return "[unknown index]";
139 }
140 
141 template <class ELFT>
142 static std::string describe(const ELFFile<ELFT> &Obj,
143                             const typename ELFT::Shdr &Sec) {
144   unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
145   return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
146                                         Sec.sh_type) +
147           " section with index " + Twine(SecNdx))
148       .str();
149 }
150 
151 template <class ELFT>
152 std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
153                                  const typename ELFT::Phdr &Phdr) {
154   auto Headers = Obj.program_headers();
155   if (Headers)
156     return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
157   // See comment in the getSecIndexForError() above.
158   llvm::consumeError(Headers.takeError());
159   return "[unknown index]";
160 }
161 
162 static inline Error defaultWarningHandler(const Twine &Msg) {
163   return createError(Msg);
164 }
165 
166 template <class ELFT>
167 bool checkSectionOffsets(const typename ELFT::Phdr &Phdr,
168                          const typename ELFT::Shdr &Sec) {
169   // SHT_NOBITS sections don't need to have an offset inside the segment.
170   if (Sec.sh_type == ELF::SHT_NOBITS)
171     return true;
172 
173   if (Sec.sh_offset < Phdr.p_offset)
174     return false;
175 
176   // Only non-empty sections can be at the end of a segment.
177   if (Sec.sh_size == 0)
178     return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);
179   return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;
180 }
181 
182 // Check that an allocatable section belongs to a virtual address
183 // space of a segment.
184 template <class ELFT>
185 bool checkSectionVMA(const typename ELFT::Phdr &Phdr,
186                      const typename ELFT::Shdr &Sec) {
187   if (!(Sec.sh_flags & ELF::SHF_ALLOC))
188     return true;
189 
190   if (Sec.sh_addr < Phdr.p_vaddr)
191     return false;
192 
193   bool IsTbss =
194       (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
195   // .tbss is special, it only has memory in PT_TLS and has NOBITS properties.
196   bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;
197   // Only non-empty sections can be at the end of a segment.
198   if (Sec.sh_size == 0 || IsTbssInNonTLS)
199     return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;
200   return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;
201 }
202 
203 template <class ELFT>
204 bool isSectionInSegment(const typename ELFT::Phdr &Phdr,
205                         const typename ELFT::Shdr &Sec) {
206   return checkSectionOffsets<ELFT>(Phdr, Sec) &&
207          checkSectionVMA<ELFT>(Phdr, Sec);
208 }
209 
210 template <class ELFT>
211 class ELFFile {
212 public:
213   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
214 
215   // This is a callback that can be passed to a number of functions.
216   // It can be used to ignore non-critical errors (warnings), which is
217   // useful for dumpers, like llvm-readobj.
218   // It accepts a warning message string and returns a success
219   // when the warning should be ignored or an error otherwise.
220   using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
221 
222   const uint8_t *base() const { return Buf.bytes_begin(); }
223   const uint8_t *end() const { return base() + getBufSize(); }
224 
225   size_t getBufSize() const { return Buf.size(); }
226 
227 private:
228   StringRef Buf;
229   std::vector<Elf_Shdr> FakeSections;
230   SmallString<0> FakeSectionStrings;
231 
232   ELFFile(StringRef Object);
233 
234 public:
235   const Elf_Ehdr &getHeader() const {
236     return *reinterpret_cast<const Elf_Ehdr *>(base());
237   }
238 
239   template <typename T>
240   Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
241   template <typename T>
242   Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
243 
244   Expected<std::vector<VerDef>>
245   getVersionDefinitions(const Elf_Shdr &Sec) const;
246   Expected<std::vector<VerNeed>> getVersionDependencies(
247       const Elf_Shdr &Sec,
248       WarningHandler WarnHandler = &defaultWarningHandler) const;
249   Expected<StringRef> getSymbolVersionByIndex(
250       uint32_t SymbolVersionIndex, bool &IsDefault,
251       SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
252       std::optional<bool> IsSymHidden) const;
253 
254   Expected<StringRef>
255   getStringTable(const Elf_Shdr &Section,
256                  WarningHandler WarnHandler = &defaultWarningHandler) const;
257   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
258   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
259                                               Elf_Shdr_Range Sections) const;
260   Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
261 
262   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
263   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
264                                              Elf_Shdr_Range Sections) const;
265 
266   Expected<uint64_t> getDynSymtabSize() const;
267 
268   StringRef getRelocationTypeName(uint32_t Type) const;
269   void getRelocationTypeName(uint32_t Type,
270                              SmallVectorImpl<char> &Result) const;
271   uint32_t getRelativeRelocationType() const;
272 
273   std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
274   std::string getDynamicTagAsString(uint64_t Type) const;
275 
276   /// Get the symbol for a given relocation.
277   Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
278                                                 const Elf_Shdr *SymTab) const;
279 
280   Expected<SmallVector<std::optional<VersionEntry>, 0>>
281   loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
282 
283   static Expected<ELFFile> create(StringRef Object);
284 
285   bool isLE() const {
286     return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
287   }
288 
289   bool isMipsELF64() const {
290     return getHeader().e_machine == ELF::EM_MIPS &&
291            getHeader().getFileClass() == ELF::ELFCLASS64;
292   }
293 
294   bool isMips64EL() const { return isMipsELF64() && isLE(); }
295 
296   Expected<Elf_Shdr_Range> sections() const;
297 
298   Expected<Elf_Dyn_Range> dynamicEntries() const;
299 
300   Expected<const uint8_t *>
301   toMappedAddr(uint64_t VAddr,
302                WarningHandler WarnHandler = &defaultWarningHandler) const;
303 
304   Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
305     if (!Sec)
306       return ArrayRef<Elf_Sym>(nullptr, nullptr);
307     return getSectionContentsAsArray<Elf_Sym>(*Sec);
308   }
309 
310   Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
311     return getSectionContentsAsArray<Elf_Rela>(Sec);
312   }
313 
314   Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
315     return getSectionContentsAsArray<Elf_Rel>(Sec);
316   }
317 
318   Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
319     return getSectionContentsAsArray<Elf_Relr>(Sec);
320   }
321 
322   std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
323 
324   Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
325 
326   /// Iterate over program header table.
327   Expected<Elf_Phdr_Range> program_headers() const {
328     if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
329       return createError("invalid e_phentsize: " +
330                          Twine(getHeader().e_phentsize));
331 
332     uint64_t HeadersSize =
333         (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
334     uint64_t PhOff = getHeader().e_phoff;
335     if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
336       return createError("program headers are longer than binary of size " +
337                          Twine(getBufSize()) + ": e_phoff = 0x" +
338                          Twine::utohexstr(getHeader().e_phoff) +
339                          ", e_phnum = " + Twine(getHeader().e_phnum) +
340                          ", e_phentsize = " + Twine(getHeader().e_phentsize));
341 
342     auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
343     return ArrayRef(Begin, Begin + getHeader().e_phnum);
344   }
345 
346   /// Get an iterator over notes in a program header.
347   ///
348   /// The program header must be of type \c PT_NOTE.
349   ///
350   /// \param Phdr the program header to iterate over.
351   /// \param Err [out] an error to support fallible iteration, which should
352   ///  be checked after iteration ends.
353   Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
354     assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
355     ErrorAsOutParameter ErrAsOutParam(&Err);
356     if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
357       Err =
358           createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
359                       ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
360       return Elf_Note_Iterator(Err);
361     }
362     // Allow 4, 8, and (for Linux core dumps) 0.
363     // TODO: Disallow 1 after all tests are fixed.
364     if (Phdr.p_align != 0 && Phdr.p_align != 1 && Phdr.p_align != 4 &&
365         Phdr.p_align != 8) {
366       Err =
367           createError("alignment (" + Twine(Phdr.p_align) + ") is not 4 or 8");
368       return Elf_Note_Iterator(Err);
369     }
370     return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz,
371                              std::max<size_t>(Phdr.p_align, 4), Err);
372   }
373 
374   /// Get an iterator over notes in a section.
375   ///
376   /// The section must be of type \c SHT_NOTE.
377   ///
378   /// \param Shdr the section to iterate over.
379   /// \param Err [out] an error to support fallible iteration, which should
380   ///  be checked after iteration ends.
381   Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
382     assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
383     ErrorAsOutParameter ErrAsOutParam(&Err);
384     if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
385       Err =
386           createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
387                       ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
388       return Elf_Note_Iterator(Err);
389     }
390     // TODO: Allow just 4 and 8 after all tests are fixed.
391     if (Shdr.sh_addralign != 0 && Shdr.sh_addralign != 1 &&
392         Shdr.sh_addralign != 4 && Shdr.sh_addralign != 8) {
393       Err = createError("alignment (" + Twine(Shdr.sh_addralign) +
394                         ") is not 4 or 8");
395       return Elf_Note_Iterator(Err);
396     }
397     return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size,
398                              std::max<size_t>(Shdr.sh_addralign, 4), Err);
399   }
400 
401   /// Get the end iterator for notes.
402   Elf_Note_Iterator notes_end() const {
403     return Elf_Note_Iterator();
404   }
405 
406   /// Get an iterator range over notes of a program header.
407   ///
408   /// The program header must be of type \c PT_NOTE.
409   ///
410   /// \param Phdr the program header to iterate over.
411   /// \param Err [out] an error to support fallible iteration, which should
412   ///  be checked after iteration ends.
413   iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
414                                           Error &Err) const {
415     return make_range(notes_begin(Phdr, Err), notes_end());
416   }
417 
418   /// Get an iterator range over notes of a section.
419   ///
420   /// The section must be of type \c SHT_NOTE.
421   ///
422   /// \param Shdr the section to iterate over.
423   /// \param Err [out] an error to support fallible iteration, which should
424   ///  be checked after iteration ends.
425   iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
426                                           Error &Err) const {
427     return make_range(notes_begin(Shdr, Err), notes_end());
428   }
429 
430   Expected<StringRef> getSectionStringTable(
431       Elf_Shdr_Range Sections,
432       WarningHandler WarnHandler = &defaultWarningHandler) const;
433   Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
434                                      DataRegion<Elf_Word> ShndxTable) const;
435   Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
436                                         const Elf_Shdr *SymTab,
437                                         DataRegion<Elf_Word> ShndxTable) const;
438   Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
439                                         Elf_Sym_Range Symtab,
440                                         DataRegion<Elf_Word> ShndxTable) const;
441   Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
442 
443   Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
444                                       uint32_t Index) const;
445 
446   Expected<StringRef>
447   getSectionName(const Elf_Shdr &Section,
448                  WarningHandler WarnHandler = &defaultWarningHandler) const;
449   Expected<StringRef> getSectionName(const Elf_Shdr &Section,
450                                      StringRef DotShstrtab) const;
451   template <typename T>
452   Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
453   Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
454   Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
455 
456   /// Returns a vector of BBAddrMap structs corresponding to each function
457   /// within the text section that the SHT_LLVM_BB_ADDR_MAP section \p Sec
458   /// is associated with. If the current ELFFile is relocatable, a corresponding
459   /// \p RelaSec must be passed in as an argument.
460   /// Optional out variable to collect all PGO Analyses. New elements are only
461   /// added if no error occurs. If not provided, the PGO Analyses are decoded
462   /// then ignored.
463   Expected<std::vector<BBAddrMap>>
464   decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr,
465                   std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr) const;
466 
467   /// Returns a map from every section matching \p IsMatch to its relocation
468   /// section, or \p nullptr if it has no relocation section. This function
469   /// returns an error if any of the \p IsMatch calls fail or if it fails to
470   /// retrieve the content section of any relocation section.
471   Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>>
472   getSectionAndRelocations(
473       std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const;
474 
475   void createFakeSections();
476 };
477 
478 using ELF32LEFile = ELFFile<ELF32LE>;
479 using ELF64LEFile = ELFFile<ELF64LE>;
480 using ELF32BEFile = ELFFile<ELF32BE>;
481 using ELF64BEFile = ELFFile<ELF64BE>;
482 
483 template <class ELFT>
484 inline Expected<const typename ELFT::Shdr *>
485 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
486   if (Index >= Sections.size())
487     return createError("invalid section index: " + Twine(Index));
488   return &Sections[Index];
489 }
490 
491 template <class ELFT>
492 inline Expected<uint32_t>
493 getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
494                             DataRegion<typename ELFT::Word> ShndxTable) {
495   assert(Sym.st_shndx == ELF::SHN_XINDEX);
496   if (!ShndxTable.First)
497     return createError(
498         "found an extended symbol index (" + Twine(SymIndex) +
499         "), but unable to locate the extended symbol index table");
500 
501   Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
502   if (!TableOrErr)
503     return createError("unable to read an extended symbol table at index " +
504                        Twine(SymIndex) + ": " +
505                        toString(TableOrErr.takeError()));
506   return *TableOrErr;
507 }
508 
509 template <class ELFT>
510 Expected<uint32_t>
511 ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
512                                DataRegion<Elf_Word> ShndxTable) const {
513   uint32_t Index = Sym.st_shndx;
514   if (Index == ELF::SHN_XINDEX) {
515     Expected<uint32_t> ErrorOrIndex =
516         getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
517     if (!ErrorOrIndex)
518       return ErrorOrIndex.takeError();
519     return *ErrorOrIndex;
520   }
521   if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
522     return 0;
523   return Index;
524 }
525 
526 template <class ELFT>
527 Expected<const typename ELFT::Shdr *>
528 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
529                           DataRegion<Elf_Word> ShndxTable) const {
530   auto SymsOrErr = symbols(SymTab);
531   if (!SymsOrErr)
532     return SymsOrErr.takeError();
533   return getSection(Sym, *SymsOrErr, ShndxTable);
534 }
535 
536 template <class ELFT>
537 Expected<const typename ELFT::Shdr *>
538 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
539                           DataRegion<Elf_Word> ShndxTable) const {
540   auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
541   if (!IndexOrErr)
542     return IndexOrErr.takeError();
543   uint32_t Index = *IndexOrErr;
544   if (Index == 0)
545     return nullptr;
546   return getSection(Index);
547 }
548 
549 template <class ELFT>
550 Expected<const typename ELFT::Sym *>
551 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
552   auto SymsOrErr = symbols(Sec);
553   if (!SymsOrErr)
554     return SymsOrErr.takeError();
555 
556   Elf_Sym_Range Symbols = *SymsOrErr;
557   if (Index >= Symbols.size())
558     return createError("unable to get symbol from section " +
559                        getSecIndexForError(*this, *Sec) +
560                        ": invalid symbol index (" + Twine(Index) + ")");
561   return &Symbols[Index];
562 }
563 
564 template <class ELFT>
565 template <typename T>
566 Expected<ArrayRef<T>>
567 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
568   if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
569     return createError("section " + getSecIndexForError(*this, Sec) +
570                        " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
571                        ", but got " + Twine(Sec.sh_entsize));
572 
573   uintX_t Offset = Sec.sh_offset;
574   uintX_t Size = Sec.sh_size;
575 
576   if (Size % sizeof(T))
577     return createError("section " + getSecIndexForError(*this, Sec) +
578                        " has an invalid sh_size (" + Twine(Size) +
579                        ") which is not a multiple of its sh_entsize (" +
580                        Twine(Sec.sh_entsize) + ")");
581   if (std::numeric_limits<uintX_t>::max() - Offset < Size)
582     return createError("section " + getSecIndexForError(*this, Sec) +
583                        " has a sh_offset (0x" + Twine::utohexstr(Offset) +
584                        ") + sh_size (0x" + Twine::utohexstr(Size) +
585                        ") that cannot be represented");
586   if (Offset + Size > Buf.size())
587     return createError("section " + getSecIndexForError(*this, Sec) +
588                        " has a sh_offset (0x" + Twine::utohexstr(Offset) +
589                        ") + sh_size (0x" + Twine::utohexstr(Size) +
590                        ") that is greater than the file size (0x" +
591                        Twine::utohexstr(Buf.size()) + ")");
592 
593   if (Offset % alignof(T))
594     // TODO: this error is untested.
595     return createError("unaligned data");
596 
597   const T *Start = reinterpret_cast<const T *>(base() + Offset);
598   return ArrayRef(Start, Size / sizeof(T));
599 }
600 
601 template <class ELFT>
602 Expected<ArrayRef<uint8_t>>
603 ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
604   uintX_t Offset = Phdr.p_offset;
605   uintX_t Size = Phdr.p_filesz;
606 
607   if (std::numeric_limits<uintX_t>::max() - Offset < Size)
608     return createError("program header " + getPhdrIndexForError(*this, Phdr) +
609                        " has a p_offset (0x" + Twine::utohexstr(Offset) +
610                        ") + p_filesz (0x" + Twine::utohexstr(Size) +
611                        ") that cannot be represented");
612   if (Offset + Size > Buf.size())
613     return createError("program header  " + getPhdrIndexForError(*this, Phdr) +
614                        " has a p_offset (0x" + Twine::utohexstr(Offset) +
615                        ") + p_filesz (0x" + Twine::utohexstr(Size) +
616                        ") that is greater than the file size (0x" +
617                        Twine::utohexstr(Buf.size()) + ")");
618   return ArrayRef(base() + Offset, Size);
619 }
620 
621 template <class ELFT>
622 Expected<ArrayRef<uint8_t>>
623 ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
624   return getSectionContentsAsArray<uint8_t>(Sec);
625 }
626 
627 template <class ELFT>
628 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
629   return getELFRelocationTypeName(getHeader().e_machine, Type);
630 }
631 
632 template <class ELFT>
633 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
634                                           SmallVectorImpl<char> &Result) const {
635   if (!isMipsELF64()) {
636     StringRef Name = getRelocationTypeName(Type);
637     Result.append(Name.begin(), Name.end());
638   } else {
639     // The Mips N64 ABI allows up to three operations to be specified per
640     // relocation record. Unfortunately there's no easy way to test for the
641     // presence of N64 ELFs as they have no special flag that identifies them
642     // as being N64. We can safely assume at the moment that all Mips
643     // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
644     // information to disambiguate between old vs new ABIs.
645     uint8_t Type1 = (Type >> 0) & 0xFF;
646     uint8_t Type2 = (Type >> 8) & 0xFF;
647     uint8_t Type3 = (Type >> 16) & 0xFF;
648 
649     // Concat all three relocation type names.
650     StringRef Name = getRelocationTypeName(Type1);
651     Result.append(Name.begin(), Name.end());
652 
653     Name = getRelocationTypeName(Type2);
654     Result.append(1, '/');
655     Result.append(Name.begin(), Name.end());
656 
657     Name = getRelocationTypeName(Type3);
658     Result.append(1, '/');
659     Result.append(Name.begin(), Name.end());
660   }
661 }
662 
663 template <class ELFT>
664 uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
665   return getELFRelativeRelocationType(getHeader().e_machine);
666 }
667 
668 template <class ELFT>
669 Expected<SmallVector<std::optional<VersionEntry>, 0>>
670 ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
671                               const Elf_Shdr *VerDefSec) const {
672   SmallVector<std::optional<VersionEntry>, 0> VersionMap;
673 
674   // The first two version indexes are reserved.
675   // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL.
676   VersionMap.push_back(VersionEntry());
677   VersionMap.push_back(VersionEntry());
678 
679   auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
680     if (N >= VersionMap.size())
681       VersionMap.resize(N + 1);
682     VersionMap[N] = {std::string(Version), IsVerdef};
683   };
684 
685   if (VerDefSec) {
686     Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
687     if (!Defs)
688       return Defs.takeError();
689     for (const VerDef &Def : *Defs)
690       InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
691   }
692 
693   if (VerNeedSec) {
694     Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
695     if (!Deps)
696       return Deps.takeError();
697     for (const VerNeed &Dep : *Deps)
698       for (const VernAux &Aux : Dep.AuxV)
699         InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
700   }
701 
702   return VersionMap;
703 }
704 
705 template <class ELFT>
706 Expected<const typename ELFT::Sym *>
707 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
708                                    const Elf_Shdr *SymTab) const {
709   uint32_t Index = Rel.getSymbol(isMips64EL());
710   if (Index == 0)
711     return nullptr;
712   return getEntry<Elf_Sym>(*SymTab, Index);
713 }
714 
715 template <class ELFT>
716 Expected<StringRef>
717 ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
718                                      WarningHandler WarnHandler) const {
719   uint32_t Index = getHeader().e_shstrndx;
720   if (Index == ELF::SHN_XINDEX) {
721     // If the section name string table section index is greater than
722     // or equal to SHN_LORESERVE, then the actual index of the section name
723     // string table section is contained in the sh_link field of the section
724     // header at index 0.
725     if (Sections.empty())
726       return createError(
727           "e_shstrndx == SHN_XINDEX, but the section header table is empty");
728 
729     Index = Sections[0].sh_link;
730   }
731 
732   // There is no section name string table. Return FakeSectionStrings which
733   // is non-empty if we have created fake sections.
734   if (!Index)
735     return FakeSectionStrings;
736 
737   if (Index >= Sections.size())
738     return createError("section header string table index " + Twine(Index) +
739                        " does not exist");
740   return getStringTable(Sections[Index], WarnHandler);
741 }
742 
743 /// This function finds the number of dynamic symbols using a GNU hash table.
744 ///
745 /// @param Table The GNU hash table for .dynsym.
746 template <class ELFT>
747 static Expected<uint64_t>
748 getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
749                             const void *BufEnd) {
750   using Elf_Word = typename ELFT::Word;
751   if (Table.nbuckets == 0)
752     return Table.symndx + 1;
753   uint64_t LastSymIdx = 0;
754   // Find the index of the first symbol in the last chain.
755   for (Elf_Word Val : Table.buckets())
756     LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
757   const Elf_Word *It =
758       reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
759   // Locate the end of the chain to find the last symbol index.
760   while (It < BufEnd && (*It & 1) == 0) {
761     ++LastSymIdx;
762     ++It;
763   }
764   if (It >= BufEnd) {
765     return createStringError(
766         object_error::parse_failed,
767         "no terminator found for GNU hash section before buffer end");
768   }
769   return LastSymIdx + 1;
770 }
771 
772 /// This function determines the number of dynamic symbols. It reads section
773 /// headers first. If section headers are not available, the number of
774 /// symbols will be inferred by parsing dynamic hash tables.
775 template <class ELFT>
776 Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
777   // Read .dynsym section header first if available.
778   Expected<Elf_Shdr_Range> SectionsOrError = sections();
779   if (!SectionsOrError)
780     return SectionsOrError.takeError();
781   for (const Elf_Shdr &Sec : *SectionsOrError) {
782     if (Sec.sh_type == ELF::SHT_DYNSYM) {
783       if (Sec.sh_size % Sec.sh_entsize != 0) {
784         return createStringError(object_error::parse_failed,
785                                  "SHT_DYNSYM section has sh_size (" +
786                                      Twine(Sec.sh_size) + ") % sh_entsize (" +
787                                      Twine(Sec.sh_entsize) + ") that is not 0");
788       }
789       return Sec.sh_size / Sec.sh_entsize;
790     }
791   }
792 
793   if (!SectionsOrError->empty()) {
794     // Section headers are available but .dynsym header is not found.
795     // Return 0 as .dynsym does not exist.
796     return 0;
797   }
798 
799   // Section headers do not exist. Falling back to infer
800   // upper bound of .dynsym from .gnu.hash and .hash.
801   Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
802   if (!DynTable)
803     return DynTable.takeError();
804   std::optional<uint64_t> ElfHash;
805   std::optional<uint64_t> ElfGnuHash;
806   for (const Elf_Dyn &Entry : *DynTable) {
807     switch (Entry.d_tag) {
808     case ELF::DT_HASH:
809       ElfHash = Entry.d_un.d_ptr;
810       break;
811     case ELF::DT_GNU_HASH:
812       ElfGnuHash = Entry.d_un.d_ptr;
813       break;
814     }
815   }
816   if (ElfGnuHash) {
817     Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
818     if (!TablePtr)
819       return TablePtr.takeError();
820     const Elf_GnuHash *Table =
821         reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
822     return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
823   }
824 
825   // Search SYSV hash table to try to find the upper bound of dynsym.
826   if (ElfHash) {
827     Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
828     if (!TablePtr)
829       return TablePtr.takeError();
830     const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
831     return Table->nchain;
832   }
833   return 0;
834 }
835 
836 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
837 
838 template <class ELFT>
839 Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
840   if (sizeof(Elf_Ehdr) > Object.size())
841     return createError("invalid buffer: the size (" + Twine(Object.size()) +
842                        ") is smaller than an ELF header (" +
843                        Twine(sizeof(Elf_Ehdr)) + ")");
844   return ELFFile(Object);
845 }
846 
847 /// Used by llvm-objdump -d (which needs sections for disassembly) to
848 /// disassemble objects without a section header table (e.g. ET_CORE objects
849 /// analyzed by linux perf or ET_EXEC with llvm-strip --strip-sections).
850 template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
851   if (!FakeSections.empty())
852     return;
853   auto PhdrsOrErr = program_headers();
854   if (!PhdrsOrErr)
855     return;
856 
857   FakeSectionStrings += '\0';
858   for (auto [Idx, Phdr] : llvm::enumerate(*PhdrsOrErr)) {
859     if (Phdr.p_type != ELF::PT_LOAD || !(Phdr.p_flags & ELF::PF_X))
860       continue;
861     Elf_Shdr FakeShdr = {};
862     FakeShdr.sh_type = ELF::SHT_PROGBITS;
863     FakeShdr.sh_flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
864     FakeShdr.sh_addr = Phdr.p_vaddr;
865     FakeShdr.sh_size = Phdr.p_memsz;
866     FakeShdr.sh_offset = Phdr.p_offset;
867     // Create a section name based on the p_type and index.
868     FakeShdr.sh_name = FakeSectionStrings.size();
869     FakeSectionStrings += ("PT_LOAD#" + Twine(Idx)).str();
870     FakeSectionStrings += '\0';
871     FakeSections.push_back(FakeShdr);
872   }
873 }
874 
875 template <class ELFT>
876 Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
877   const uintX_t SectionTableOffset = getHeader().e_shoff;
878   if (SectionTableOffset == 0) {
879     if (!FakeSections.empty())
880       return ArrayRef(FakeSections.data(), FakeSections.size());
881     return ArrayRef<Elf_Shdr>();
882   }
883 
884   if (getHeader().e_shentsize != sizeof(Elf_Shdr))
885     return createError("invalid e_shentsize in ELF header: " +
886                        Twine(getHeader().e_shentsize));
887 
888   const uint64_t FileSize = Buf.size();
889   if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
890       SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
891     return createError(
892         "section header table goes past the end of the file: e_shoff = 0x" +
893         Twine::utohexstr(SectionTableOffset));
894 
895   // Invalid address alignment of section headers
896   if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
897     // TODO: this error is untested.
898     return createError("invalid alignment of section headers");
899 
900   const Elf_Shdr *First =
901       reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
902 
903   uintX_t NumSections = getHeader().e_shnum;
904   if (NumSections == 0)
905     NumSections = First->sh_size;
906 
907   if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
908     return createError("invalid number of sections specified in the NULL "
909                        "section's sh_size field (" +
910                        Twine(NumSections) + ")");
911 
912   const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
913   if (SectionTableOffset + SectionTableSize < SectionTableOffset)
914     return createError(
915         "invalid section header table offset (e_shoff = 0x" +
916         Twine::utohexstr(SectionTableOffset) +
917         ") or invalid number of sections specified in the first section "
918         "header's sh_size field (0x" +
919         Twine::utohexstr(NumSections) + ")");
920 
921   // Section table goes past end of file!
922   if (SectionTableOffset + SectionTableSize > FileSize)
923     return createError("section table goes past the end of file");
924   return ArrayRef(First, NumSections);
925 }
926 
927 template <class ELFT>
928 template <typename T>
929 Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
930                                             uint32_t Entry) const {
931   auto SecOrErr = getSection(Section);
932   if (!SecOrErr)
933     return SecOrErr.takeError();
934   return getEntry<T>(**SecOrErr, Entry);
935 }
936 
937 template <class ELFT>
938 template <typename T>
939 Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
940                                             uint32_t Entry) const {
941   Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
942   if (!EntriesOrErr)
943     return EntriesOrErr.takeError();
944 
945   ArrayRef<T> Arr = *EntriesOrErr;
946   if (Entry >= Arr.size())
947     return createError(
948         "can't read an entry at 0x" +
949         Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
950         ": it goes past the end of the section (0x" +
951         Twine::utohexstr(Section.sh_size) + ")");
952   return &Arr[Entry];
953 }
954 
955 template <typename ELFT>
956 Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
957     uint32_t SymbolVersionIndex, bool &IsDefault,
958     SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
959     std::optional<bool> IsSymHidden) const {
960   size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
961 
962   // Special markers for unversioned symbols.
963   if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
964       VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
965     IsDefault = false;
966     return "";
967   }
968 
969   // Lookup this symbol in the version table.
970   if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
971     return createError("SHT_GNU_versym section refers to a version index " +
972                        Twine(VersionIndex) + " which is missing");
973 
974   const VersionEntry &Entry = *VersionMap[VersionIndex];
975   // A default version (@@) is only available for defined symbols.
976   if (!Entry.IsVerDef || IsSymHidden.value_or(false))
977     IsDefault = false;
978   else
979     IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
980   return Entry.Name.c_str();
981 }
982 
983 template <class ELFT>
984 Expected<std::vector<VerDef>>
985 ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
986   Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
987   if (!StrTabOrErr)
988     return StrTabOrErr.takeError();
989 
990   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
991   if (!ContentsOrErr)
992     return createError("cannot read content of " + describe(*this, Sec) + ": " +
993                        toString(ContentsOrErr.takeError()));
994 
995   const uint8_t *Start = ContentsOrErr->data();
996   const uint8_t *End = Start + ContentsOrErr->size();
997 
998   auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
999                             unsigned VerDefNdx) -> Expected<VerdAux> {
1000     if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
1001       return createError("invalid " + describe(*this, Sec) +
1002                          ": version definition " + Twine(VerDefNdx) +
1003                          " refers to an auxiliary entry that goes past the end "
1004                          "of the section");
1005 
1006     auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
1007     VerdauxBuf += Verdaux->vda_next;
1008 
1009     VerdAux Aux;
1010     Aux.Offset = VerdauxBuf - Start;
1011     if (Verdaux->vda_name <= StrTabOrErr->size())
1012       Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
1013     else
1014       Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
1015     return Aux;
1016   };
1017 
1018   std::vector<VerDef> Ret;
1019   const uint8_t *VerdefBuf = Start;
1020   for (unsigned I = 1; I <= /*VerDefsNum=*/Sec.sh_info; ++I) {
1021     if (VerdefBuf + sizeof(Elf_Verdef) > End)
1022       return createError("invalid " + describe(*this, Sec) +
1023                          ": version definition " + Twine(I) +
1024                          " goes past the end of the section");
1025 
1026     if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
1027       return createError(
1028           "invalid " + describe(*this, Sec) +
1029           ": found a misaligned version definition entry at offset 0x" +
1030           Twine::utohexstr(VerdefBuf - Start));
1031 
1032     unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
1033     if (Version != 1)
1034       return createError("unable to dump " + describe(*this, Sec) +
1035                          ": version " + Twine(Version) +
1036                          " is not yet supported");
1037 
1038     const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
1039     VerDef &VD = *Ret.emplace(Ret.end());
1040     VD.Offset = VerdefBuf - Start;
1041     VD.Version = D->vd_version;
1042     VD.Flags = D->vd_flags;
1043     VD.Ndx = D->vd_ndx;
1044     VD.Cnt = D->vd_cnt;
1045     VD.Hash = D->vd_hash;
1046 
1047     const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
1048     for (unsigned J = 0; J < D->vd_cnt; ++J) {
1049       if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
1050         return createError("invalid " + describe(*this, Sec) +
1051                            ": found a misaligned auxiliary entry at offset 0x" +
1052                            Twine::utohexstr(VerdauxBuf - Start));
1053 
1054       Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
1055       if (!AuxOrErr)
1056         return AuxOrErr.takeError();
1057 
1058       if (J == 0)
1059         VD.Name = AuxOrErr->Name;
1060       else
1061         VD.AuxV.push_back(*AuxOrErr);
1062     }
1063 
1064     VerdefBuf += D->vd_next;
1065   }
1066 
1067   return Ret;
1068 }
1069 
1070 template <class ELFT>
1071 Expected<std::vector<VerNeed>>
1072 ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
1073                                       WarningHandler WarnHandler) const {
1074   StringRef StrTab;
1075   Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
1076   if (!StrTabOrErr) {
1077     if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
1078       return std::move(E);
1079   } else {
1080     StrTab = *StrTabOrErr;
1081   }
1082 
1083   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
1084   if (!ContentsOrErr)
1085     return createError("cannot read content of " + describe(*this, Sec) + ": " +
1086                        toString(ContentsOrErr.takeError()));
1087 
1088   const uint8_t *Start = ContentsOrErr->data();
1089   const uint8_t *End = Start + ContentsOrErr->size();
1090   const uint8_t *VerneedBuf = Start;
1091 
1092   std::vector<VerNeed> Ret;
1093   for (unsigned I = 1; I <= /*VerneedNum=*/Sec.sh_info; ++I) {
1094     if (VerneedBuf + sizeof(Elf_Verdef) > End)
1095       return createError("invalid " + describe(*this, Sec) +
1096                          ": version dependency " + Twine(I) +
1097                          " goes past the end of the section");
1098 
1099     if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
1100       return createError(
1101           "invalid " + describe(*this, Sec) +
1102           ": found a misaligned version dependency entry at offset 0x" +
1103           Twine::utohexstr(VerneedBuf - Start));
1104 
1105     unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
1106     if (Version != 1)
1107       return createError("unable to dump " + describe(*this, Sec) +
1108                          ": version " + Twine(Version) +
1109                          " is not yet supported");
1110 
1111     const Elf_Verneed *Verneed =
1112         reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
1113 
1114     VerNeed &VN = *Ret.emplace(Ret.end());
1115     VN.Version = Verneed->vn_version;
1116     VN.Cnt = Verneed->vn_cnt;
1117     VN.Offset = VerneedBuf - Start;
1118 
1119     if (Verneed->vn_file < StrTab.size())
1120       VN.File = std::string(StrTab.data() + Verneed->vn_file);
1121     else
1122       VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
1123 
1124     const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
1125     for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
1126       if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
1127         return createError("invalid " + describe(*this, Sec) +
1128                            ": found a misaligned auxiliary entry at offset 0x" +
1129                            Twine::utohexstr(VernauxBuf - Start));
1130 
1131       if (VernauxBuf + sizeof(Elf_Vernaux) > End)
1132         return createError(
1133             "invalid " + describe(*this, Sec) + ": version dependency " +
1134             Twine(I) +
1135             " refers to an auxiliary entry that goes past the end "
1136             "of the section");
1137 
1138       const Elf_Vernaux *Vernaux =
1139           reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
1140 
1141       VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
1142       Aux.Hash = Vernaux->vna_hash;
1143       Aux.Flags = Vernaux->vna_flags;
1144       Aux.Other = Vernaux->vna_other;
1145       Aux.Offset = VernauxBuf - Start;
1146       if (StrTab.size() <= Vernaux->vna_name)
1147         Aux.Name = "<corrupt>";
1148       else
1149         Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
1150 
1151       VernauxBuf += Vernaux->vna_next;
1152     }
1153     VerneedBuf += Verneed->vn_next;
1154   }
1155   return Ret;
1156 }
1157 
1158 template <class ELFT>
1159 Expected<const typename ELFT::Shdr *>
1160 ELFFile<ELFT>::getSection(uint32_t Index) const {
1161   auto TableOrErr = sections();
1162   if (!TableOrErr)
1163     return TableOrErr.takeError();
1164   return object::getSection<ELFT>(*TableOrErr, Index);
1165 }
1166 
1167 template <class ELFT>
1168 Expected<StringRef>
1169 ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
1170                               WarningHandler WarnHandler) const {
1171   if (Section.sh_type != ELF::SHT_STRTAB)
1172     if (Error E = WarnHandler("invalid sh_type for string table section " +
1173                               getSecIndexForError(*this, Section) +
1174                               ": expected SHT_STRTAB, but got " +
1175                               object::getELFSectionTypeName(
1176                                   getHeader().e_machine, Section.sh_type)))
1177       return std::move(E);
1178 
1179   auto V = getSectionContentsAsArray<char>(Section);
1180   if (!V)
1181     return V.takeError();
1182   ArrayRef<char> Data = *V;
1183   if (Data.empty())
1184     return createError("SHT_STRTAB string table section " +
1185                        getSecIndexForError(*this, Section) + " is empty");
1186   if (Data.back() != '\0')
1187     return createError("SHT_STRTAB string table section " +
1188                        getSecIndexForError(*this, Section) +
1189                        " is non-null terminated");
1190   return StringRef(Data.begin(), Data.size());
1191 }
1192 
1193 template <class ELFT>
1194 Expected<ArrayRef<typename ELFT::Word>>
1195 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
1196   auto SectionsOrErr = sections();
1197   if (!SectionsOrErr)
1198     return SectionsOrErr.takeError();
1199   return getSHNDXTable(Section, *SectionsOrErr);
1200 }
1201 
1202 template <class ELFT>
1203 Expected<ArrayRef<typename ELFT::Word>>
1204 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
1205                              Elf_Shdr_Range Sections) const {
1206   assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
1207   auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
1208   if (!VOrErr)
1209     return VOrErr.takeError();
1210   ArrayRef<Elf_Word> V = *VOrErr;
1211   auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
1212   if (!SymTableOrErr)
1213     return SymTableOrErr.takeError();
1214   const Elf_Shdr &SymTable = **SymTableOrErr;
1215   if (SymTable.sh_type != ELF::SHT_SYMTAB &&
1216       SymTable.sh_type != ELF::SHT_DYNSYM)
1217     return createError(
1218         "SHT_SYMTAB_SHNDX section is linked with " +
1219         object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
1220         " section (expected SHT_SYMTAB/SHT_DYNSYM)");
1221 
1222   uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
1223   if (V.size() != Syms)
1224     return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
1225                        " entries, but the symbol table associated has " +
1226                        Twine(Syms));
1227 
1228   return V;
1229 }
1230 
1231 template <class ELFT>
1232 Expected<StringRef>
1233 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
1234   auto SectionsOrErr = sections();
1235   if (!SectionsOrErr)
1236     return SectionsOrErr.takeError();
1237   return getStringTableForSymtab(Sec, *SectionsOrErr);
1238 }
1239 
1240 template <class ELFT>
1241 Expected<StringRef>
1242 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
1243                                        Elf_Shdr_Range Sections) const {
1244 
1245   if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
1246     return createError(
1247         "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
1248   Expected<const Elf_Shdr *> SectionOrErr =
1249       object::getSection<ELFT>(Sections, Sec.sh_link);
1250   if (!SectionOrErr)
1251     return SectionOrErr.takeError();
1252   return getStringTable(**SectionOrErr);
1253 }
1254 
1255 template <class ELFT>
1256 Expected<StringRef>
1257 ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
1258   Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
1259       getSection(Sec.sh_link);
1260   if (!StrTabSecOrErr)
1261     return createError("invalid section linked to " + describe(*this, Sec) +
1262                        ": " + toString(StrTabSecOrErr.takeError()));
1263 
1264   Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
1265   if (!StrTabOrErr)
1266     return createError("invalid string table linked to " +
1267                        describe(*this, Sec) + ": " +
1268                        toString(StrTabOrErr.takeError()));
1269   return *StrTabOrErr;
1270 }
1271 
1272 template <class ELFT>
1273 Expected<StringRef>
1274 ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1275                               WarningHandler WarnHandler) const {
1276   auto SectionsOrErr = sections();
1277   if (!SectionsOrErr)
1278     return SectionsOrErr.takeError();
1279   auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
1280   if (!Table)
1281     return Table.takeError();
1282   return getSectionName(Section, *Table);
1283 }
1284 
1285 template <class ELFT>
1286 Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1287                                                   StringRef DotShstrtab) const {
1288   uint32_t Offset = Section.sh_name;
1289   if (Offset == 0)
1290     return StringRef();
1291   if (Offset >= DotShstrtab.size())
1292     return createError("a section " + getSecIndexForError(*this, Section) +
1293                        " has an invalid sh_name (0x" +
1294                        Twine::utohexstr(Offset) +
1295                        ") offset which goes past the end of the "
1296                        "section name string table");
1297   return StringRef(DotShstrtab.data() + Offset);
1298 }
1299 
1300 /// This function returns the hash value for a symbol in the .dynsym section
1301 /// Name of the API remains consistent as specified in the libelf
1302 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
1303 inline uint32_t hashSysV(StringRef SymbolName) {
1304   uint32_t H = 0;
1305   for (uint8_t C : SymbolName) {
1306     H = (H << 4) + C;
1307     H ^= (H >> 24) & 0xf0;
1308   }
1309   return H & 0x0fffffff;
1310 }
1311 
1312 /// This function returns the hash value for a symbol in the .dynsym section
1313 /// for the GNU hash table. The implementation is defined in the GNU hash ABI.
1314 /// REF : https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c#l222
1315 inline uint32_t hashGnu(StringRef Name) {
1316   uint32_t H = 5381;
1317   for (uint8_t C : Name)
1318     H = (H << 5) + H + C;
1319   return H;
1320 }
1321 
1322 } // end namespace object
1323 } // end namespace llvm
1324 
1325 #endif // LLVM_OBJECT_ELF_H
1326