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