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