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