1//===- ELFObjectFile.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 ELFObjectFile template class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
15#define LLVM_OBJECT_ELFOBJECTFILE_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/PointerIntPair.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/ADT/Triple.h"
22#include "llvm/Object/ELF.h"
23#include "llvm/Object/ObjectFile.h"
24#include "llvm/Support/Casting.h"
25#include "llvm/Support/ELF.h"
26#include "llvm/Support/Endian.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Support/MemoryBuffer.h"
29#include "llvm/Support/raw_ostream.h"
30#include <algorithm>
31#include <cctype>
32#include <limits>
33#include <utility>
34
35namespace llvm {
36namespace object {
37
38class elf_symbol_iterator;
39class ELFSymbolRef;
40class ELFRelocationRef;
41
42class ELFObjectFileBase : public ObjectFile {
43  friend class ELFSymbolRef;
44  friend class ELFSectionRef;
45  friend class ELFRelocationRef;
46
47protected:
48  ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
49
50  virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
51  virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
52  virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
53
54  virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
55  virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
56
57  virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
58public:
59
60  typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
61  virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
62
63  elf_symbol_iterator_range symbols() const;
64
65  static inline bool classof(const Binary *v) { return v->isELF(); }
66};
67
68class ELFSectionRef : public SectionRef {
69public:
70  ELFSectionRef(const SectionRef &B) : SectionRef(B) {
71    assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
72  }
73
74  const ELFObjectFileBase *getObject() const {
75    return cast<ELFObjectFileBase>(SectionRef::getObject());
76  }
77
78  uint32_t getType() const {
79    return getObject()->getSectionType(getRawDataRefImpl());
80  }
81
82  uint64_t getFlags() const {
83    return getObject()->getSectionFlags(getRawDataRefImpl());
84  }
85};
86
87class elf_section_iterator : public section_iterator {
88public:
89  elf_section_iterator(const section_iterator &B) : section_iterator(B) {
90    assert(isa<ELFObjectFileBase>(B->getObject()));
91  }
92
93  const ELFSectionRef *operator->() const {
94    return static_cast<const ELFSectionRef *>(section_iterator::operator->());
95  }
96
97  const ELFSectionRef &operator*() const {
98    return static_cast<const ELFSectionRef &>(section_iterator::operator*());
99  }
100};
101
102class ELFSymbolRef : public SymbolRef {
103public:
104  ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
105    assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
106  }
107
108  const ELFObjectFileBase *getObject() const {
109    return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
110  }
111
112  uint64_t getSize() const {
113    return getObject()->getSymbolSize(getRawDataRefImpl());
114  }
115
116  uint8_t getOther() const {
117    return getObject()->getSymbolOther(getRawDataRefImpl());
118  }
119
120  uint8_t getELFType() const {
121    return getObject()->getSymbolELFType(getRawDataRefImpl());
122  }
123};
124
125class elf_symbol_iterator : public symbol_iterator {
126public:
127  elf_symbol_iterator(const basic_symbol_iterator &B)
128      : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
129                                  cast<ELFObjectFileBase>(B->getObject()))) {}
130
131  const ELFSymbolRef *operator->() const {
132    return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
133  }
134
135  const ELFSymbolRef &operator*() const {
136    return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
137  }
138};
139
140class ELFRelocationRef : public RelocationRef {
141public:
142  ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
143    assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
144  }
145
146  const ELFObjectFileBase *getObject() const {
147    return cast<ELFObjectFileBase>(RelocationRef::getObject());
148  }
149
150  ErrorOr<int64_t> getAddend() const {
151    return getObject()->getRelocationAddend(getRawDataRefImpl());
152  }
153};
154
155class elf_relocation_iterator : public relocation_iterator {
156public:
157  elf_relocation_iterator(const relocation_iterator &B)
158      : relocation_iterator(RelocationRef(
159            B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
160
161  const ELFRelocationRef *operator->() const {
162    return static_cast<const ELFRelocationRef *>(
163        relocation_iterator::operator->());
164  }
165
166  const ELFRelocationRef &operator*() const {
167    return static_cast<const ELFRelocationRef &>(
168        relocation_iterator::operator*());
169  }
170};
171
172inline ELFObjectFileBase::elf_symbol_iterator_range
173ELFObjectFileBase::symbols() const {
174  return elf_symbol_iterator_range(symbol_begin(), symbol_end());
175}
176
177template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
178  uint64_t getSymbolSize(DataRefImpl Sym) const override;
179
180public:
181  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
182
183  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
184
185  typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
186  typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
187  typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
188  typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
189  typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
190  typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
191
192protected:
193  ELFFile<ELFT> EF;
194
195  const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
196  const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
197  ArrayRef<Elf_Word> ShndxTable;
198
199  void moveSymbolNext(DataRefImpl &Symb) const override;
200  ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
201  ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
202  uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
203  uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
204  uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
205  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
206  uint8_t getSymbolOther(DataRefImpl Symb) const override;
207  uint8_t getSymbolELFType(DataRefImpl Symb) const override;
208  SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
209  ErrorOr<section_iterator> getSymbolSection(const Elf_Sym *Symb,
210                                             const Elf_Shdr *SymTab) const;
211  ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
212
213  void moveSectionNext(DataRefImpl &Sec) const override;
214  std::error_code getSectionName(DataRefImpl Sec,
215                                 StringRef &Res) const override;
216  uint64_t getSectionAddress(DataRefImpl Sec) const override;
217  uint64_t getSectionSize(DataRefImpl Sec) const override;
218  std::error_code getSectionContents(DataRefImpl Sec,
219                                     StringRef &Res) const override;
220  uint64_t getSectionAlignment(DataRefImpl Sec) const override;
221  bool isSectionText(DataRefImpl Sec) const override;
222  bool isSectionData(DataRefImpl Sec) const override;
223  bool isSectionBSS(DataRefImpl Sec) const override;
224  bool isSectionVirtual(DataRefImpl Sec) const override;
225  relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
226  relocation_iterator section_rel_end(DataRefImpl Sec) const override;
227  section_iterator getRelocatedSection(DataRefImpl Sec) const override;
228
229  void moveRelocationNext(DataRefImpl &Rel) const override;
230  uint64_t getRelocationOffset(DataRefImpl Rel) const override;
231  symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
232  uint64_t getRelocationType(DataRefImpl Rel) const override;
233  void getRelocationTypeName(DataRefImpl Rel,
234                             SmallVectorImpl<char> &Result) const override;
235
236  uint32_t getSectionType(DataRefImpl Sec) const override;
237  uint64_t getSectionFlags(DataRefImpl Sec) const override;
238  StringRef getRelocationTypeName(uint32_t Type) const;
239
240  /// \brief Get the relocation section that contains \a Rel.
241  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
242    return *EF.getSection(Rel.d.a);
243  }
244
245  DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
246    DataRefImpl DRI;
247    if (!SymTable) {
248      DRI.d.a = 0;
249      DRI.d.b = 0;
250      return DRI;
251    }
252    assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
253           SymTable->sh_type == ELF::SHT_DYNSYM);
254
255    uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
256    unsigned SymTableIndex =
257        (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
258
259    DRI.d.a = SymTableIndex;
260    DRI.d.b = SymbolNum;
261    return DRI;
262  }
263
264  const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
265    return reinterpret_cast<const Elf_Shdr *>(Sec.p);
266  }
267
268  DataRefImpl toDRI(const Elf_Shdr *Sec) const {
269    DataRefImpl DRI;
270    DRI.p = reinterpret_cast<uintptr_t>(Sec);
271    return DRI;
272  }
273
274  DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
275    DataRefImpl DRI;
276    DRI.p = reinterpret_cast<uintptr_t>(Dyn);
277    return DRI;
278  }
279
280  bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
281    unsigned char Binding = ESym->getBinding();
282    unsigned char Visibility = ESym->getVisibility();
283
284    // A symbol is exported if its binding is either GLOBAL or WEAK, and its
285    // visibility is either DEFAULT or PROTECTED. All other symbols are not
286    // exported.
287    if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
288        (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED))
289      return true;
290
291    return false;
292  }
293
294  // This flag is used for classof, to distinguish ELFObjectFile from
295  // its subclass. If more subclasses will be created, this flag will
296  // have to become an enum.
297  bool isDyldELFObject;
298
299public:
300  ELFObjectFile(MemoryBufferRef Object, std::error_code &EC);
301
302  const Elf_Rel *getRel(DataRefImpl Rel) const;
303  const Elf_Rela *getRela(DataRefImpl Rela) const;
304
305  const Elf_Sym *getSymbol(DataRefImpl Sym) const {
306    return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
307  }
308
309  const Elf_Shdr *getSection(DataRefImpl Sec) const {
310    return reinterpret_cast<const Elf_Shdr *>(Sec.p);
311  }
312
313  basic_symbol_iterator symbol_begin_impl() const override;
314  basic_symbol_iterator symbol_end_impl() const override;
315
316  elf_symbol_iterator dynamic_symbol_begin() const;
317  elf_symbol_iterator dynamic_symbol_end() const;
318
319  section_iterator section_begin() const override;
320  section_iterator section_end() const override;
321
322  ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
323
324  uint8_t getBytesInAddress() const override;
325  StringRef getFileFormatName() const override;
326  unsigned getArch() const override;
327
328  std::error_code getPlatformFlags(unsigned &Result) const override {
329    Result = EF.getHeader()->e_flags;
330    return std::error_code();
331  }
332
333  const ELFFile<ELFT> *getELFFile() const { return &EF; }
334
335  bool isDyldType() const { return isDyldELFObject; }
336  static inline bool classof(const Binary *v) {
337    return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
338                                      ELFT::Is64Bits);
339  }
340
341  elf_symbol_iterator_range getDynamicSymbolIterators() const override;
342
343  bool isRelocatableObject() const override;
344};
345
346typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
347typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
348typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
349typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
350
351template <class ELFT>
352void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
353  ++Sym.d.b;
354}
355
356template <class ELFT>
357ErrorOr<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
358  const Elf_Sym *ESym = getSymbol(Sym);
359  const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a);
360  const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link);
361  StringRef SymTable = *EF.getStringTable(StringTableSec);
362  return ESym->getName(SymTable);
363}
364
365template <class ELFT>
366uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
367  return getSection(Sec)->sh_flags;
368}
369
370template <class ELFT>
371uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
372  return getSection(Sec)->sh_type;
373}
374
375template <class ELFT>
376uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
377  const Elf_Sym *ESym = getSymbol(Symb);
378  uint64_t Ret = ESym->st_value;
379  if (ESym->st_shndx == ELF::SHN_ABS)
380    return Ret;
381
382  const Elf_Ehdr *Header = EF.getHeader();
383  // Clear the ARM/Thumb or microMIPS indicator flag.
384  if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
385      ESym->getType() == ELF::STT_FUNC)
386    Ret &= ~1;
387
388  return Ret;
389}
390
391template <class ELFT>
392ErrorOr<uint64_t>
393ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
394  uint64_t Result = getSymbolValue(Symb);
395  const Elf_Sym *ESym = getSymbol(Symb);
396  switch (ESym->st_shndx) {
397  case ELF::SHN_COMMON:
398  case ELF::SHN_UNDEF:
399  case ELF::SHN_ABS:
400    return Result;
401  }
402
403  const Elf_Ehdr *Header = EF.getHeader();
404  const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
405
406  if (Header->e_type == ELF::ET_REL) {
407    ErrorOr<const Elf_Shdr *> SectionOrErr =
408        EF.getSection(ESym, SymTab, ShndxTable);
409    if (std::error_code EC = SectionOrErr.getError())
410      return EC;
411    const Elf_Shdr *Section = *SectionOrErr;
412    if (Section)
413      Result += Section->sh_addr;
414  }
415
416  return Result;
417}
418
419template <class ELFT>
420uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
421  const Elf_Sym *Sym = getSymbol(Symb);
422  if (Sym->st_shndx == ELF::SHN_COMMON)
423    return Sym->st_value;
424  return 0;
425}
426
427template <class ELFT>
428uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
429  return getSymbol(Sym)->st_size;
430}
431
432template <class ELFT>
433uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
434  return getSymbol(Symb)->st_size;
435}
436
437template <class ELFT>
438uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
439  return getSymbol(Symb)->st_other;
440}
441
442template <class ELFT>
443uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
444  return getSymbol(Symb)->getType();
445}
446
447template <class ELFT>
448SymbolRef::Type ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
449  const Elf_Sym *ESym = getSymbol(Symb);
450
451  switch (ESym->getType()) {
452  case ELF::STT_NOTYPE:
453    return SymbolRef::ST_Unknown;
454  case ELF::STT_SECTION:
455    return SymbolRef::ST_Debug;
456  case ELF::STT_FILE:
457    return SymbolRef::ST_File;
458  case ELF::STT_FUNC:
459    return SymbolRef::ST_Function;
460  case ELF::STT_OBJECT:
461  case ELF::STT_COMMON:
462  case ELF::STT_TLS:
463    return SymbolRef::ST_Data;
464  default:
465    return SymbolRef::ST_Other;
466  }
467}
468
469template <class ELFT>
470uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
471  const Elf_Sym *ESym = getSymbol(Sym);
472
473  uint32_t Result = SymbolRef::SF_None;
474
475  if (ESym->getBinding() != ELF::STB_LOCAL)
476    Result |= SymbolRef::SF_Global;
477
478  if (ESym->getBinding() == ELF::STB_WEAK)
479    Result |= SymbolRef::SF_Weak;
480
481  if (ESym->st_shndx == ELF::SHN_ABS)
482    Result |= SymbolRef::SF_Absolute;
483
484  if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
485      ESym == EF.symbol_begin(DotSymtabSec) ||
486      ESym == EF.symbol_begin(DotDynSymSec))
487    Result |= SymbolRef::SF_FormatSpecific;
488
489  if (EF.getHeader()->e_machine == ELF::EM_ARM) {
490    if (ErrorOr<StringRef> NameOrErr = getSymbolName(Sym)) {
491      StringRef Name = *NameOrErr;
492      if (Name.startswith("$d") || Name.startswith("$t") ||
493          Name.startswith("$a"))
494        Result |= SymbolRef::SF_FormatSpecific;
495    }
496  }
497
498  if (ESym->st_shndx == ELF::SHN_UNDEF)
499    Result |= SymbolRef::SF_Undefined;
500
501  if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
502    Result |= SymbolRef::SF_Common;
503
504  if (isExportedToOtherDSO(ESym))
505    Result |= SymbolRef::SF_Exported;
506
507  if (ESym->getVisibility() == ELF::STV_HIDDEN)
508    Result |= SymbolRef::SF_Hidden;
509
510  return Result;
511}
512
513template <class ELFT>
514ErrorOr<section_iterator>
515ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
516                                      const Elf_Shdr *SymTab) const {
517  ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
518  if (std::error_code EC = ESecOrErr.getError())
519    return EC;
520
521  const Elf_Shdr *ESec = *ESecOrErr;
522  if (!ESec)
523    return section_end();
524
525  DataRefImpl Sec;
526  Sec.p = reinterpret_cast<intptr_t>(ESec);
527  return section_iterator(SectionRef(Sec, this));
528}
529
530template <class ELFT>
531ErrorOr<section_iterator>
532ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
533  const Elf_Sym *Sym = getSymbol(Symb);
534  const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
535  return getSymbolSection(Sym, SymTab);
536}
537
538template <class ELFT>
539void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
540  const Elf_Shdr *ESec = getSection(Sec);
541  Sec = toDRI(++ESec);
542}
543
544template <class ELFT>
545std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
546                                                    StringRef &Result) const {
547  ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec));
548  if (!Name)
549    return Name.getError();
550  Result = *Name;
551  return std::error_code();
552}
553
554template <class ELFT>
555uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
556  return getSection(Sec)->sh_addr;
557}
558
559template <class ELFT>
560uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
561  return getSection(Sec)->sh_size;
562}
563
564template <class ELFT>
565std::error_code
566ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
567                                        StringRef &Result) const {
568  const Elf_Shdr *EShdr = getSection(Sec);
569  Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
570  return std::error_code();
571}
572
573template <class ELFT>
574uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
575  return getSection(Sec)->sh_addralign;
576}
577
578template <class ELFT>
579bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
580  return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
581}
582
583template <class ELFT>
584bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
585  const Elf_Shdr *EShdr = getSection(Sec);
586  return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
587         EShdr->sh_type == ELF::SHT_PROGBITS;
588}
589
590template <class ELFT>
591bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
592  const Elf_Shdr *EShdr = getSection(Sec);
593  return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
594         EShdr->sh_type == ELF::SHT_NOBITS;
595}
596
597template <class ELFT>
598bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
599  return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
600}
601
602template <class ELFT>
603relocation_iterator
604ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
605  DataRefImpl RelData;
606  uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
607  RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
608  RelData.d.b = 0;
609
610  const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
611  if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
612    return relocation_iterator(RelocationRef(RelData, this));
613
614  const Elf_Shdr *RelSec = getRelSection(RelData);
615  ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
616  if (std::error_code EC = SymSecOrErr.getError())
617    report_fatal_error(EC.message());
618  const Elf_Shdr *SymSec = *SymSecOrErr;
619  uint32_t SymSecType = SymSec->sh_type;
620  if (SymSecType != ELF::SHT_SYMTAB && SymSecType != ELF::SHT_DYNSYM)
621    report_fatal_error("Invalid symbol table section type!");
622  if (SymSecType == ELF::SHT_DYNSYM)
623    RelData.d.b = 1;
624
625  return relocation_iterator(RelocationRef(RelData, this));
626}
627
628template <class ELFT>
629relocation_iterator
630ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
631  const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
632  relocation_iterator Begin = section_rel_begin(Sec);
633  if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
634    return Begin;
635  DataRefImpl RelData = Begin->getRawDataRefImpl();
636  RelData.d.b += (S->sh_size / S->sh_entsize) << 1;
637  return relocation_iterator(RelocationRef(RelData, this));
638}
639
640template <class ELFT>
641section_iterator
642ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
643  if (EF.getHeader()->e_type != ELF::ET_REL)
644    return section_end();
645
646  const Elf_Shdr *EShdr = getSection(Sec);
647  uintX_t Type = EShdr->sh_type;
648  if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
649    return section_end();
650
651  ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info);
652  if (std::error_code EC = R.getError())
653    report_fatal_error(EC.message());
654  return section_iterator(SectionRef(toDRI(*R), this));
655}
656
657// Relocations
658template <class ELFT>
659void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
660  Rel.d.b += 2;
661}
662
663template <class ELFT>
664symbol_iterator
665ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
666  uint32_t symbolIdx;
667  const Elf_Shdr *sec = getRelSection(Rel);
668  if (sec->sh_type == ELF::SHT_REL)
669    symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
670  else
671    symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
672  if (!symbolIdx)
673    return symbol_end();
674
675  bool IsDyn = Rel.d.b & 1;
676  DataRefImpl SymbolData;
677  if (IsDyn)
678    SymbolData = toDRI(DotDynSymSec, symbolIdx);
679  else
680    SymbolData = toDRI(DotSymtabSec, symbolIdx);
681  return symbol_iterator(SymbolRef(SymbolData, this));
682}
683
684template <class ELFT>
685uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
686  assert(EF.getHeader()->e_type == ELF::ET_REL &&
687         "Only relocatable object files have relocation offsets");
688  const Elf_Shdr *sec = getRelSection(Rel);
689  if (sec->sh_type == ELF::SHT_REL)
690    return getRel(Rel)->r_offset;
691
692  return getRela(Rel)->r_offset;
693}
694
695template <class ELFT>
696uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
697  const Elf_Shdr *sec = getRelSection(Rel);
698  if (sec->sh_type == ELF::SHT_REL)
699    return getRel(Rel)->getType(EF.isMips64EL());
700  else
701    return getRela(Rel)->getType(EF.isMips64EL());
702}
703
704template <class ELFT>
705StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
706  return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
707}
708
709template <class ELFT>
710void ELFObjectFile<ELFT>::getRelocationTypeName(
711    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
712  uint32_t type = getRelocationType(Rel);
713  EF.getRelocationTypeName(type, Result);
714}
715
716template <class ELFT>
717ErrorOr<int64_t>
718ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
719  if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
720    return object_error::parse_failed;
721  return (int64_t)getRela(Rel)->r_addend;
722}
723
724template <class ELFT>
725const typename ELFObjectFile<ELFT>::Elf_Rel *
726ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
727  assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
728  return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b >> 1);
729}
730
731template <class ELFT>
732const typename ELFObjectFile<ELFT>::Elf_Rela *
733ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
734  assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
735  return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b >> 1);
736}
737
738template <class ELFT>
739ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
740    : ELFObjectFileBase(
741          getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
742          Object),
743      EF(Data.getBuffer(), EC) {
744  if (EC)
745    return;
746  for (const Elf_Shdr &Sec : EF.sections()) {
747    switch (Sec.sh_type) {
748    case ELF::SHT_DYNSYM: {
749      if (DotDynSymSec) {
750        // More than one .dynsym!
751        EC = object_error::parse_failed;
752        return;
753      }
754      DotDynSymSec = &Sec;
755      break;
756    }
757    case ELF::SHT_SYMTAB: {
758      if (DotSymtabSec) {
759        // More than one .dynsym!
760        EC = object_error::parse_failed;
761        return;
762      }
763      DotSymtabSec = &Sec;
764      break;
765    }
766    case ELF::SHT_SYMTAB_SHNDX: {
767      ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec);
768      if ((EC = TableOrErr.getError()))
769        return;
770      ShndxTable = *TableOrErr;
771      break;
772    }
773    }
774  }
775}
776
777template <class ELFT>
778basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
779  DataRefImpl Sym = toDRI(DotSymtabSec, 0);
780  return basic_symbol_iterator(SymbolRef(Sym, this));
781}
782
783template <class ELFT>
784basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
785  const Elf_Shdr *SymTab = DotSymtabSec;
786  if (!SymTab)
787    return symbol_begin_impl();
788  DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
789  return basic_symbol_iterator(SymbolRef(Sym, this));
790}
791
792template <class ELFT>
793elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
794  DataRefImpl Sym = toDRI(DotDynSymSec, 0);
795  return symbol_iterator(SymbolRef(Sym, this));
796}
797
798template <class ELFT>
799elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
800  const Elf_Shdr *SymTab = DotDynSymSec;
801  DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
802  return basic_symbol_iterator(SymbolRef(Sym, this));
803}
804
805template <class ELFT>
806section_iterator ELFObjectFile<ELFT>::section_begin() const {
807  return section_iterator(SectionRef(toDRI(EF.section_begin()), this));
808}
809
810template <class ELFT>
811section_iterator ELFObjectFile<ELFT>::section_end() const {
812  return section_iterator(SectionRef(toDRI(EF.section_end()), this));
813}
814
815template <class ELFT>
816uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
817  return ELFT::Is64Bits ? 8 : 4;
818}
819
820template <class ELFT>
821StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
822  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
823  switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
824  case ELF::ELFCLASS32:
825    switch (EF.getHeader()->e_machine) {
826    case ELF::EM_386:
827      return "ELF32-i386";
828    case ELF::EM_IAMCU:
829      return "ELF32-iamcu";
830    case ELF::EM_X86_64:
831      return "ELF32-x86-64";
832    case ELF::EM_ARM:
833      return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
834    case ELF::EM_AVR:
835      return "ELF32-avr";
836    case ELF::EM_HEXAGON:
837      return "ELF32-hexagon";
838    case ELF::EM_MIPS:
839      return "ELF32-mips";
840    case ELF::EM_PPC:
841      return "ELF32-ppc";
842    case ELF::EM_SPARC:
843    case ELF::EM_SPARC32PLUS:
844      return "ELF32-sparc";
845    default:
846      return "ELF32-unknown";
847    }
848  case ELF::ELFCLASS64:
849    switch (EF.getHeader()->e_machine) {
850    case ELF::EM_386:
851      return "ELF64-i386";
852    case ELF::EM_X86_64:
853      return "ELF64-x86-64";
854    case ELF::EM_AARCH64:
855      return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
856    case ELF::EM_PPC64:
857      return "ELF64-ppc64";
858    case ELF::EM_S390:
859      return "ELF64-s390";
860    case ELF::EM_SPARCV9:
861      return "ELF64-sparc";
862    case ELF::EM_MIPS:
863      return "ELF64-mips";
864    default:
865      return "ELF64-unknown";
866    }
867  default:
868    // FIXME: Proper error handling.
869    report_fatal_error("Invalid ELFCLASS!");
870  }
871}
872
873template <class ELFT>
874unsigned ELFObjectFile<ELFT>::getArch() const {
875  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
876  switch (EF.getHeader()->e_machine) {
877  case ELF::EM_386:
878  case ELF::EM_IAMCU:
879    return Triple::x86;
880  case ELF::EM_X86_64:
881    return Triple::x86_64;
882  case ELF::EM_AARCH64:
883    return Triple::aarch64;
884  case ELF::EM_ARM:
885    return Triple::arm;
886  case ELF::EM_AVR:
887    return Triple::avr;
888  case ELF::EM_HEXAGON:
889    return Triple::hexagon;
890  case ELF::EM_MIPS:
891    switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
892    case ELF::ELFCLASS32:
893      return IsLittleEndian ? Triple::mipsel : Triple::mips;
894    case ELF::ELFCLASS64:
895      return IsLittleEndian ? Triple::mips64el : Triple::mips64;
896    default:
897      report_fatal_error("Invalid ELFCLASS!");
898    }
899  case ELF::EM_PPC:
900    return Triple::ppc;
901  case ELF::EM_PPC64:
902    return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
903  case ELF::EM_S390:
904    return Triple::systemz;
905
906  case ELF::EM_SPARC:
907  case ELF::EM_SPARC32PLUS:
908    return IsLittleEndian ? Triple::sparcel : Triple::sparc;
909  case ELF::EM_SPARCV9:
910    return Triple::sparcv9;
911
912  default:
913    return Triple::UnknownArch;
914  }
915}
916
917template <class ELFT>
918ELFObjectFileBase::elf_symbol_iterator_range
919ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
920  return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
921}
922
923template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
924  return EF.getHeader()->e_type == ELF::ET_REL;
925}
926
927}
928}
929
930#endif
931