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