1 //===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the ELFObjectFile template class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
15 #define LLVM_OBJECT_ELFOBJECTFILE_H
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"
38 class elf_symbol_iterator;
41 class ELFObjectFileBase : public ObjectFile {
42 friend class ELFSymbolRef;
45 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
47 virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
50 virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
52 // FIXME: This is a bit of a hack. Every caller should know if it expecting
54 virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
56 typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
57 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
59 virtual uint64_t getSectionFlags(SectionRef Sec) const = 0;
60 virtual uint32_t getSectionType(SectionRef Sec) const = 0;
62 elf_symbol_iterator_range symbols() const;
64 static inline bool classof(const Binary *v) { return v->isELF(); }
67 class ELFSymbolRef : public SymbolRef {
69 ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
70 assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
73 const ELFObjectFileBase *getObject() const {
74 return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
77 uint64_t getSize() const {
78 return getObject()->getSymbolSize(getRawDataRefImpl());
82 class elf_symbol_iterator : public symbol_iterator {
84 elf_symbol_iterator(const basic_symbol_iterator &B)
85 : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
86 cast<ELFObjectFileBase>(B->getObject()))) {}
88 const ELFSymbolRef *operator->() const {
89 return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
92 const ELFSymbolRef &operator*() const {
93 return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
97 inline ELFObjectFileBase::elf_symbol_iterator_range
98 ELFObjectFileBase::symbols() const {
99 return elf_symbol_iterator_range(symbol_begin(), symbol_end());
102 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
103 uint64_t getSymbolSize(DataRefImpl Sym) const override;
106 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
108 typedef typename ELFFile<ELFT>::uintX_t uintX_t;
110 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
111 typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
112 typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
113 typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
114 typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
115 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
117 typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
118 typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
119 typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
124 void moveSymbolNext(DataRefImpl &Symb) const override;
125 std::error_code getSymbolName(DataRefImpl Symb,
126 StringRef &Res) const override;
127 std::error_code getSymbolAddress(DataRefImpl Symb,
128 uint64_t &Res) const override;
129 uint64_t getSymbolValue(DataRefImpl Symb) const override;
130 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
131 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
132 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
133 std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override;
134 std::error_code getSymbolType(DataRefImpl Symb,
135 SymbolRef::Type &Res) const override;
136 section_iterator getSymbolSection(const Elf_Sym *Symb) const;
137 std::error_code getSymbolSection(DataRefImpl Symb,
138 section_iterator &Res) const override;
140 void moveSectionNext(DataRefImpl &Sec) const override;
141 std::error_code getSectionName(DataRefImpl Sec,
142 StringRef &Res) const override;
143 uint64_t getSectionAddress(DataRefImpl Sec) const override;
144 uint64_t getSectionSize(DataRefImpl Sec) const override;
145 std::error_code getSectionContents(DataRefImpl Sec,
146 StringRef &Res) const override;
147 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
148 bool isSectionText(DataRefImpl Sec) const override;
149 bool isSectionData(DataRefImpl Sec) const override;
150 bool isSectionBSS(DataRefImpl Sec) const override;
151 bool isSectionVirtual(DataRefImpl Sec) const override;
152 bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override;
153 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
154 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
155 section_iterator getRelocatedSection(DataRefImpl Sec) const override;
157 void moveRelocationNext(DataRefImpl &Rel) const override;
158 std::error_code getRelocationAddress(DataRefImpl Rel,
159 uint64_t &Res) const override;
160 std::error_code getRelocationOffset(DataRefImpl Rel,
161 uint64_t &Res) const override;
162 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
163 std::error_code getRelocationType(DataRefImpl Rel,
164 uint64_t &Res) const override;
166 getRelocationTypeName(DataRefImpl Rel,
167 SmallVectorImpl<char> &Result) const override;
169 uint64_t getROffset(DataRefImpl Rel) const;
170 StringRef getRelocationTypeName(uint32_t Type) const;
172 /// \brief Get the relocation section that contains \a Rel.
173 const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
174 return EF.getSection(Rel.d.a);
177 const Elf_Rel *getRel(DataRefImpl Rel) const;
178 const Elf_Rela *getRela(DataRefImpl Rela) const;
180 Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const {
181 bool IsDynamic = Symb.p & 1;
184 EF.begin_dynamic_symbols().getEntSize(),
185 reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic);
186 return Elf_Sym_Iter(EF.begin_symbols().getEntSize(),
187 reinterpret_cast<const char *>(Symb.p), IsDynamic);
190 DataRefImpl toDRI(Elf_Sym_Iter Symb) const {
192 DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) |
193 static_cast<uintptr_t>(Symb.isDynamic());
197 Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const {
198 return Elf_Shdr_Iter(EF.getHeader()->e_shentsize,
199 reinterpret_cast<const char *>(Sec.p));
202 DataRefImpl toDRI(Elf_Shdr_Iter Sec) const {
204 DRI.p = reinterpret_cast<uintptr_t>(Sec.get());
208 DataRefImpl toDRI(const Elf_Shdr *Sec) const {
210 DRI.p = reinterpret_cast<uintptr_t>(Sec);
214 Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
215 return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
216 reinterpret_cast<const char *>(Dyn.p));
219 DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
221 DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
225 bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
226 unsigned char Binding = ESym->getBinding();
227 unsigned char Visibility = ESym->getVisibility();
229 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
230 // visibility is either DEFAULT or PROTECTED. All other symbols are not
232 if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
233 (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED))
239 // This flag is used for classof, to distinguish ELFObjectFile from
240 // its subclass. If more subclasses will be created, this flag will
241 // have to become an enum.
242 bool isDyldELFObject;
245 ELFObjectFile(MemoryBufferRef Object, std::error_code &EC);
247 const Elf_Sym *getSymbol(DataRefImpl Symb) const;
249 basic_symbol_iterator symbol_begin_impl() const override;
250 basic_symbol_iterator symbol_end_impl() const override;
252 elf_symbol_iterator dynamic_symbol_begin() const;
253 elf_symbol_iterator dynamic_symbol_end() const;
255 section_iterator section_begin() const override;
256 section_iterator section_end() const override;
258 ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
259 bool hasRelocationAddend(DataRefImpl Rel) const override;
261 uint64_t getSectionFlags(SectionRef Sec) const override;
262 uint32_t getSectionType(SectionRef Sec) const override;
264 uint8_t getBytesInAddress() const override;
265 StringRef getFileFormatName() const override;
266 unsigned getArch() const override;
267 StringRef getLoadName() const;
269 std::error_code getPlatformFlags(unsigned &Result) const override {
270 Result = EF.getHeader()->e_flags;
271 return std::error_code();
274 const ELFFile<ELFT> *getELFFile() const { return &EF; }
276 bool isDyldType() const { return isDyldELFObject; }
277 static inline bool classof(const Binary *v) {
278 return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
282 elf_symbol_iterator_range getDynamicSymbolIterators() const override;
284 bool isRelocatableObject() const override;
287 typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
288 typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
289 typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
290 typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
292 template <class ELFT>
293 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
294 Symb = toDRI(++toELFSymIter(Symb));
297 template <class ELFT>
298 std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
299 StringRef &Result) const {
300 ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
302 return Name.getError();
304 return std::error_code();
307 template <class ELFT>
308 uint64_t ELFObjectFile<ELFT>::getSectionFlags(SectionRef Sec) const {
309 DataRefImpl DRI = Sec.getRawDataRefImpl();
310 return toELFShdrIter(DRI)->sh_flags;
313 template <class ELFT>
314 uint32_t ELFObjectFile<ELFT>::getSectionType(SectionRef Sec) const {
315 DataRefImpl DRI = Sec.getRawDataRefImpl();
316 return toELFShdrIter(DRI)->sh_type;
319 template <class ELFT>
320 uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
321 const Elf_Sym *ESym = getSymbol(Symb);
322 switch (ESym->st_shndx) {
323 case ELF::SHN_COMMON:
325 return UnknownAddress;
327 return ESym->st_value;
330 const Elf_Ehdr *Header = EF.getHeader();
331 uint64_t Ret = ESym->st_value;
333 // Clear the ARM/Thumb or microMIPS indicator flag.
334 if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
335 ESym->getType() == ELF::STT_FUNC)
341 template <class ELFT>
342 std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
343 uint64_t &Result) const {
344 Result = getSymbolValue(Symb);
345 const Elf_Sym *ESym = getSymbol(Symb);
346 switch (ESym->st_shndx) {
347 case ELF::SHN_COMMON:
350 return std::error_code();
353 const Elf_Ehdr *Header = EF.getHeader();
355 if (Header->e_type == ELF::ET_REL) {
356 const typename ELFFile<ELFT>::Elf_Shdr * Section = EF.getSection(ESym);
357 if (Section != nullptr)
358 Result += Section->sh_addr;
361 return std::error_code();
364 template <class ELFT>
365 uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
366 Elf_Sym_Iter Sym = toELFSymIter(Symb);
367 if (Sym->st_shndx == ELF::SHN_COMMON)
368 return Sym->st_value;
372 template <class ELFT>
373 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
374 return toELFSymIter(Sym)->st_size;
377 template <class ELFT>
378 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
379 return toELFSymIter(Symb)->st_size;
382 template <class ELFT>
383 std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb,
384 uint8_t &Result) const {
385 Result = toELFSymIter(Symb)->st_other;
386 return std::error_code();
389 template <class ELFT>
391 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
392 SymbolRef::Type &Result) const {
393 const Elf_Sym *ESym = getSymbol(Symb);
395 switch (ESym->getType()) {
396 case ELF::STT_NOTYPE:
397 Result = SymbolRef::ST_Unknown;
399 case ELF::STT_SECTION:
400 Result = SymbolRef::ST_Debug;
403 Result = SymbolRef::ST_File;
406 Result = SymbolRef::ST_Function;
408 case ELF::STT_OBJECT:
409 case ELF::STT_COMMON:
411 Result = SymbolRef::ST_Data;
414 Result = SymbolRef::ST_Other;
417 return std::error_code();
420 template <class ELFT>
421 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
422 Elf_Sym_Iter EIter = toELFSymIter(Symb);
423 const Elf_Sym *ESym = &*EIter;
425 uint32_t Result = SymbolRef::SF_None;
427 if (ESym->getBinding() != ELF::STB_LOCAL)
428 Result |= SymbolRef::SF_Global;
430 if (ESym->getBinding() == ELF::STB_WEAK)
431 Result |= SymbolRef::SF_Weak;
433 if (ESym->st_shndx == ELF::SHN_ABS)
434 Result |= SymbolRef::SF_Absolute;
436 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
437 EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols())
438 Result |= SymbolRef::SF_FormatSpecific;
440 if (EF.getHeader()->e_machine == ELF::EM_ARM) {
441 if (ErrorOr<StringRef> NameOrErr = EF.getSymbolName(EIter)) {
442 StringRef Name = *NameOrErr;
443 if (Name.startswith("$d") || Name.startswith("$t") ||
444 Name.startswith("$a"))
445 Result |= SymbolRef::SF_FormatSpecific;
449 if (ESym->st_shndx == ELF::SHN_UNDEF)
450 Result |= SymbolRef::SF_Undefined;
452 if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
453 Result |= SymbolRef::SF_Common;
455 if (isExportedToOtherDSO(ESym))
456 Result |= SymbolRef::SF_Exported;
458 if (ESym->getVisibility() == ELF::STV_HIDDEN)
459 Result |= SymbolRef::SF_Hidden;
464 template <class ELFT>
466 ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const {
467 const Elf_Shdr *ESec = EF.getSection(ESym);
469 return section_end();
472 Sec.p = reinterpret_cast<intptr_t>(ESec);
473 return section_iterator(SectionRef(Sec, this));
477 template <class ELFT>
479 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
480 section_iterator &Res) const {
481 Res = getSymbolSection(getSymbol(Symb));
482 return std::error_code();
485 template <class ELFT>
486 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
487 Sec = toDRI(++toELFShdrIter(Sec));
490 template <class ELFT>
491 std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
492 StringRef &Result) const {
493 ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
495 return Name.getError();
497 return std::error_code();
500 template <class ELFT>
501 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
502 return toELFShdrIter(Sec)->sh_addr;
505 template <class ELFT>
506 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
507 return toELFShdrIter(Sec)->sh_size;
510 template <class ELFT>
512 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
513 StringRef &Result) const {
514 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
515 Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
516 return std::error_code();
519 template <class ELFT>
520 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
521 return toELFShdrIter(Sec)->sh_addralign;
524 template <class ELFT>
525 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
526 return toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
529 template <class ELFT>
530 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
531 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
532 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
533 EShdr->sh_type == ELF::SHT_PROGBITS;
536 template <class ELFT>
537 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
538 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
539 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
540 EShdr->sh_type == ELF::SHT_NOBITS;
543 template <class ELFT>
544 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
545 return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
548 template <class ELFT>
549 bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
550 DataRefImpl Symb) const {
551 Elf_Sym_Iter ESym = toELFSymIter(Symb);
553 uintX_t Index = ESym->st_shndx;
554 bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
556 return !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
559 template <class ELFT>
561 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
563 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
564 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
566 return relocation_iterator(RelocationRef(RelData, this));
569 template <class ELFT>
571 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
573 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
574 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
575 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
576 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
579 RelData.d.b = S->sh_size / S->sh_entsize;
581 return relocation_iterator(RelocationRef(RelData, this));
584 template <class ELFT>
586 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
587 if (EF.getHeader()->e_type != ELF::ET_REL)
588 return section_end();
590 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
591 uintX_t Type = EShdr->sh_type;
592 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
593 return section_end();
595 const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
596 return section_iterator(SectionRef(toDRI(R), this));
600 template <class ELFT>
601 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
605 template <class ELFT>
607 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
609 const Elf_Shdr *sec = getRelSection(Rel);
610 switch (sec->sh_type) {
612 report_fatal_error("Invalid section type in Rel!");
614 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
617 case ELF::SHT_RELA: {
618 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
625 const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
627 DataRefImpl SymbolData;
628 switch (SymSec->sh_type) {
630 report_fatal_error("Invalid symbol table section type!");
631 case ELF::SHT_SYMTAB:
632 SymbolData = toDRI(EF.begin_symbols() + symbolIdx);
634 case ELF::SHT_DYNSYM:
635 SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx);
639 return symbol_iterator(SymbolRef(SymbolData, this));
642 template <class ELFT>
644 ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
645 uint64_t &Result) const {
646 uint64_t ROffset = getROffset(Rel);
647 const Elf_Ehdr *Header = EF.getHeader();
649 if (Header->e_type == ELF::ET_REL) {
650 const Elf_Shdr *RelocationSec = getRelSection(Rel);
651 const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
652 Result = ROffset + RelocatedSec->sh_addr;
657 return std::error_code();
660 template <class ELFT>
662 ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
663 uint64_t &Result) const {
664 assert(EF.getHeader()->e_type == ELF::ET_REL &&
665 "Only relocatable object files have relocation offsets");
666 Result = getROffset(Rel);
667 return std::error_code();
670 template <class ELFT>
671 uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
672 const Elf_Shdr *sec = getRelSection(Rel);
673 switch (sec->sh_type) {
675 report_fatal_error("Invalid section type in Rel!");
677 return getRel(Rel)->r_offset;
679 return getRela(Rel)->r_offset;
683 template <class ELFT>
684 std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
685 uint64_t &Result) const {
686 const Elf_Shdr *sec = getRelSection(Rel);
687 switch (sec->sh_type) {
689 report_fatal_error("Invalid section type in Rel!");
691 Result = getRel(Rel)->getType(EF.isMips64EL());
694 case ELF::SHT_RELA: {
695 Result = getRela(Rel)->getType(EF.isMips64EL());
699 return std::error_code();
702 template <class ELFT>
703 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
704 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
707 template <class ELFT>
708 std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
709 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
710 const Elf_Shdr *sec = getRelSection(Rel);
712 switch (sec->sh_type) {
714 return object_error::parse_failed;
716 type = getRel(Rel)->getType(EF.isMips64EL());
719 case ELF::SHT_RELA: {
720 type = getRela(Rel)->getType(EF.isMips64EL());
725 EF.getRelocationTypeName(type, Result);
726 return std::error_code();
729 template <class ELFT>
731 ELFObjectFile<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;
737 template <class ELFT>
738 bool ELFObjectFile<ELFT>::hasRelocationAddend(DataRefImpl Rel) const {
739 return getRelSection(Rel)->sh_type == ELF::SHT_RELA;
742 template <class ELFT>
743 const typename ELFFile<ELFT>::Elf_Sym *
744 ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
745 return &*toELFSymIter(Symb);
748 template <class ELFT>
749 const typename ELFObjectFile<ELFT>::Elf_Rel *
750 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
751 return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
754 template <class ELFT>
755 const typename ELFObjectFile<ELFT>::Elf_Rela *
756 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
757 return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
760 template <class ELFT>
761 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
763 getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
767 EF(Data.getBuffer(), EC) {}
769 template <class ELFT>
770 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
771 return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
774 template <class ELFT>
775 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
776 return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
779 template <class ELFT>
780 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
781 return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
784 template <class ELFT>
785 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
786 return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
789 template <class ELFT>
790 section_iterator ELFObjectFile<ELFT>::section_begin() const {
791 return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
794 template <class ELFT>
795 section_iterator ELFObjectFile<ELFT>::section_end() const {
796 return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
799 template <class ELFT>
800 StringRef ELFObjectFile<ELFT>::getLoadName() const {
801 Elf_Dyn_Iter DI = EF.begin_dynamic_table();
802 Elf_Dyn_Iter DE = EF.end_dynamic_table();
804 while (DI != DE && DI->getTag() != ELF::DT_SONAME)
808 return EF.getDynamicString(DI->getVal());
812 template <class ELFT>
813 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
814 return ELFT::Is64Bits ? 8 : 4;
817 template <class ELFT>
818 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
819 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
820 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
821 case ELF::ELFCLASS32:
822 switch (EF.getHeader()->e_machine) {
826 return "ELF32-x86-64";
828 return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
829 case ELF::EM_HEXAGON:
830 return "ELF32-hexagon";
836 case ELF::EM_SPARC32PLUS:
837 return "ELF32-sparc";
839 return "ELF32-unknown";
841 case ELF::ELFCLASS64:
842 switch (EF.getHeader()->e_machine) {
846 return "ELF64-x86-64";
847 case ELF::EM_AARCH64:
848 return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
850 return "ELF64-ppc64";
853 case ELF::EM_SPARCV9:
854 return "ELF64-sparc";
858 return "ELF64-unknown";
861 // FIXME: Proper error handling.
862 report_fatal_error("Invalid ELFCLASS!");
866 template <class ELFT>
867 unsigned ELFObjectFile<ELFT>::getArch() const {
868 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
869 switch (EF.getHeader()->e_machine) {
873 return Triple::x86_64;
874 case ELF::EM_AARCH64:
875 return Triple::aarch64;
878 case ELF::EM_HEXAGON:
879 return Triple::hexagon;
881 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
882 case ELF::ELFCLASS32:
883 return IsLittleEndian ? Triple::mipsel : Triple::mips;
884 case ELF::ELFCLASS64:
885 return IsLittleEndian ? Triple::mips64el : Triple::mips64;
887 report_fatal_error("Invalid ELFCLASS!");
892 return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
894 return Triple::systemz;
897 case ELF::EM_SPARC32PLUS:
898 return IsLittleEndian ? Triple::sparcel : Triple::sparc;
899 case ELF::EM_SPARCV9:
900 return Triple::sparcv9;
903 return Triple::UnknownArch;
907 template <class ELFT>
908 ELFObjectFileBase::elf_symbol_iterator_range
909 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
910 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
913 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
914 return EF.getHeader()->e_type == ELF::ET_REL;