OSDN Git Service

Change some StringRef::data() reinterpret_cast to bytes_begin() or arrayRefFromString...
[android-x86/external-llvm.git] / include / llvm / Object / ELF.h
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 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
34 uint32_t getELFRelativeRelocationType(uint32_t Machine);
35 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
36
37 // Subclasses of ELFFile may need this for template instantiation
38 inline std::pair<unsigned char, unsigned char>
39 getElfArchType(StringRef Object) {
40   if (Object.size() < ELF::EI_NIDENT)
41     return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
42                           (uint8_t)ELF::ELFDATANONE);
43   return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
44                         (uint8_t)Object[ELF::EI_DATA]);
45 }
46
47 static inline Error createError(StringRef Err) {
48   return make_error<StringError>(Err, object_error::parse_failed);
49 }
50
51 template <class ELFT>
52 class ELFFile {
53 public:
54   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
55   using uintX_t = typename ELFT::uint;
56   using Elf_Ehdr = typename ELFT::Ehdr;
57   using Elf_Shdr = typename ELFT::Shdr;
58   using Elf_Sym = typename ELFT::Sym;
59   using Elf_Dyn = typename ELFT::Dyn;
60   using Elf_Phdr = typename ELFT::Phdr;
61   using Elf_Rel = typename ELFT::Rel;
62   using Elf_Rela = typename ELFT::Rela;
63   using Elf_Relr = typename ELFT::Relr;
64   using Elf_Verdef = typename ELFT::Verdef;
65   using Elf_Verdaux = typename ELFT::Verdaux;
66   using Elf_Verneed = typename ELFT::Verneed;
67   using Elf_Vernaux = typename ELFT::Vernaux;
68   using Elf_Versym = typename ELFT::Versym;
69   using Elf_Hash = typename ELFT::Hash;
70   using Elf_GnuHash = typename ELFT::GnuHash;
71   using Elf_Nhdr = typename ELFT::Nhdr;
72   using Elf_Note = typename ELFT::Note;
73   using Elf_Note_Iterator = typename ELFT::NoteIterator;
74   using Elf_Dyn_Range = typename ELFT::DynRange;
75   using Elf_Shdr_Range = typename ELFT::ShdrRange;
76   using Elf_Sym_Range = typename ELFT::SymRange;
77   using Elf_Rel_Range = typename ELFT::RelRange;
78   using Elf_Rela_Range = typename ELFT::RelaRange;
79   using Elf_Relr_Range = typename ELFT::RelrRange;
80   using Elf_Phdr_Range = typename ELFT::PhdrRange;
81
82   const uint8_t *base() const { return Buf.bytes_begin(); }
83
84   size_t getBufSize() const { return Buf.size(); }
85
86 private:
87   StringRef Buf;
88
89   ELFFile(StringRef Object);
90
91 public:
92   const Elf_Ehdr *getHeader() const {
93     return reinterpret_cast<const Elf_Ehdr *>(base());
94   }
95
96   template <typename T>
97   Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
98   template <typename T>
99   Expected<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
100
101   Expected<StringRef> getStringTable(const Elf_Shdr *Section) const;
102   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
103   Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
104                                               Elf_Shdr_Range Sections) const;
105
106   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
107   Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
108                                              Elf_Shdr_Range Sections) const;
109
110   StringRef getRelocationTypeName(uint32_t Type) const;
111   void getRelocationTypeName(uint32_t Type,
112                              SmallVectorImpl<char> &Result) const;
113   uint32_t getRelativeRelocationType() const;
114
115   std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
116   std::string getDynamicTagAsString(uint64_t Type) const;
117
118   /// Get the symbol for a given relocation.
119   Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
120                                                 const Elf_Shdr *SymTab) const;
121
122   static Expected<ELFFile> create(StringRef Object);
123
124   bool isMipsELF64() const {
125     return getHeader()->e_machine == ELF::EM_MIPS &&
126            getHeader()->getFileClass() == ELF::ELFCLASS64;
127   }
128
129   bool isMips64EL() const {
130     return isMipsELF64() &&
131            getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
132   }
133
134   Expected<Elf_Shdr_Range> sections() const;
135
136   Expected<Elf_Dyn_Range> dynamicEntries() const;
137
138   Expected<const uint8_t *> toMappedAddr(uint64_t VAddr) const;
139
140   Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
141     if (!Sec)
142       return makeArrayRef<Elf_Sym>(nullptr, nullptr);
143     return getSectionContentsAsArray<Elf_Sym>(Sec);
144   }
145
146   Expected<Elf_Rela_Range> relas(const Elf_Shdr *Sec) const {
147     return getSectionContentsAsArray<Elf_Rela>(Sec);
148   }
149
150   Expected<Elf_Rel_Range> rels(const Elf_Shdr *Sec) const {
151     return getSectionContentsAsArray<Elf_Rel>(Sec);
152   }
153
154   Expected<Elf_Relr_Range> relrs(const Elf_Shdr *Sec) const {
155     return getSectionContentsAsArray<Elf_Relr>(Sec);
156   }
157
158   Expected<std::vector<Elf_Rela>> decode_relrs(Elf_Relr_Range relrs) const;
159
160   Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr *Sec) const;
161
162   /// Iterate over program header table.
163   Expected<Elf_Phdr_Range> program_headers() const {
164     if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
165       return createError("invalid e_phentsize");
166     if (getHeader()->e_phoff +
167             (getHeader()->e_phnum * getHeader()->e_phentsize) >
168         getBufSize())
169       return createError("program headers longer than binary");
170     auto *Begin =
171         reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
172     return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
173   }
174
175   /// Get an iterator over notes in a program header.
176   ///
177   /// The program header must be of type \c PT_NOTE.
178   ///
179   /// \param Phdr the program header to iterate over.
180   /// \param Err [out] an error to support fallible iteration, which should
181   ///  be checked after iteration ends.
182   Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
183     if (Phdr.p_type != ELF::PT_NOTE) {
184       Err = createError("attempt to iterate notes of non-note program header");
185       return Elf_Note_Iterator(Err);
186     }
187     if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
188       Err = createError("invalid program header offset/size");
189       return Elf_Note_Iterator(Err);
190     }
191     return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
192   }
193
194   /// Get an iterator over notes in a section.
195   ///
196   /// The section must be of type \c SHT_NOTE.
197   ///
198   /// \param Shdr the section to iterate over.
199   /// \param Err [out] an error to support fallible iteration, which should
200   ///  be checked after iteration ends.
201   Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
202     if (Shdr.sh_type != ELF::SHT_NOTE) {
203       Err = createError("attempt to iterate notes of non-note section");
204       return Elf_Note_Iterator(Err);
205     }
206     if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
207       Err = createError("invalid section offset/size");
208       return Elf_Note_Iterator(Err);
209     }
210     return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
211   }
212
213   /// Get the end iterator for notes.
214   Elf_Note_Iterator notes_end() const {
215     return Elf_Note_Iterator();
216   }
217
218   /// Get an iterator range over notes of a program header.
219   ///
220   /// The program header must be of type \c PT_NOTE.
221   ///
222   /// \param Phdr the program header to iterate over.
223   /// \param Err [out] an error to support fallible iteration, which should
224   ///  be checked after iteration ends.
225   iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
226                                           Error &Err) const {
227     return make_range(notes_begin(Phdr, Err), notes_end());
228   }
229
230   /// Get an iterator range over notes of a section.
231   ///
232   /// The section must be of type \c SHT_NOTE.
233   ///
234   /// \param Shdr the section to iterate over.
235   /// \param Err [out] an error to support fallible iteration, which should
236   ///  be checked after iteration ends.
237   iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
238                                           Error &Err) const {
239     return make_range(notes_begin(Shdr, Err), notes_end());
240   }
241
242   Expected<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
243   Expected<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
244                                      ArrayRef<Elf_Word> ShndxTable) const;
245   Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
246                                         const Elf_Shdr *SymTab,
247                                         ArrayRef<Elf_Word> ShndxTable) const;
248   Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
249                                         Elf_Sym_Range Symtab,
250                                         ArrayRef<Elf_Word> ShndxTable) const;
251   Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
252   Expected<const Elf_Shdr *> getSection(const StringRef SectionName) const;
253
254   Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
255                                       uint32_t Index) const;
256
257   Expected<StringRef> getSectionName(const Elf_Shdr *Section) const;
258   Expected<StringRef> getSectionName(const Elf_Shdr *Section,
259                                      StringRef DotShstrtab) const;
260   template <typename T>
261   Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
262   Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
263 };
264
265 using ELF32LEFile = ELFFile<ELF32LE>;
266 using ELF64LEFile = ELFFile<ELF64LE>;
267 using ELF32BEFile = ELFFile<ELF32BE>;
268 using ELF64BEFile = ELFFile<ELF64BE>;
269
270 template <class ELFT>
271 inline Expected<const typename ELFT::Shdr *>
272 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
273   if (Index >= Sections.size())
274     return createError("invalid section index");
275   return &Sections[Index];
276 }
277
278 template <class ELFT>
279 inline Expected<uint32_t>
280 getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
281                             const typename ELFT::Sym *FirstSym,
282                             ArrayRef<typename ELFT::Word> ShndxTable) {
283   assert(Sym->st_shndx == ELF::SHN_XINDEX);
284   unsigned Index = Sym - FirstSym;
285   if (Index >= ShndxTable.size())
286     return createError("index past the end of the symbol table");
287
288   // The size of the table was checked in getSHNDXTable.
289   return ShndxTable[Index];
290 }
291
292 template <class ELFT>
293 Expected<uint32_t>
294 ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
295                                ArrayRef<Elf_Word> ShndxTable) const {
296   uint32_t Index = Sym->st_shndx;
297   if (Index == ELF::SHN_XINDEX) {
298     auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
299         Sym, Syms.begin(), ShndxTable);
300     if (!ErrorOrIndex)
301       return ErrorOrIndex.takeError();
302     return *ErrorOrIndex;
303   }
304   if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
305     return 0;
306   return Index;
307 }
308
309 template <class ELFT>
310 Expected<const typename ELFT::Shdr *>
311 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
312                           ArrayRef<Elf_Word> ShndxTable) const {
313   auto SymsOrErr = symbols(SymTab);
314   if (!SymsOrErr)
315     return SymsOrErr.takeError();
316   return getSection(Sym, *SymsOrErr, ShndxTable);
317 }
318
319 template <class ELFT>
320 Expected<const typename ELFT::Shdr *>
321 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
322                           ArrayRef<Elf_Word> ShndxTable) const {
323   auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
324   if (!IndexOrErr)
325     return IndexOrErr.takeError();
326   uint32_t Index = *IndexOrErr;
327   if (Index == 0)
328     return nullptr;
329   return getSection(Index);
330 }
331
332 template <class ELFT>
333 inline Expected<const typename ELFT::Sym *>
334 getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
335   if (Index >= Symbols.size())
336     return createError("invalid symbol index");
337   return &Symbols[Index];
338 }
339
340 template <class ELFT>
341 Expected<const typename ELFT::Sym *>
342 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
343   auto SymtabOrErr = symbols(Sec);
344   if (!SymtabOrErr)
345     return SymtabOrErr.takeError();
346   return object::getSymbol<ELFT>(*SymtabOrErr, Index);
347 }
348
349 template <class ELFT>
350 template <typename T>
351 Expected<ArrayRef<T>>
352 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
353   if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
354     return createError("invalid sh_entsize");
355
356   uintX_t Offset = Sec->sh_offset;
357   uintX_t Size = Sec->sh_size;
358
359   if (Size % sizeof(T))
360     return createError("size is not a multiple of sh_entsize");
361   if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
362       Offset + Size > Buf.size())
363     return createError("invalid section offset");
364
365   if (Offset % alignof(T))
366     return createError("unaligned data");
367
368   const T *Start = reinterpret_cast<const T *>(base() + Offset);
369   return makeArrayRef(Start, Size / sizeof(T));
370 }
371
372 template <class ELFT>
373 Expected<ArrayRef<uint8_t>>
374 ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
375   return getSectionContentsAsArray<uint8_t>(Sec);
376 }
377
378 template <class ELFT>
379 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
380   return getELFRelocationTypeName(getHeader()->e_machine, Type);
381 }
382
383 template <class ELFT>
384 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
385                                           SmallVectorImpl<char> &Result) const {
386   if (!isMipsELF64()) {
387     StringRef Name = getRelocationTypeName(Type);
388     Result.append(Name.begin(), Name.end());
389   } else {
390     // The Mips N64 ABI allows up to three operations to be specified per
391     // relocation record. Unfortunately there's no easy way to test for the
392     // presence of N64 ELFs as they have no special flag that identifies them
393     // as being N64. We can safely assume at the moment that all Mips
394     // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
395     // information to disambiguate between old vs new ABIs.
396     uint8_t Type1 = (Type >> 0) & 0xFF;
397     uint8_t Type2 = (Type >> 8) & 0xFF;
398     uint8_t Type3 = (Type >> 16) & 0xFF;
399
400     // Concat all three relocation type names.
401     StringRef Name = getRelocationTypeName(Type1);
402     Result.append(Name.begin(), Name.end());
403
404     Name = getRelocationTypeName(Type2);
405     Result.append(1, '/');
406     Result.append(Name.begin(), Name.end());
407
408     Name = getRelocationTypeName(Type3);
409     Result.append(1, '/');
410     Result.append(Name.begin(), Name.end());
411   }
412 }
413
414 template <class ELFT>
415 uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
416   return getELFRelativeRelocationType(getHeader()->e_machine);
417 }
418
419 template <class ELFT>
420 Expected<const typename ELFT::Sym *>
421 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
422                                    const Elf_Shdr *SymTab) const {
423   uint32_t Index = Rel->getSymbol(isMips64EL());
424   if (Index == 0)
425     return nullptr;
426   return getEntry<Elf_Sym>(SymTab, Index);
427 }
428
429 template <class ELFT>
430 Expected<StringRef>
431 ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
432   uint32_t Index = getHeader()->e_shstrndx;
433   if (Index == ELF::SHN_XINDEX)
434     Index = Sections[0].sh_link;
435
436   if (!Index) // no section string table.
437     return "";
438   if (Index >= Sections.size())
439     return createError("invalid section index");
440   return getStringTable(&Sections[Index]);
441 }
442
443 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
444
445 template <class ELFT>
446 Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
447   if (sizeof(Elf_Ehdr) > Object.size())
448     return createError("Invalid buffer");
449   return ELFFile(Object);
450 }
451
452 template <class ELFT>
453 Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
454   const uintX_t SectionTableOffset = getHeader()->e_shoff;
455   if (SectionTableOffset == 0)
456     return ArrayRef<Elf_Shdr>();
457
458   if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
459     return createError(
460         "invalid section header entry size (e_shentsize) in ELF header");
461
462   const uint64_t FileSize = Buf.size();
463
464   if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
465     return createError("section header table goes past the end of the file");
466
467   // Invalid address alignment of section headers
468   if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
469     return createError("invalid alignment of section headers");
470
471   const Elf_Shdr *First =
472       reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
473
474   uintX_t NumSections = getHeader()->e_shnum;
475   if (NumSections == 0)
476     NumSections = First->sh_size;
477
478   if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
479     return createError("section table goes past the end of file");
480
481   const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
482
483   // Section table goes past end of file!
484   if (SectionTableOffset + SectionTableSize > FileSize)
485     return createError("section table goes past the end of file");
486
487   return makeArrayRef(First, NumSections);
488 }
489
490 template <class ELFT>
491 template <typename T>
492 Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
493                                             uint32_t Entry) const {
494   auto SecOrErr = getSection(Section);
495   if (!SecOrErr)
496     return SecOrErr.takeError();
497   return getEntry<T>(*SecOrErr, Entry);
498 }
499
500 template <class ELFT>
501 template <typename T>
502 Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
503                                             uint32_t Entry) const {
504   if (sizeof(T) != Section->sh_entsize)
505     return createError("invalid sh_entsize");
506   size_t Pos = Section->sh_offset + Entry * sizeof(T);
507   if (Pos + sizeof(T) > Buf.size())
508     return createError("invalid section offset");
509   return reinterpret_cast<const T *>(base() + Pos);
510 }
511
512 template <class ELFT>
513 Expected<const typename ELFT::Shdr *>
514 ELFFile<ELFT>::getSection(uint32_t Index) const {
515   auto TableOrErr = sections();
516   if (!TableOrErr)
517     return TableOrErr.takeError();
518   return object::getSection<ELFT>(*TableOrErr, Index);
519 }
520
521 template <class ELFT>
522 Expected<const typename ELFT::Shdr *>
523 ELFFile<ELFT>::getSection(const StringRef SectionName) const {
524   auto TableOrErr = sections();
525   if (!TableOrErr)
526     return TableOrErr.takeError();
527   for (auto &Sec : *TableOrErr) {
528     auto SecNameOrErr = getSectionName(&Sec);
529     if (!SecNameOrErr)
530       return SecNameOrErr.takeError();
531     if (*SecNameOrErr == SectionName)
532       return &Sec;
533   }
534   return createError("invalid section name");
535 }
536
537 template <class ELFT>
538 Expected<StringRef>
539 ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
540   if (Section->sh_type != ELF::SHT_STRTAB)
541     return createError("invalid sh_type for string table, expected SHT_STRTAB");
542   auto V = getSectionContentsAsArray<char>(Section);
543   if (!V)
544     return V.takeError();
545   ArrayRef<char> Data = *V;
546   if (Data.empty())
547     return createError("empty string table");
548   if (Data.back() != '\0')
549     return createError("string table non-null terminated");
550   return StringRef(Data.begin(), Data.size());
551 }
552
553 template <class ELFT>
554 Expected<ArrayRef<typename ELFT::Word>>
555 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
556   auto SectionsOrErr = sections();
557   if (!SectionsOrErr)
558     return SectionsOrErr.takeError();
559   return getSHNDXTable(Section, *SectionsOrErr);
560 }
561
562 template <class ELFT>
563 Expected<ArrayRef<typename ELFT::Word>>
564 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
565                              Elf_Shdr_Range Sections) const {
566   assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
567   auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
568   if (!VOrErr)
569     return VOrErr.takeError();
570   ArrayRef<Elf_Word> V = *VOrErr;
571   auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
572   if (!SymTableOrErr)
573     return SymTableOrErr.takeError();
574   const Elf_Shdr &SymTable = **SymTableOrErr;
575   if (SymTable.sh_type != ELF::SHT_SYMTAB &&
576       SymTable.sh_type != ELF::SHT_DYNSYM)
577     return createError("invalid sh_type");
578   if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
579     return createError("invalid section contents size");
580   return V;
581 }
582
583 template <class ELFT>
584 Expected<StringRef>
585 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
586   auto SectionsOrErr = sections();
587   if (!SectionsOrErr)
588     return SectionsOrErr.takeError();
589   return getStringTableForSymtab(Sec, *SectionsOrErr);
590 }
591
592 template <class ELFT>
593 Expected<StringRef>
594 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
595                                        Elf_Shdr_Range Sections) const {
596
597   if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
598     return createError(
599         "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
600   auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
601   if (!SectionOrErr)
602     return SectionOrErr.takeError();
603   return getStringTable(*SectionOrErr);
604 }
605
606 template <class ELFT>
607 Expected<StringRef>
608 ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
609   auto SectionsOrErr = sections();
610   if (!SectionsOrErr)
611     return SectionsOrErr.takeError();
612   auto Table = getSectionStringTable(*SectionsOrErr);
613   if (!Table)
614     return Table.takeError();
615   return getSectionName(Section, *Table);
616 }
617
618 template <class ELFT>
619 Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
620                                                   StringRef DotShstrtab) const {
621   uint32_t Offset = Section->sh_name;
622   if (Offset == 0)
623     return StringRef();
624   if (Offset >= DotShstrtab.size())
625     return createError("invalid string offset");
626   return StringRef(DotShstrtab.data() + Offset);
627 }
628
629 /// This function returns the hash value for a symbol in the .dynsym section
630 /// Name of the API remains consistent as specified in the libelf
631 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
632 inline unsigned hashSysV(StringRef SymbolName) {
633   unsigned h = 0, g;
634   for (char C : SymbolName) {
635     h = (h << 4) + C;
636     g = h & 0xf0000000L;
637     if (g != 0)
638       h ^= g >> 24;
639     h &= ~g;
640   }
641   return h;
642 }
643
644 } // end namespace object
645 } // end namespace llvm
646
647 #endif // LLVM_OBJECT_ELF_H