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