LLVM  10.0.0svn
ELF.h
Go to the documentation of this file.
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 
36 
37 // Subclasses of ELFFile may need this for template instantiation
38 inline std::pair<unsigned char, unsigned char>
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(const Twine &Err) {
48  return make_error<StringError>(Err, object_error::parse_failed);
49 }
50 
51 template <class ELFT> class ELFFile;
52 
53 template <class ELFT>
54 std::string getSecIndexForError(const ELFFile<ELFT> *Obj,
55  const typename ELFT::Shdr *Sec) {
56  auto TableOrErr = Obj->sections();
57  if (TableOrErr)
58  return "[index " + std::to_string(Sec - &TableOrErr->front()) + "]";
59  // To make this helper be more convenient for error reporting purposes we
60  // drop the error. But really it should never be triggered. Before this point,
61  // our code should have called 'sections()' and reported a proper error on
62  // failure.
63  llvm::consumeError(TableOrErr.takeError());
64  return "[unknown index]";
65 }
66 
67 static inline Error defaultWarningHandler(const Twine &Msg) {
68  return createError(Msg);
69 }
70 
71 template <class ELFT>
72 class ELFFile {
73 public:
75  using uintX_t = typename ELFT::uint;
76  using Elf_Ehdr = typename ELFT::Ehdr;
77  using Elf_Shdr = typename ELFT::Shdr;
78  using Elf_Sym = typename ELFT::Sym;
79  using Elf_Dyn = typename ELFT::Dyn;
80  using Elf_Phdr = typename ELFT::Phdr;
81  using Elf_Rel = typename ELFT::Rel;
82  using Elf_Rela = typename ELFT::Rela;
83  using Elf_Relr = typename ELFT::Relr;
84  using Elf_Verdef = typename ELFT::Verdef;
85  using Elf_Verdaux = typename ELFT::Verdaux;
86  using Elf_Verneed = typename ELFT::Verneed;
87  using Elf_Vernaux = typename ELFT::Vernaux;
88  using Elf_Versym = typename ELFT::Versym;
89  using Elf_Hash = typename ELFT::Hash;
90  using Elf_GnuHash = typename ELFT::GnuHash;
91  using Elf_Nhdr = typename ELFT::Nhdr;
92  using Elf_Note = typename ELFT::Note;
93  using Elf_Note_Iterator = typename ELFT::NoteIterator;
94  using Elf_Dyn_Range = typename ELFT::DynRange;
95  using Elf_Shdr_Range = typename ELFT::ShdrRange;
96  using Elf_Sym_Range = typename ELFT::SymRange;
97  using Elf_Rel_Range = typename ELFT::RelRange;
98  using Elf_Rela_Range = typename ELFT::RelaRange;
99  using Elf_Relr_Range = typename ELFT::RelrRange;
100  using Elf_Phdr_Range = typename ELFT::PhdrRange;
101 
102  // This is a callback that can be passed to a number of functions.
103  // It can be used to ignore non-critical errors (warnings), which is
104  // useful for dumpers, like llvm-readobj.
105  // It accepts a warning message string and returns a success
106  // when the warning should be ignored or an error otherwise.
108 
109  const uint8_t *base() const { return Buf.bytes_begin(); }
110 
111  size_t getBufSize() const { return Buf.size(); }
112 
113 private:
114  StringRef Buf;
115 
116  ELFFile(StringRef Object);
117 
118 public:
119  const Elf_Ehdr *getHeader() const {
120  return reinterpret_cast<const Elf_Ehdr *>(base());
121  }
122 
123  template <typename T>
125  template <typename T>
126  Expected<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
127 
129  getStringTable(const Elf_Shdr *Section,
130  WarningHandler WarnHandler = &defaultWarningHandler) const;
133  Elf_Shdr_Range Sections) const;
134 
135  Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
137  Elf_Shdr_Range Sections) const;
138 
141  SmallVectorImpl<char> &Result) const;
143 
144  std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
145  std::string getDynamicTagAsString(uint64_t Type) const;
146 
147  /// Get the symbol for a given relocation.
149  const Elf_Shdr *SymTab) const;
150 
151  static Expected<ELFFile> create(StringRef Object);
152 
153  bool isLE() const {
154  return getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
155  }
156 
157  bool isMipsELF64() const {
158  return getHeader()->e_machine == ELF::EM_MIPS &&
159  getHeader()->getFileClass() == ELF::ELFCLASS64;
160  }
161 
162  bool isMips64EL() const { return isMipsELF64() && isLE(); }
163 
165 
167 
168  Expected<const uint8_t *> toMappedAddr(uint64_t VAddr) const;
169 
171  if (!Sec)
172  return makeArrayRef<Elf_Sym>(nullptr, nullptr);
173  return getSectionContentsAsArray<Elf_Sym>(Sec);
174  }
175 
177  return getSectionContentsAsArray<Elf_Rela>(Sec);
178  }
179 
181  return getSectionContentsAsArray<Elf_Rel>(Sec);
182  }
183 
185  return getSectionContentsAsArray<Elf_Relr>(Sec);
186  }
187 
189 
191 
192  /// Iterate over program header table.
194  if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
195  return createError("invalid e_phentsize: " +
196  Twine(getHeader()->e_phentsize));
197  if (getHeader()->e_phoff +
198  (getHeader()->e_phnum * getHeader()->e_phentsize) >
199  getBufSize())
200  return createError("program headers are longer than binary of size " +
201  Twine(getBufSize()) + ": e_phoff = 0x" +
202  Twine::utohexstr(getHeader()->e_phoff) +
203  ", e_phnum = " + Twine(getHeader()->e_phnum) +
204  ", e_phentsize = " + Twine(getHeader()->e_phentsize));
205  auto *Begin =
206  reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
207  return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
208  }
209 
210  /// Get an iterator over notes in a program header.
211  ///
212  /// The program header must be of type \c PT_NOTE.
213  ///
214  /// \param Phdr the program header to iterate over.
215  /// \param Err [out] an error to support fallible iteration, which should
216  /// be checked after iteration ends.
217  Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
218  assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
219  ErrorAsOutParameter ErrAsOutParam(&Err);
220  if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
221  Err = createError("PT_NOTE header has invalid offset (0x" +
222  Twine::utohexstr(Phdr.p_offset) + ") or size (0x" +
223  Twine::utohexstr(Phdr.p_filesz) + ")");
224  return Elf_Note_Iterator(Err);
225  }
226  return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
227  }
228 
229  /// Get an iterator over notes in a section.
230  ///
231  /// The section must be of type \c SHT_NOTE.
232  ///
233  /// \param Shdr the section to iterate over.
234  /// \param Err [out] an error to support fallible iteration, which should
235  /// be checked after iteration ends.
236  Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
237  assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
238  ErrorAsOutParameter ErrAsOutParam(&Err);
239  if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
240  Err = createError("SHT_NOTE section " + getSecIndexForError(this, &Shdr) +
241  " has invalid offset (0x" +
242  Twine::utohexstr(Shdr.sh_offset) + ") or size (0x" +
243  Twine::utohexstr(Shdr.sh_size) + ")");
244  return Elf_Note_Iterator(Err);
245  }
246  return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
247  }
248 
249  /// Get the end iterator for notes.
251  return Elf_Note_Iterator();
252  }
253 
254  /// Get an iterator range over notes of a program header.
255  ///
256  /// The program header must be of type \c PT_NOTE.
257  ///
258  /// \param Phdr the program header to iterate over.
259  /// \param Err [out] an error to support fallible iteration, which should
260  /// be checked after iteration ends.
262  Error &Err) const {
263  return make_range(notes_begin(Phdr, Err), notes_end());
264  }
265 
266  /// Get an iterator range over notes of a section.
267  ///
268  /// The section must be of type \c SHT_NOTE.
269  ///
270  /// \param Shdr the section to iterate over.
271  /// \param Err [out] an error to support fallible iteration, which should
272  /// be checked after iteration ends.
274  Error &Err) const {
275  return make_range(notes_begin(Shdr, Err), notes_end());
276  }
277 
279  Elf_Shdr_Range Sections,
280  WarningHandler WarnHandler = &defaultWarningHandler) const;
282  ArrayRef<Elf_Word> ShndxTable) const;
284  const Elf_Shdr *SymTab,
285  ArrayRef<Elf_Word> ShndxTable) const;
287  Elf_Sym_Range Symtab,
288  ArrayRef<Elf_Word> ShndxTable) const;
290 
292  uint32_t Index) const;
293 
295  getSectionName(const Elf_Shdr *Section,
296  WarningHandler WarnHandler = &defaultWarningHandler) const;
298  StringRef DotShstrtab) const;
299  template <typename T>
302 };
303 
308 
309 template <class ELFT>
311 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
312  if (Index >= Sections.size())
313  return createError("invalid section index: " + Twine(Index));
314  return &Sections[Index];
315 }
316 
317 template <class ELFT>
318 inline Expected<uint32_t>
319 getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
320  const typename ELFT::Sym *FirstSym,
321  ArrayRef<typename ELFT::Word> ShndxTable) {
322  assert(Sym->st_shndx == ELF::SHN_XINDEX);
323  unsigned Index = Sym - FirstSym;
324  if (Index >= ShndxTable.size())
325  return createError(
326  "extended symbol index (" + Twine(Index) +
327  ") is past the end of the SHT_SYMTAB_SHNDX section of size " +
328  Twine(ShndxTable.size()));
329 
330  // The size of the table was checked in getSHNDXTable.
331  return ShndxTable[Index];
332 }
333 
334 template <class ELFT>
337  ArrayRef<Elf_Word> ShndxTable) const {
338  uint32_t Index = Sym->st_shndx;
339  if (Index == ELF::SHN_XINDEX) {
340  auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
341  Sym, Syms.begin(), ShndxTable);
342  if (!ErrorOrIndex)
343  return ErrorOrIndex.takeError();
344  return *ErrorOrIndex;
345  }
346  if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
347  return 0;
348  return Index;
349 }
350 
351 template <class ELFT>
353 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
354  ArrayRef<Elf_Word> ShndxTable) const {
355  auto SymsOrErr = symbols(SymTab);
356  if (!SymsOrErr)
357  return SymsOrErr.takeError();
358  return getSection(Sym, *SymsOrErr, ShndxTable);
359 }
360 
361 template <class ELFT>
364  ArrayRef<Elf_Word> ShndxTable) const {
365  auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
366  if (!IndexOrErr)
367  return IndexOrErr.takeError();
368  uint32_t Index = *IndexOrErr;
369  if (Index == 0)
370  return nullptr;
371  return getSection(Index);
372 }
373 
374 template <class ELFT>
377  auto SymsOrErr = symbols(Sec);
378  if (!SymsOrErr)
379  return SymsOrErr.takeError();
380 
381  Elf_Sym_Range Symbols = *SymsOrErr;
382  if (Index >= Symbols.size())
383  return createError("unable to get symbol from section " +
384  getSecIndexForError(this, Sec) +
385  ": invalid symbol index (" + Twine(Index) + ")");
386  return &Symbols[Index];
387 }
388 
389 template <class ELFT>
390 template <typename T>
393  if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
394  return createError("section " + getSecIndexForError(this, Sec) +
395  " has an invalid sh_entsize: " + Twine(Sec->sh_entsize));
396 
397  uintX_t Offset = Sec->sh_offset;
398  uintX_t Size = Sec->sh_size;
399 
400  if (Size % sizeof(T))
401  return createError("section " + getSecIndexForError(this, Sec) +
402  " has an invalid sh_size (" + Twine(Size) +
403  ") which is not a multiple of its sh_entsize (" +
404  Twine(Sec->sh_entsize) + ")");
405  if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
406  Offset + Size > Buf.size())
407  return createError("section " + getSecIndexForError(this, Sec) +
408  " has a sh_offset (0x" + Twine::utohexstr(Offset) +
409  ") + sh_size (0x" + Twine(Size) +
410  ") that cannot be represented");
411 
412  if (Offset % alignof(T))
413  // TODO: this error is untested.
414  return createError("unaligned data");
415 
416  const T *Start = reinterpret_cast<const T *>(base() + Offset);
417  return makeArrayRef(Start, Size / sizeof(T));
418 }
419 
420 template <class ELFT>
423  return getSectionContentsAsArray<uint8_t>(Sec);
424 }
425 
426 template <class ELFT>
428  return getELFRelocationTypeName(getHeader()->e_machine, Type);
429 }
430 
431 template <class ELFT>
433  SmallVectorImpl<char> &Result) const {
434  if (!isMipsELF64()) {
436  Result.append(Name.begin(), Name.end());
437  } else {
438  // The Mips N64 ABI allows up to three operations to be specified per
439  // relocation record. Unfortunately there's no easy way to test for the
440  // presence of N64 ELFs as they have no special flag that identifies them
441  // as being N64. We can safely assume at the moment that all Mips
442  // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
443  // information to disambiguate between old vs new ABIs.
444  uint8_t Type1 = (Type >> 0) & 0xFF;
445  uint8_t Type2 = (Type >> 8) & 0xFF;
446  uint8_t Type3 = (Type >> 16) & 0xFF;
447 
448  // Concat all three relocation type names.
450  Result.append(Name.begin(), Name.end());
451 
452  Name = getRelocationTypeName(Type2);
453  Result.append(1, '/');
454  Result.append(Name.begin(), Name.end());
455 
456  Name = getRelocationTypeName(Type3);
457  Result.append(1, '/');
458  Result.append(Name.begin(), Name.end());
459  }
460 }
461 
462 template <class ELFT>
464  return getELFRelativeRelocationType(getHeader()->e_machine);
465 }
466 
467 template <class ELFT>
470  const Elf_Shdr *SymTab) const {
471  uint32_t Index = Rel->getSymbol(isMips64EL());
472  if (Index == 0)
473  return nullptr;
474  return getEntry<Elf_Sym>(SymTab, Index);
475 }
476 
477 template <class ELFT>
480  WarningHandler WarnHandler) const {
481  uint32_t Index = getHeader()->e_shstrndx;
482  if (Index == ELF::SHN_XINDEX)
483  Index = Sections[0].sh_link;
484 
485  if (!Index) // no section string table.
486  return "";
487  if (Index >= Sections.size())
488  return createError("section header string table index " + Twine(Index) +
489  " does not exist");
490  return getStringTable(&Sections[Index], WarnHandler);
491 }
492 
493 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
494 
495 template <class ELFT>
497  if (sizeof(Elf_Ehdr) > Object.size())
498  return createError("invalid buffer: the size (" + Twine(Object.size()) +
499  ") is smaller than an ELF header (" +
500  Twine(sizeof(Elf_Ehdr)) + ")");
501  return ELFFile(Object);
502 }
503 
504 template <class ELFT>
506  const uintX_t SectionTableOffset = getHeader()->e_shoff;
507  if (SectionTableOffset == 0)
508  return ArrayRef<Elf_Shdr>();
509 
510  if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
511  return createError("invalid e_shentsize in ELF header: " +
512  Twine(getHeader()->e_shentsize));
513 
514  const uint64_t FileSize = Buf.size();
515  if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
516  SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
517  return createError(
518  "section header table goes past the end of the file: e_shoff = 0x" +
519  Twine::utohexstr(SectionTableOffset));
520 
521  // Invalid address alignment of section headers
522  if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
523  // TODO: this error is untested.
524  return createError("invalid alignment of section headers");
525 
526  const Elf_Shdr *First =
527  reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
528 
529  uintX_t NumSections = getHeader()->e_shnum;
530  if (NumSections == 0)
531  NumSections = First->sh_size;
532 
533  if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
534  return createError("invalid number of sections specified in the NULL "
535  "section's sh_size field (" +
536  Twine(NumSections) + ")");
537 
538  const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
539  if (SectionTableOffset + SectionTableSize < SectionTableOffset)
540  return createError(
541  "invalid section header table offset (e_shoff = 0x" +
542  Twine::utohexstr(SectionTableOffset) +
543  ") or invalid number of sections specified in the first section "
544  "header's sh_size field (0x" +
545  Twine::utohexstr(NumSections) + ")");
546 
547  // Section table goes past end of file!
548  if (SectionTableOffset + SectionTableSize > FileSize)
549  return createError("section table goes past the end of file");
550  return makeArrayRef(First, NumSections);
551 }
552 
553 template <class ELFT>
554 template <typename T>
556  uint32_t Entry) const {
557  auto SecOrErr = getSection(Section);
558  if (!SecOrErr)
559  return SecOrErr.takeError();
560  return getEntry<T>(*SecOrErr, Entry);
561 }
562 
563 template <class ELFT>
564 template <typename T>
566  uint32_t Entry) const {
567  if (sizeof(T) != Section->sh_entsize)
568  return createError("section " + getSecIndexForError(this, Section) +
569  " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
570  ", but got " + Twine(Section->sh_entsize));
571  size_t Pos = Section->sh_offset + Entry * sizeof(T);
572  if (Pos + sizeof(T) > Buf.size())
573  return createError("unable to access section " +
574  getSecIndexForError(this, Section) + " data at 0x" +
575  Twine::utohexstr(Pos) +
576  ": offset goes past the end of file");
577  return reinterpret_cast<const T *>(base() + Pos);
578 }
579 
580 template <class ELFT>
583  auto TableOrErr = sections();
584  if (!TableOrErr)
585  return TableOrErr.takeError();
586  return object::getSection<ELFT>(*TableOrErr, Index);
587 }
588 
589 template <class ELFT>
592  WarningHandler WarnHandler) const {
593  if (Section->sh_type != ELF::SHT_STRTAB)
594  if (Error E = WarnHandler("invalid sh_type for string table section " +
595  getSecIndexForError(this, Section) +
596  ": expected SHT_STRTAB, but got " +
598  getHeader()->e_machine, Section->sh_type)))
599  return std::move(E);
600 
601  auto V = getSectionContentsAsArray<char>(Section);
602  if (!V)
603  return V.takeError();
604  ArrayRef<char> Data = *V;
605  if (Data.empty())
606  return createError("SHT_STRTAB string table section " +
607  getSecIndexForError(this, Section) + " is empty");
608  if (Data.back() != '\0')
609  return createError("SHT_STRTAB string table section " +
610  getSecIndexForError(this, Section) +
611  " is non-null terminated");
612  return StringRef(Data.begin(), Data.size());
613 }
614 
615 template <class ELFT>
618  auto SectionsOrErr = sections();
619  if (!SectionsOrErr)
620  return SectionsOrErr.takeError();
621  return getSHNDXTable(Section, *SectionsOrErr);
622 }
623 
624 template <class ELFT>
627  Elf_Shdr_Range Sections) const {
628  assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
629  auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
630  if (!VOrErr)
631  return VOrErr.takeError();
632  ArrayRef<Elf_Word> V = *VOrErr;
633  auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
634  if (!SymTableOrErr)
635  return SymTableOrErr.takeError();
636  const Elf_Shdr &SymTable = **SymTableOrErr;
637  if (SymTable.sh_type != ELF::SHT_SYMTAB &&
638  SymTable.sh_type != ELF::SHT_DYNSYM)
639  return createError("SHT_SYMTAB_SHNDX section is linked with " +
641  SymTable.sh_type) +
642  " section (expected SHT_SYMTAB/SHT_DYNSYM)");
643 
644  if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
645  return createError("SHT_SYMTAB_SHNDX section has sh_size (" +
646  Twine(SymTable.sh_size) +
647  ") which is not equal to the number of symbols (" +
648  Twine(V.size()) + ")");
649  return V;
650 }
651 
652 template <class ELFT>
655  auto SectionsOrErr = sections();
656  if (!SectionsOrErr)
657  return SectionsOrErr.takeError();
658  return getStringTableForSymtab(Sec, *SectionsOrErr);
659 }
660 
661 template <class ELFT>
664  Elf_Shdr_Range Sections) const {
665 
666  if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
667  // TODO: this error is untested.
668  return createError(
669  "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
670  auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
671  if (!SectionOrErr)
672  return SectionOrErr.takeError();
673  return getStringTable(*SectionOrErr);
674 }
675 
676 template <class ELFT>
679  WarningHandler WarnHandler) const {
680  auto SectionsOrErr = sections();
681  if (!SectionsOrErr)
682  return SectionsOrErr.takeError();
683  auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
684  if (!Table)
685  return Table.takeError();
686  return getSectionName(Section, *Table);
687 }
688 
689 template <class ELFT>
691  StringRef DotShstrtab) const {
692  uint32_t Offset = Section->sh_name;
693  if (Offset == 0)
694  return StringRef();
695  if (Offset >= DotShstrtab.size())
696  return createError("a section " + getSecIndexForError(this, Section) +
697  " has an invalid sh_name (0x" +
698  Twine::utohexstr(Offset) +
699  ") offset which goes past the end of the "
700  "section name string table");
701  return StringRef(DotShstrtab.data() + Offset);
702 }
703 
704 /// This function returns the hash value for a symbol in the .dynsym section
705 /// Name of the API remains consistent as specified in the libelf
706 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
707 inline unsigned hashSysV(StringRef SymbolName) {
708  unsigned h = 0, g;
709  for (char C : SymbolName) {
710  h = (h << 4) + C;
711  g = h & 0xf0000000L;
712  if (g != 0)
713  h ^= g >> 24;
714  h &= ~g;
715  }
716  return h;
717 }
718 
719 } // end namespace object
720 } // end namespace llvm
721 
722 #endif // LLVM_OBJECT_ELF_H
typename ELFT::Dyn Elf_Dyn
Definition: ELF.h:79
uint64_t CallInst * C
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:157
typename ELFT::Rel Elf_Rel
Definition: ELF.h:81
iterator_range< Elf_Note_Iterator > notes(const Elf_Phdr &Phdr, Error &Err) const
Get an iterator range over notes of a program header.
Definition: ELF.h:261
Expected< const T * > getEntry(uint32_t Section, uint32_t Entry) const
Definition: ELF.h:555
This class represents lattice values for constants.
Definition: AllocatorList.h:23
typename ELFT::Note Elf_Note
Definition: ELF.h:92
static Expected< ELFFile > create(StringRef Object)
Definition: ELF.h:496
iterator begin() const
Definition: ArrayRef.h:136
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
Expected< StringRef > getStringTable(const Elf_Shdr *Section, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition: ELF.h:591
typename ELFT::Vernaux Elf_Vernaux
Definition: ELF.h:87
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
StringRef getRelocationTypeName(uint32_t Type) const
Definition: ELF.h:427
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:104
ELFYAML::ELF_REL Type3
Definition: ELFYAML.cpp:1295
Expected< std::vector< Elf_Rela > > decode_relrs(Elf_Relr_Range relrs) const
Definition: ELF.cpp:272
unsigned hashSysV(StringRef SymbolName)
This function returns the hash value for a symbol in the .dynsym section Name of the API remains cons...
Definition: ELF.h:707
typename ELFT::Sym Elf_Sym
Definition: ELF.h:78
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Definition: ELF.h:193
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr) const
Definition: ELF.cpp:557
const uint8_t * base() const
Definition: ELF.h:109
Expected< const Elf_Shdr * > getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef< Elf_Word > ShndxTable) const
Definition: ELF.h:353
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool isMips64EL() const
Definition: ELF.h:162
iterator_range< Elf_Note_Iterator > notes(const Elf_Shdr &Shdr, Error &Err) const
Get an iterator range over notes of a section.
Definition: ELF.h:273
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:450
Expected< Elf_Shdr_Range > sections() const
Definition: ELF.h:505
typename ELFT::PhdrRange Elf_Phdr_Range
Definition: ELF.h:100
typename ELFT::Phdr Elf_Phdr
Definition: ELF.h:80
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
uint32_t getELFRelativeRelocationType(uint32_t Machine)
Definition: ELF.cpp:156
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr *Sec) const
Definition: ELF.h:422
#define UINT64_MAX
Definition: DataTypes.h:83
bool isLE() const
Definition: ELF.h:153
static Error createError(const Twine &Err)
Definition: ELF.h:47
typename ELFT::Relr Elf_Relr
Definition: ELF.h:83
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
Definition: ELF.h:39
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
typename ELFT::GnuHash Elf_GnuHash
Definition: ELF.h:90
static Error defaultWarningHandler(const Twine &Msg)
Definition: ELF.h:67
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:365
typename ELFT::SymRange Elf_Sym_Range
Definition: ELF.h:96
Elf_Note_Iterator notes_end() const
Get the end iterator for notes.
Definition: ELF.h:250
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr *Sec) const
Definition: ELF.h:392
Expected< Elf_Rel_Range > rels(const Elf_Shdr *Sec) const
Definition: ELF.h:180
Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section) const
Definition: ELF.h:617
bool isMipsELF64() const
Definition: ELF.h:157
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const
Get an iterator over notes in a section.
Definition: ELF.h:236
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const
Definition: ELF.h:654
Expected< Elf_Rela_Range > relas(const Elf_Shdr *Sec) const
Definition: ELF.h:176
typename ELFT::uint uintX_t
Definition: ELF.h:75
Expected< uint32_t > getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef< Elf_Word > ShndxTable) const
Definition: ELF.h:336
Expected< Elf_Relr_Range > relrs(const Elf_Shdr *Sec) const
Definition: ELF.h:184
typename ELFT::NoteIterator Elf_Note_Iterator
Definition: ELF.h:93
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Definition: ELF.cpp:431
typename ELFT::Nhdr Elf_Nhdr
Definition: ELF.h:91
Expected< StringRef > getSectionName(const Elf_Shdr *Section, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition: ELF.h:678
typename ELFT::Verdaux Elf_Verdaux
Definition: ELF.h:85
typename ELFT::Ehdr Elf_Ehdr
Definition: ELF.h:76
typename ELFT::RelrRange Elf_Relr_Range
Definition: ELF.h:99
typename ELFT::Rela Elf_Rela
Definition: ELF.h:82
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1001
typename ELFT::Verneed Elf_Verneed
Definition: ELF.h:86
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:22
Expected< uint32_t > getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym, const typename ELFT::Sym *FirstSym, ArrayRef< typename ELFT::Word > ShndxTable)
Definition: ELF.h:319
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
size_t getBufSize() const
Definition: ELF.h:111
Expected< StringRef > getSectionStringTable(Elf_Shdr_Range Sections, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition: ELF.h:479
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const
Get the symbol for a given relocation.
Definition: ELF.h:469
A range adaptor for a pair of iterators.
Helper for Errors used as out-parameters.
Definition: Error.h:1055
iterator begin() const
Definition: StringRef.h:115
Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const
Get an iterator over notes in a program header.
Definition: ELF.h:217
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:387
typename ELFT::DynRange Elf_Dyn_Range
Definition: ELF.h:94
ELFYAML::ELF_REL Type2
Definition: ELFYAML.cpp:1294
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr *Sec) const
Definition: ELF.cpp:351
uint32_t getRelativeRelocationType() const
Definition: ELF.h:463
const unsigned char * bytes_begin() const
Definition: StringRef.h:119
Expected< const Elf_Sym * > getSymbol(const Elf_Shdr *Sec, uint32_t Index) const
Definition: ELF.h:376
Expected< Elf_Sym_Range > symbols(const Elf_Shdr *Sec) const
Definition: ELF.h:170
uint32_t Size
Definition: Profile.cpp:46
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
typename ELFT::Verdef Elf_Verdef
Definition: ELF.h:84
Expected< Elf_Dyn_Range > dynamicEntries() const
Definition: ELF.cpp:500
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
typename ELFT::RelRange Elf_Rel_Range
Definition: ELF.h:97
aarch64 promote const
typename ELFT::Versym Elf_Versym
Definition: ELF.h:88
typename ELFT::RelaRange Elf_Rela_Range
Definition: ELF.h:98
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Definition: ELFTypes.h:103
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
typename ELFT::ShdrRange Elf_Shdr_Range
Definition: ELF.h:95
const Elf_Ehdr * getHeader() const
Definition: ELF.h:119
std::string getSecIndexForError(const ELFFile< ELFT > *Obj, const typename ELFT::Shdr *Sec)
Definition: ELF.h:54
iterator end() const
Definition: StringRef.h:117
typename ELFT::Shdr Elf_Shdr
Definition: ELF.h:77
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143
typename ELFT::Hash Elf_Hash
Definition: ELF.h:89