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