LLVM  4.0.0
Object/ELF.h
Go to the documentation of this file.
1 //===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the ELFFile template class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_OBJECT_ELF_H
15 #define LLVM_OBJECT_ELF_H
16 
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Object/ELFTypes.h"
20 
21 namespace llvm {
22 namespace object {
23 
25 
26 // Subclasses of ELFFile may need this for template instantiation
27 inline std::pair<unsigned char, unsigned char>
29  if (Object.size() < ELF::EI_NIDENT)
30  return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
31  (uint8_t)ELF::ELFDATANONE);
32  return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
33  (uint8_t)Object[ELF::EI_DATA]);
34 }
35 
36 static inline Error createError(StringRef Err) {
37  return make_error<StringError>(Err, object_error::parse_failed);
38 }
39 
40 template <class ELFT>
41 class ELFFile {
42 public:
44  typedef typename ELFT::uint uintX_t;
45  typedef typename ELFT::Ehdr Elf_Ehdr;
46  typedef typename ELFT::Shdr Elf_Shdr;
47  typedef typename ELFT::Sym Elf_Sym;
48  typedef typename ELFT::Dyn Elf_Dyn;
49  typedef typename ELFT::Phdr Elf_Phdr;
50  typedef typename ELFT::Rel Elf_Rel;
51  typedef typename ELFT::Rela Elf_Rela;
52  typedef typename ELFT::Verdef Elf_Verdef;
53  typedef typename ELFT::Verdaux Elf_Verdaux;
54  typedef typename ELFT::Verneed Elf_Verneed;
55  typedef typename ELFT::Vernaux Elf_Vernaux;
56  typedef typename ELFT::Versym Elf_Versym;
57  typedef typename ELFT::Hash Elf_Hash;
58  typedef typename ELFT::GnuHash Elf_GnuHash;
59  typedef typename ELFT::DynRange Elf_Dyn_Range;
60  typedef typename ELFT::ShdrRange Elf_Shdr_Range;
61  typedef typename ELFT::SymRange Elf_Sym_Range;
62  typedef typename ELFT::RelRange Elf_Rel_Range;
63  typedef typename ELFT::RelaRange Elf_Rela_Range;
64  typedef typename ELFT::PhdrRange Elf_Phdr_Range;
65 
66  const uint8_t *base() const {
67  return reinterpret_cast<const uint8_t *>(Buf.data());
68  }
69 
70  size_t getBufSize() const { return Buf.size(); }
71 
72 private:
73 
74  StringRef Buf;
75 
76 public:
77  const Elf_Ehdr *getHeader() const {
78  return reinterpret_cast<const Elf_Ehdr *>(base());
79  }
80 
81  template <typename T>
83  template <typename T>
85 
89  Elf_Shdr_Range Sections) const;
90 
93  Elf_Shdr_Range Sections) const;
94 
95  void VerifyStrTab(const Elf_Shdr *sh) const;
96 
99  SmallVectorImpl<char> &Result) const;
100 
101  /// \brief Get the symbol for a given relocation.
103  const Elf_Shdr *SymTab) const;
104 
105  ELFFile(StringRef Object);
106 
107  bool isMipsELF64() const {
108  return getHeader()->e_machine == ELF::EM_MIPS &&
109  getHeader()->getFileClass() == ELF::ELFCLASS64;
110  }
111 
112  bool isMips64EL() const {
113  return isMipsELF64() &&
114  getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
115  }
116 
118 
120  if (!Sec)
121  return makeArrayRef<Elf_Sym>(nullptr, nullptr);
122  return getSectionContentsAsArray<Elf_Sym>(Sec);
123  }
124 
126  return getSectionContentsAsArray<Elf_Rela>(Sec);
127  }
128 
130  return getSectionContentsAsArray<Elf_Rel>(Sec);
131  }
132 
133  /// \brief Iterate over program header table.
135  if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
136  return createError("invalid e_phentsize");
137  auto *Begin =
138  reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
139  return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
140  }
141 
144  ArrayRef<Elf_Word> ShndxTable) const;
146  const Elf_Shdr *SymTab,
147  ArrayRef<Elf_Word> ShndxTable) const;
149  Elf_Sym_Range Symtab,
150  ArrayRef<Elf_Word> ShndxTable) const;
152 
154  uint32_t Index) const;
155 
158  StringRef DotShstrtab) const;
159  template <typename T>
162 };
163 
168 
169 template <class ELFT>
171 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
172  if (Index >= Sections.size())
173  return createError("invalid section index");
174  return &Sections[Index];
175 }
176 
177 template <class ELFT>
178 inline Expected<uint32_t>
179 getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
180  const typename ELFT::Sym *FirstSym,
181  ArrayRef<typename ELFT::Word> ShndxTable) {
182  assert(Sym->st_shndx == ELF::SHN_XINDEX);
183  unsigned Index = Sym - FirstSym;
184  if (Index >= ShndxTable.size())
185  return createError("index past the end of the symbol table");
186 
187  // The size of the table was checked in getSHNDXTable.
188  return ShndxTable[Index];
189 }
190 
191 template <class ELFT>
194  ArrayRef<Elf_Word> ShndxTable) const {
195  uint32_t Index = Sym->st_shndx;
196  if (Index == ELF::SHN_XINDEX) {
197  auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
198  Sym, Syms.begin(), ShndxTable);
199  if (!ErrorOrIndex)
200  return ErrorOrIndex.takeError();
201  return *ErrorOrIndex;
202  }
203  if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
204  return 0;
205  return Index;
206 }
207 
208 template <class ELFT>
210 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
211  ArrayRef<Elf_Word> ShndxTable) const {
212  auto SymsOrErr = symbols(SymTab);
213  if (!SymsOrErr)
214  return SymsOrErr.takeError();
215  return getSection(Sym, *SymsOrErr, ShndxTable);
216 }
217 
218 template <class ELFT>
221  ArrayRef<Elf_Word> ShndxTable) const {
222  auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
223  if (!IndexOrErr)
224  return IndexOrErr.takeError();
225  uint32_t Index = *IndexOrErr;
226  if (Index == 0)
227  return nullptr;
228  auto SectionsOrErr = sections();
229  if (!SectionsOrErr)
230  return SectionsOrErr.takeError();
231  return object::getSection<ELFT>(*SectionsOrErr, Index);
232 }
233 
234 template <class ELFT>
236 getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
237  if (Index >= Symbols.size())
238  return createError("invalid symbol index");
239  return &Symbols[Index];
240 }
241 
242 template <class ELFT>
244 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
245  auto SymtabOrErr = symbols(Sec);
246  if (!SymtabOrErr)
247  return SymtabOrErr.takeError();
248  return object::getSymbol<ELFT>(*SymtabOrErr, Index);
249 }
250 
251 template <class ELFT>
252 template <typename T>
255  if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
256  return createError("invalid sh_entsize");
257 
258  uintX_t Offset = Sec->sh_offset;
259  uintX_t Size = Sec->sh_size;
260 
261  if (Size % sizeof(T))
262  return createError("size is not a multiple of sh_entsize");
263  if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
264  Offset + Size > Buf.size())
265  return createError("invalid section offset");
266 
267  const T *Start = reinterpret_cast<const T *>(base() + Offset);
268  return makeArrayRef(Start, Size / sizeof(T));
269 }
270 
271 template <class ELFT>
274  return getSectionContentsAsArray<uint8_t>(Sec);
275 }
276 
277 template <class ELFT>
279  return getELFRelocationTypeName(getHeader()->e_machine, Type);
280 }
281 
282 template <class ELFT>
284  SmallVectorImpl<char> &Result) const {
285  if (!isMipsELF64()) {
286  StringRef Name = getRelocationTypeName(Type);
287  Result.append(Name.begin(), Name.end());
288  } else {
289  // The Mips N64 ABI allows up to three operations to be specified per
290  // relocation record. Unfortunately there's no easy way to test for the
291  // presence of N64 ELFs as they have no special flag that identifies them
292  // as being N64. We can safely assume at the moment that all Mips
293  // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
294  // information to disambiguate between old vs new ABIs.
295  uint8_t Type1 = (Type >> 0) & 0xFF;
296  uint8_t Type2 = (Type >> 8) & 0xFF;
297  uint8_t Type3 = (Type >> 16) & 0xFF;
298 
299  // Concat all three relocation type names.
300  StringRef Name = getRelocationTypeName(Type1);
301  Result.append(Name.begin(), Name.end());
302 
303  Name = getRelocationTypeName(Type2);
304  Result.append(1, '/');
305  Result.append(Name.begin(), Name.end());
306 
307  Name = getRelocationTypeName(Type3);
308  Result.append(1, '/');
309  Result.append(Name.begin(), Name.end());
310  }
311 }
312 
313 template <class ELFT>
316  const Elf_Shdr *SymTab) const {
317  uint32_t Index = Rel->getSymbol(isMips64EL());
318  if (Index == 0)
319  return nullptr;
320  return getEntry<Elf_Sym>(SymTab, Index);
321 }
322 
323 template <class ELFT>
326  uint32_t Index = getHeader()->e_shstrndx;
327  if (Index == ELF::SHN_XINDEX)
328  Index = Sections[0].sh_link;
329 
330  if (!Index) // no section string table.
331  return "";
332  if (Index >= Sections.size())
333  return createError("invalid section index");
334  return getStringTable(&Sections[Index]);
335 }
336 
337 template <class ELFT>
338 ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
339  assert(sizeof(Elf_Ehdr) <= Buf.size() && "Invalid buffer");
340 }
341 
342 template <class ELFT>
343 static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
344  return VAddr < Phdr->p_vaddr;
345 }
346 
347 template <class ELFT>
349  const uintX_t SectionTableOffset = getHeader()->e_shoff;
350  if (SectionTableOffset == 0)
351  return ArrayRef<Elf_Shdr>();
352 
353  if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
354  return createError(
355  "invalid section header entry size (e_shentsize) in ELF header");
356 
357  const uint64_t FileSize = Buf.size();
358 
359  if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
360  return createError("section header table goes past the end of the file");
361 
362  // Invalid address alignment of section headers
363  if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
364  return createError("invalid alignment of section headers");
365 
366  const Elf_Shdr *First =
367  reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
368 
369  uintX_t NumSections = getHeader()->e_shnum;
370  if (NumSections == 0)
371  NumSections = First->sh_size;
372 
373  if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
374  return createError("section table goes past the end of file");
375 
376  const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
377 
378  // Section table goes past end of file!
379  if (SectionTableOffset + SectionTableSize > FileSize)
380  return createError("section table goes past the end of file");
381 
382  return makeArrayRef(First, NumSections);
383 }
384 
385 template <class ELFT>
386 template <typename T>
388  uint32_t Entry) const {
389  auto SecOrErr = getSection(Section);
390  if (!SecOrErr)
391  return SecOrErr.takeError();
392  return getEntry<T>(*SecOrErr, Entry);
393 }
394 
395 template <class ELFT>
396 template <typename T>
398  uint32_t Entry) const {
399  if (sizeof(T) != Section->sh_entsize)
400  return createError("invalid sh_entsize");
401  size_t Pos = Section->sh_offset + Entry * sizeof(T);
402  if (Pos + sizeof(T) > Buf.size())
403  return createError("invalid section offset");
404  return reinterpret_cast<const T *>(base() + Pos);
405 }
406 
407 template <class ELFT>
410  auto TableOrErr = sections();
411  if (!TableOrErr)
412  return TableOrErr.takeError();
413  return object::getSection<ELFT>(*TableOrErr, Index);
414 }
415 
416 template <class ELFT>
419  if (Section->sh_type != ELF::SHT_STRTAB)
420  return createError("invalid sh_type for string table, expected SHT_STRTAB");
421  auto V = getSectionContentsAsArray<char>(Section);
422  if (!V)
423  return V.takeError();
424  ArrayRef<char> Data = *V;
425  if (Data.empty())
426  return createError("empty string table");
427  if (Data.back() != '\0')
428  return createError("string table non-null terminated");
429  return StringRef(Data.begin(), Data.size());
430 }
431 
432 template <class ELFT>
435  auto SectionsOrErr = sections();
436  if (!SectionsOrErr)
437  return SectionsOrErr.takeError();
438  return getSHNDXTable(Section, *SectionsOrErr);
439 }
440 
441 template <class ELFT>
444  Elf_Shdr_Range Sections) const {
445  assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
446  auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
447  if (!VOrErr)
448  return VOrErr.takeError();
449  ArrayRef<Elf_Word> V = *VOrErr;
450  auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
451  if (!SymTableOrErr)
452  return SymTableOrErr.takeError();
453  const Elf_Shdr &SymTable = **SymTableOrErr;
454  if (SymTable.sh_type != ELF::SHT_SYMTAB &&
455  SymTable.sh_type != ELF::SHT_DYNSYM)
456  return createError("invalid sh_type");
457  if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
458  return createError("invalid section contents size");
459  return V;
460 }
461 
462 template <class ELFT>
465  auto SectionsOrErr = sections();
466  if (!SectionsOrErr)
467  return SectionsOrErr.takeError();
468  return getStringTableForSymtab(Sec, *SectionsOrErr);
469 }
470 
471 template <class ELFT>
474  Elf_Shdr_Range Sections) const {
475 
476  if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
477  return createError(
478  "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
479  auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
480  if (!SectionOrErr)
481  return SectionOrErr.takeError();
482  return getStringTable(*SectionOrErr);
483 }
484 
485 template <class ELFT>
488  auto SectionsOrErr = sections();
489  if (!SectionsOrErr)
490  return SectionsOrErr.takeError();
491  auto Table = getSectionStringTable(*SectionsOrErr);
492  if (!Table)
493  return Table.takeError();
494  return getSectionName(Section, *Table);
495 }
496 
497 template <class ELFT>
499  StringRef DotShstrtab) const {
500  uint32_t Offset = Section->sh_name;
501  if (Offset == 0)
502  return StringRef();
503  if (Offset >= DotShstrtab.size())
504  return createError("invalid string offset");
505  return StringRef(DotShstrtab.data() + Offset);
506 }
507 
508 /// This function returns the hash value for a symbol in the .dynsym section
509 /// Name of the API remains consistent as specified in the libelf
510 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
511 inline unsigned hashSysV(StringRef SymbolName) {
512  unsigned h = 0, g;
513  for (char C : SymbolName) {
514  h = (h << 4) + C;
515  g = h & 0xf0000000L;
516  if (g != 0)
517  h ^= g >> 24;
518  h &= ~g;
519  }
520  return h;
521 }
522 } // end namespace object
523 } // end namespace llvm
524 
525 #endif
MachineLoop * L
StringRef getRelocationTypeName(uint32_t Type) const
Definition: Object/ELF.h:278
Expected< StringRef > getSectionName(const Elf_Shdr *Section) const
Definition: Object/ELF.h:487
size_t getBufSize() const
Definition: Object/ELF.h:70
ELFFile< ELFType< support::big, true > > ELF64BEFile
Definition: Object/ELF.h:167
ELFFile< ELFType< support::little, false > > ELF32LEFile
Definition: Object/ELF.h:164
const uint8_t * base() const
Definition: Object/ELF.h:66
ELFYAML::ELF_REL Type3
Definition: ELFYAML.cpp:804
static Error createError(StringRef Err)
Definition: Object/ELF.h:36
unsigned hashSysV(StringRef SymbolName)
This function returns the hash value for a symbol in the .dynsym section Name of the API remains cons...
Definition: Object/ELF.h:511
ELFT::SymRange Elf_Sym_Range
Definition: Object/ELF.h:61
ELFT::RelRange Elf_Rel_Range
Definition: Object/ELF.h:62
Expected< StringRef > getSectionStringTable(Elf_Shdr_Range Sections) const
Definition: Object/ELF.h:325
ELFT::Rela Elf_Rela
Definition: Object/ELF.h:51
ELFT::Verneed Elf_Verneed
Definition: Object/ELF.h:54
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
Tagged union holding either a T or a Error.
ELFT::Phdr Elf_Phdr
Definition: Object/ELF.h:49
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Definition: Object/ELF.h:171
Expected< const Elf_Sym * > getSymbol(const Elf_Shdr *Sec, uint32_t Index) const
Definition: Object/ELF.h:244
#define T
bool isMipsELF64() const
Definition: Object/ELF.h:107
Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const
Get the symbol for a given relocation.
Definition: Object/ELF.h:315
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
Definition: Object/ELF.h:28
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:303
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Definition: Object/ELF.h:236
iterator begin() const
Definition: StringRef.h:103
Expected< uint32_t > getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef< Elf_Word > ShndxTable) const
Definition: Object/ELF.h:193
ELFT::Verdaux Elf_Verdaux
Definition: Object/ELF.h:53
ELFT::GnuHash Elf_GnuHash
Definition: Object/ELF.h:58
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
ELFT::ShdrRange Elf_Shdr_Range
Definition: Object/ELF.h:60
Expected< const T * > getEntry(uint32_t Section, uint32_t Entry) const
Definition: Object/ELF.h:387
ELFT::Versym Elf_Versym
Definition: Object/ELF.h:56
static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl< ELFT > *Phdr)
Definition: Object/ELF.h:343
uint32_t Offset
Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section) const
Definition: Object/ELF.h:434
Expected< StringRef > getStringTable(const Elf_Shdr *Section) const
Definition: Object/ELF.h:418
iterator begin() const
Definition: ArrayRef.h:129
ELFT::uint uintX_t
Definition: Object/ELF.h:44
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
Expected< Elf_Sym_Range > symbols(const Elf_Shdr *Sec) const
Definition: Object/ELF.h:119
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
ELFT::RelaRange Elf_Rela_Range
Definition: Object/ELF.h:63
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr *Sec) const
Definition: Object/ELF.h:254
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:150
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:19
Expected< uint32_t > getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym, const typename ELFT::Sym *FirstSym, ArrayRef< typename ELFT::Word > ShndxTable)
Definition: Object/ELF.h:179
ELFT::Shdr Elf_Shdr
Definition: Object/ELF.h:46
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
ELFFile(StringRef Object)
Definition: Object/ELF.h:338
ELFT::DynRange Elf_Dyn_Range
Definition: Object/ELF.h:59
ELFFile< ELFType< support::little, true > > ELF64LEFile
Definition: Object/ELF.h:165
ELFYAML::ELF_REL Type2
Definition: ELFYAML.cpp:803
Expected< const Elf_Shdr * > getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef< Elf_Word > ShndxTable) const
Definition: Object/ELF.h:210
void VerifyStrTab(const Elf_Shdr *sh) const
Expected< Elf_Shdr_Range > sections() const
Definition: Object/ELF.h:348
ELFT::Verdef Elf_Verdef
Definition: Object/ELF.h:52
ELFT::PhdrRange Elf_Phdr_Range
Definition: Object/ELF.h:64
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr *Sec) const
Definition: Object/ELF.h:273
aarch64 promote const
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Definition: Object/ELF.h:134
Expected< Elf_Rela_Range > relas(const Elf_Shdr *Sec) const
Definition: Object/ELF.h:125
Lightweight error class with error context and mandatory checking.
ELFT::Ehdr Elf_Ehdr
Definition: Object/ELF.h:45
iterator end() const
Definition: StringRef.h:105
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
std::string Hash(const Unit &U)
Definition: FuzzerSHA1.cpp:216
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Definition: ELFTypes.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const
Definition: Object/ELF.h:464
ELFT::Hash Elf_Hash
Definition: Object/ELF.h:57
const Elf_Ehdr * getHeader() const
Definition: Object/ELF.h:77
bool isMips64EL() const
Definition: Object/ELF.h:112
Expected< Elf_Rel_Range > rels(const Elf_Shdr *Sec) const
Definition: Object/ELF.h:129
ELFFile< ELFType< support::big, false > > ELF32BEFile
Definition: Object/ELF.h:166
ELFT::Vernaux Elf_Vernaux
Definition: Object/ELF.h:55