1 //===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file declares the ELFObjectFile template class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
14 #define LLVM_OBJECT_ELFOBJECTFILE_H
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/STLExtras.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/Casting.h"
32 #include "llvm/Support/ELFAttributes.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"
39 #include <system_error>
44 constexpr int NumElfSymbolTypes = 16;
45 extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
47 class elf_symbol_iterator;
49 class ELFObjectFileBase : public ObjectFile {
50 friend class ELFRelocationRef;
51 friend class ELFSectionRef;
52 friend class ELFSymbolRef;
55 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
57 virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
58 virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
59 virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
60 virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
62 virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
63 virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
64 virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
66 virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
67 virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
70 using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
72 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
74 /// Returns platform-specific object flags, if any.
75 virtual unsigned getPlatformFlags() const = 0;
77 elf_symbol_iterator_range symbols() const;
79 static bool classof(const Binary *v) { return v->isELF(); }
81 SubtargetFeatures getFeatures() const override;
83 SubtargetFeatures getMIPSFeatures() const;
85 SubtargetFeatures getARMFeatures() const;
87 SubtargetFeatures getRISCVFeatures() const;
89 void setARMSubArch(Triple &TheTriple) const override;
91 virtual uint16_t getEType() const = 0;
93 virtual uint16_t getEMachine() const = 0;
95 std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
98 class ELFSectionRef : public SectionRef {
100 ELFSectionRef(const SectionRef &B) : SectionRef(B) {
101 assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
104 const ELFObjectFileBase *getObject() const {
105 return cast<ELFObjectFileBase>(SectionRef::getObject());
108 uint32_t getType() const {
109 return getObject()->getSectionType(getRawDataRefImpl());
112 uint64_t getFlags() const {
113 return getObject()->getSectionFlags(getRawDataRefImpl());
116 uint64_t getOffset() const {
117 return getObject()->getSectionOffset(getRawDataRefImpl());
121 class elf_section_iterator : public section_iterator {
123 elf_section_iterator(const section_iterator &B) : section_iterator(B) {
124 assert(isa<ELFObjectFileBase>(B->getObject()));
127 const ELFSectionRef *operator->() const {
128 return static_cast<const ELFSectionRef *>(section_iterator::operator->());
131 const ELFSectionRef &operator*() const {
132 return static_cast<const ELFSectionRef &>(section_iterator::operator*());
136 class ELFSymbolRef : public SymbolRef {
138 ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
139 assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
142 const ELFObjectFileBase *getObject() const {
143 return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
146 uint64_t getSize() const {
147 return getObject()->getSymbolSize(getRawDataRefImpl());
150 uint8_t getBinding() const {
151 return getObject()->getSymbolBinding(getRawDataRefImpl());
154 uint8_t getOther() const {
155 return getObject()->getSymbolOther(getRawDataRefImpl());
158 uint8_t getELFType() const {
159 return getObject()->getSymbolELFType(getRawDataRefImpl());
162 StringRef getELFTypeName() const {
163 uint8_t Type = getELFType();
164 for (auto &EE : ElfSymbolTypes) {
165 if (EE.Value == Type) {
173 class elf_symbol_iterator : public symbol_iterator {
175 elf_symbol_iterator(const basic_symbol_iterator &B)
176 : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
177 cast<ELFObjectFileBase>(B->getObject()))) {}
179 const ELFSymbolRef *operator->() const {
180 return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
183 const ELFSymbolRef &operator*() const {
184 return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
188 class ELFRelocationRef : public RelocationRef {
190 ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
191 assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
194 const ELFObjectFileBase *getObject() const {
195 return cast<ELFObjectFileBase>(RelocationRef::getObject());
198 Expected<int64_t> getAddend() const {
199 return getObject()->getRelocationAddend(getRawDataRefImpl());
203 class elf_relocation_iterator : public relocation_iterator {
205 elf_relocation_iterator(const relocation_iterator &B)
206 : relocation_iterator(RelocationRef(
207 B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
209 const ELFRelocationRef *operator->() const {
210 return static_cast<const ELFRelocationRef *>(
211 relocation_iterator::operator->());
214 const ELFRelocationRef &operator*() const {
215 return static_cast<const ELFRelocationRef &>(
216 relocation_iterator::operator*());
220 inline ELFObjectFileBase::elf_symbol_iterator_range
221 ELFObjectFileBase::symbols() const {
222 return elf_symbol_iterator_range(symbol_begin(), symbol_end());
225 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
226 uint16_t getEMachine() const override;
227 uint16_t getEType() const override;
228 uint64_t getSymbolSize(DataRefImpl Sym) const override;
231 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
233 using uintX_t = typename ELFT::uint;
235 using Elf_Sym = typename ELFT::Sym;
236 using Elf_Shdr = typename ELFT::Shdr;
237 using Elf_Ehdr = typename ELFT::Ehdr;
238 using Elf_Rel = typename ELFT::Rel;
239 using Elf_Rela = typename ELFT::Rela;
240 using Elf_Dyn = typename ELFT::Dyn;
242 SectionRef toSectionRef(const Elf_Shdr *Sec) const {
243 return SectionRef(toDRI(Sec), this);
247 ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
248 const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
249 ArrayRef<Elf_Word> ShndxTable);
254 const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
255 const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
256 ArrayRef<Elf_Word> ShndxTable;
258 void moveSymbolNext(DataRefImpl &Symb) const override;
259 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
260 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
261 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
262 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
263 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
264 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
265 uint8_t getSymbolBinding(DataRefImpl Symb) const override;
266 uint8_t getSymbolOther(DataRefImpl Symb) const override;
267 uint8_t getSymbolELFType(DataRefImpl Symb) const override;
268 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
269 Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
270 const Elf_Shdr *SymTab) const;
271 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
273 void moveSectionNext(DataRefImpl &Sec) const override;
274 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
275 uint64_t getSectionAddress(DataRefImpl Sec) const override;
276 uint64_t getSectionIndex(DataRefImpl Sec) const override;
277 uint64_t getSectionSize(DataRefImpl Sec) const override;
278 Expected<ArrayRef<uint8_t>>
279 getSectionContents(DataRefImpl Sec) const override;
280 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
281 bool isSectionCompressed(DataRefImpl Sec) const override;
282 bool isSectionText(DataRefImpl Sec) const override;
283 bool isSectionData(DataRefImpl Sec) const override;
284 bool isSectionBSS(DataRefImpl Sec) const override;
285 bool isSectionVirtual(DataRefImpl Sec) const override;
286 bool isBerkeleyText(DataRefImpl Sec) const override;
287 bool isBerkeleyData(DataRefImpl Sec) const override;
288 bool isDebugSection(StringRef SectionName) const override;
289 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
290 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
291 std::vector<SectionRef> dynamic_relocation_sections() const override;
292 Expected<section_iterator>
293 getRelocatedSection(DataRefImpl Sec) const override;
295 void moveRelocationNext(DataRefImpl &Rel) const override;
296 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
297 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
298 uint64_t getRelocationType(DataRefImpl Rel) const override;
299 void getRelocationTypeName(DataRefImpl Rel,
300 SmallVectorImpl<char> &Result) const override;
302 uint32_t getSectionType(DataRefImpl Sec) const override;
303 uint64_t getSectionFlags(DataRefImpl Sec) const override;
304 uint64_t getSectionOffset(DataRefImpl Sec) const override;
305 StringRef getRelocationTypeName(uint32_t Type) const;
307 /// Get the relocation section that contains \a Rel.
308 const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
309 auto RelSecOrErr = EF.getSection(Rel.d.a);
311 report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
315 DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
322 assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
323 SymTable->sh_type == ELF::SHT_DYNSYM);
325 auto SectionsOrErr = EF.sections();
326 if (!SectionsOrErr) {
331 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
332 unsigned SymTableIndex =
333 (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
335 DRI.d.a = SymTableIndex;
340 const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
341 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
344 DataRefImpl toDRI(const Elf_Shdr *Sec) const {
346 DRI.p = reinterpret_cast<uintptr_t>(Sec);
350 DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
352 DRI.p = reinterpret_cast<uintptr_t>(Dyn);
356 bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
357 unsigned char Binding = ESym->getBinding();
358 unsigned char Visibility = ESym->getVisibility();
360 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
361 // visibility is either DEFAULT or PROTECTED. All other symbols are not
364 (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK ||
365 Binding == ELF::STB_GNU_UNIQUE) &&
366 (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
369 Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
370 auto SectionsOrErr = EF.sections();
372 return SectionsOrErr.takeError();
374 for (const Elf_Shdr &Sec : *SectionsOrErr) {
375 if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
376 Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
377 auto ErrorOrContents = EF.getSectionContents(&Sec);
378 if (!ErrorOrContents)
379 return ErrorOrContents.takeError();
381 auto Contents = ErrorOrContents.get();
382 if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
383 return Error::success();
385 if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
390 return Error::success();
393 // This flag is used for classof, to distinguish ELFObjectFile from
394 // its subclass. If more subclasses will be created, this flag will
395 // have to become an enum.
396 bool isDyldELFObject;
399 ELFObjectFile(ELFObjectFile<ELFT> &&Other);
400 static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
402 const Elf_Rel *getRel(DataRefImpl Rel) const;
403 const Elf_Rela *getRela(DataRefImpl Rela) const;
405 const Elf_Sym *getSymbol(DataRefImpl Sym) const {
406 auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
408 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
412 const Elf_Shdr *getSection(DataRefImpl Sec) const {
413 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
416 basic_symbol_iterator symbol_begin() const override;
417 basic_symbol_iterator symbol_end() const override;
419 elf_symbol_iterator dynamic_symbol_begin() const;
420 elf_symbol_iterator dynamic_symbol_end() const;
422 section_iterator section_begin() const override;
423 section_iterator section_end() const override;
425 Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
427 uint8_t getBytesInAddress() const override;
428 StringRef getFileFormatName() const override;
429 Triple::ArchType getArch() const override;
430 Expected<uint64_t> getStartAddress() const override;
432 unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
434 const ELFFile<ELFT> *getELFFile() const { return &EF; }
436 bool isDyldType() const { return isDyldELFObject; }
437 static bool classof(const Binary *v) {
438 return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
442 elf_symbol_iterator_range getDynamicSymbolIterators() const override;
444 bool isRelocatableObject() const override;
447 using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
448 using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
449 using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
450 using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
452 template <class ELFT>
453 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
457 template <class ELFT>
458 Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
459 const Elf_Sym *ESym = getSymbol(Sym);
460 auto SymTabOrErr = EF.getSection(Sym.d.a);
462 return SymTabOrErr.takeError();
463 const Elf_Shdr *SymTableSec = *SymTabOrErr;
464 auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
466 return StrTabOrErr.takeError();
467 const Elf_Shdr *StringTableSec = *StrTabOrErr;
468 auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
470 return SymStrTabOrErr.takeError();
471 Expected<StringRef> Name = ESym->getName(*SymStrTabOrErr);
472 if (Name && !Name->empty())
475 // If the symbol name is empty use the section name.
476 if (ESym->getType() == ELF::STT_SECTION) {
477 if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
478 consumeError(Name.takeError());
479 return (*SecOrErr)->getName();
485 template <class ELFT>
486 uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
487 return getSection(Sec)->sh_flags;
490 template <class ELFT>
491 uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
492 return getSection(Sec)->sh_type;
495 template <class ELFT>
496 uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
497 return getSection(Sec)->sh_offset;
500 template <class ELFT>
501 uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
502 const Elf_Sym *ESym = getSymbol(Symb);
503 uint64_t Ret = ESym->st_value;
504 if (ESym->st_shndx == ELF::SHN_ABS)
507 const Elf_Ehdr *Header = EF.getHeader();
508 // Clear the ARM/Thumb or microMIPS indicator flag.
509 if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
510 ESym->getType() == ELF::STT_FUNC)
516 template <class ELFT>
518 ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
519 Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
520 if (!SymbolValueOrErr)
521 // TODO: Test this error.
522 return SymbolValueOrErr.takeError();
524 uint64_t Result = *SymbolValueOrErr;
525 const Elf_Sym *ESym = getSymbol(Symb);
526 switch (ESym->st_shndx) {
527 case ELF::SHN_COMMON:
533 const Elf_Ehdr *Header = EF.getHeader();
534 auto SymTabOrErr = EF.getSection(Symb.d.a);
536 return SymTabOrErr.takeError();
537 const Elf_Shdr *SymTab = *SymTabOrErr;
539 if (Header->e_type == ELF::ET_REL) {
540 auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
542 return SectionOrErr.takeError();
543 const Elf_Shdr *Section = *SectionOrErr;
545 Result += Section->sh_addr;
551 template <class ELFT>
552 uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
553 const Elf_Sym *Sym = getSymbol(Symb);
554 if (Sym->st_shndx == ELF::SHN_COMMON)
555 return Sym->st_value;
559 template <class ELFT>
560 uint16_t ELFObjectFile<ELFT>::getEMachine() const {
561 return EF.getHeader()->e_machine;
564 template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
565 return EF.getHeader()->e_type;
568 template <class ELFT>
569 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
570 return getSymbol(Sym)->st_size;
573 template <class ELFT>
574 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
575 return getSymbol(Symb)->st_size;
578 template <class ELFT>
579 uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
580 return getSymbol(Symb)->getBinding();
583 template <class ELFT>
584 uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
585 return getSymbol(Symb)->st_other;
588 template <class ELFT>
589 uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
590 return getSymbol(Symb)->getType();
593 template <class ELFT>
594 Expected<SymbolRef::Type>
595 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
596 const Elf_Sym *ESym = getSymbol(Symb);
598 switch (ESym->getType()) {
599 case ELF::STT_NOTYPE:
600 return SymbolRef::ST_Unknown;
601 case ELF::STT_SECTION:
602 return SymbolRef::ST_Debug;
604 return SymbolRef::ST_File;
606 return SymbolRef::ST_Function;
607 case ELF::STT_OBJECT:
608 case ELF::STT_COMMON:
610 return SymbolRef::ST_Data;
612 return SymbolRef::ST_Other;
616 template <class ELFT>
617 Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
618 const Elf_Sym *ESym = getSymbol(Sym);
620 uint32_t Result = SymbolRef::SF_None;
622 if (ESym->getBinding() != ELF::STB_LOCAL)
623 Result |= SymbolRef::SF_Global;
625 if (ESym->getBinding() == ELF::STB_WEAK)
626 Result |= SymbolRef::SF_Weak;
628 if (ESym->st_shndx == ELF::SHN_ABS)
629 Result |= SymbolRef::SF_Absolute;
631 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
632 Result |= SymbolRef::SF_FormatSpecific;
634 if (Expected<typename ELFT::SymRange> SymbolsOrErr =
635 EF.symbols(DotSymtabSec)) {
636 // Set the SF_FormatSpecific flag for the 0-index null symbol.
637 if (ESym == SymbolsOrErr->begin())
638 Result |= SymbolRef::SF_FormatSpecific;
640 // TODO: Test this error.
641 return SymbolsOrErr.takeError();
643 if (Expected<typename ELFT::SymRange> SymbolsOrErr =
644 EF.symbols(DotDynSymSec)) {
645 // Set the SF_FormatSpecific flag for the 0-index null symbol.
646 if (ESym == SymbolsOrErr->begin())
647 Result |= SymbolRef::SF_FormatSpecific;
649 // TODO: Test this error.
650 return SymbolsOrErr.takeError();
652 if (EF.getHeader()->e_machine == ELF::EM_ARM) {
653 if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
654 StringRef Name = *NameOrErr;
655 if (Name.startswith("$d") || Name.startswith("$t") ||
656 Name.startswith("$a"))
657 Result |= SymbolRef::SF_FormatSpecific;
659 // TODO: Actually report errors helpfully.
660 consumeError(NameOrErr.takeError());
662 if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
663 Result |= SymbolRef::SF_Thumb;
666 if (ESym->st_shndx == ELF::SHN_UNDEF)
667 Result |= SymbolRef::SF_Undefined;
669 if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
670 Result |= SymbolRef::SF_Common;
672 if (isExportedToOtherDSO(ESym))
673 Result |= SymbolRef::SF_Exported;
675 if (ESym->getVisibility() == ELF::STV_HIDDEN)
676 Result |= SymbolRef::SF_Hidden;
681 template <class ELFT>
682 Expected<section_iterator>
683 ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
684 const Elf_Shdr *SymTab) const {
685 auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
687 return ESecOrErr.takeError();
689 const Elf_Shdr *ESec = *ESecOrErr;
691 return section_end();
694 Sec.p = reinterpret_cast<intptr_t>(ESec);
695 return section_iterator(SectionRef(Sec, this));
698 template <class ELFT>
699 Expected<section_iterator>
700 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
701 const Elf_Sym *Sym = getSymbol(Symb);
702 auto SymTabOrErr = EF.getSection(Symb.d.a);
704 return SymTabOrErr.takeError();
705 const Elf_Shdr *SymTab = *SymTabOrErr;
706 return getSymbolSection(Sym, SymTab);
709 template <class ELFT>
710 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
711 const Elf_Shdr *ESec = getSection(Sec);
715 template <class ELFT>
716 Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
717 return EF.getSectionName(&*getSection(Sec));
720 template <class ELFT>
721 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
722 return getSection(Sec)->sh_addr;
725 template <class ELFT>
726 uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
727 auto SectionsOrErr = EF.sections();
728 handleAllErrors(std::move(SectionsOrErr.takeError()),
729 [](const ErrorInfoBase &) {
730 llvm_unreachable("unable to get section index");
732 const Elf_Shdr *First = SectionsOrErr->begin();
733 return getSection(Sec) - First;
736 template <class ELFT>
737 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
738 return getSection(Sec)->sh_size;
741 template <class ELFT>
742 Expected<ArrayRef<uint8_t>>
743 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
744 const Elf_Shdr *EShdr = getSection(Sec);
745 if (EShdr->sh_type == ELF::SHT_NOBITS)
746 return makeArrayRef((const uint8_t *)base(), 0);
748 checkOffset(getMemoryBufferRef(),
749 (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
751 return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
755 template <class ELFT>
756 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
757 return getSection(Sec)->sh_addralign;
760 template <class ELFT>
761 bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
762 return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
765 template <class ELFT>
766 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
767 return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
770 template <class ELFT>
771 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
772 const Elf_Shdr *EShdr = getSection(Sec);
773 return EShdr->sh_type == ELF::SHT_PROGBITS &&
774 EShdr->sh_flags & ELF::SHF_ALLOC &&
775 !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
778 template <class ELFT>
779 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
780 const Elf_Shdr *EShdr = getSection(Sec);
781 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
782 EShdr->sh_type == ELF::SHT_NOBITS;
785 template <class ELFT>
786 std::vector<SectionRef>
787 ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
788 std::vector<SectionRef> Res;
789 std::vector<uintptr_t> Offsets;
791 auto SectionsOrErr = EF.sections();
795 for (const Elf_Shdr &Sec : *SectionsOrErr) {
796 if (Sec.sh_type != ELF::SHT_DYNAMIC)
799 reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
800 for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
801 if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
802 Dynamic->d_tag == ELF::DT_JMPREL) {
803 Offsets.push_back(Dynamic->d_un.d_val);
807 for (const Elf_Shdr &Sec : *SectionsOrErr) {
808 if (is_contained(Offsets, Sec.sh_addr))
809 Res.emplace_back(toDRI(&Sec), this);
814 template <class ELFT>
815 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
816 return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
819 template <class ELFT>
820 bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
821 return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
822 (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
823 !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
826 template <class ELFT>
827 bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
828 const Elf_Shdr *EShdr = getSection(Sec);
829 return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
830 EShdr->sh_flags & ELF::SHF_ALLOC;
833 template <class ELFT>
834 bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const {
835 return SectionName.startswith(".debug") ||
836 SectionName.startswith(".zdebug") || SectionName == ".gdb_index";
839 template <class ELFT>
841 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
843 auto SectionsOrErr = EF.sections();
845 return relocation_iterator(RelocationRef());
846 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
847 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
849 return relocation_iterator(RelocationRef(RelData, this));
852 template <class ELFT>
854 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
855 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
856 relocation_iterator Begin = section_rel_begin(Sec);
857 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
859 DataRefImpl RelData = Begin->getRawDataRefImpl();
860 const Elf_Shdr *RelSec = getRelSection(RelData);
862 // Error check sh_link here so that getRelocationSymbol can just use it.
863 auto SymSecOrErr = EF.getSection(RelSec->sh_link);
865 report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
867 RelData.d.b += S->sh_size / S->sh_entsize;
868 return relocation_iterator(RelocationRef(RelData, this));
871 template <class ELFT>
872 Expected<section_iterator>
873 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
874 if (EF.getHeader()->e_type != ELF::ET_REL)
875 return section_end();
877 const Elf_Shdr *EShdr = getSection(Sec);
878 uintX_t Type = EShdr->sh_type;
879 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
880 return section_end();
882 Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
884 return SecOrErr.takeError();
885 return section_iterator(SectionRef(toDRI(*SecOrErr), this));
889 template <class ELFT>
890 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
894 template <class ELFT>
896 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
898 const Elf_Shdr *sec = getRelSection(Rel);
899 if (sec->sh_type == ELF::SHT_REL)
900 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
902 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
906 // FIXME: error check symbolIdx
907 DataRefImpl SymbolData;
908 SymbolData.d.a = sec->sh_link;
909 SymbolData.d.b = symbolIdx;
910 return symbol_iterator(SymbolRef(SymbolData, this));
913 template <class ELFT>
914 uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
915 const Elf_Shdr *sec = getRelSection(Rel);
916 if (sec->sh_type == ELF::SHT_REL)
917 return getRel(Rel)->r_offset;
919 return getRela(Rel)->r_offset;
922 template <class ELFT>
923 uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
924 const Elf_Shdr *sec = getRelSection(Rel);
925 if (sec->sh_type == ELF::SHT_REL)
926 return getRel(Rel)->getType(EF.isMips64EL());
928 return getRela(Rel)->getType(EF.isMips64EL());
931 template <class ELFT>
932 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
933 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
936 template <class ELFT>
937 void ELFObjectFile<ELFT>::getRelocationTypeName(
938 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
939 uint32_t type = getRelocationType(Rel);
940 EF.getRelocationTypeName(type, Result);
943 template <class ELFT>
945 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
946 if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
947 return createError("Section is not SHT_RELA");
948 return (int64_t)getRela(Rel)->r_addend;
951 template <class ELFT>
952 const typename ELFObjectFile<ELFT>::Elf_Rel *
953 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
954 assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
955 auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
957 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
961 template <class ELFT>
962 const typename ELFObjectFile<ELFT>::Elf_Rela *
963 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
964 assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
965 auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
967 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
971 template <class ELFT>
972 Expected<ELFObjectFile<ELFT>>
973 ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
974 auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
975 if (Error E = EFOrErr.takeError())
977 auto EF = std::move(*EFOrErr);
979 auto SectionsOrErr = EF.sections();
981 return SectionsOrErr.takeError();
983 const Elf_Shdr *DotDynSymSec = nullptr;
984 const Elf_Shdr *DotSymtabSec = nullptr;
985 ArrayRef<Elf_Word> ShndxTable;
986 for (const Elf_Shdr &Sec : *SectionsOrErr) {
987 switch (Sec.sh_type) {
988 case ELF::SHT_DYNSYM: {
993 case ELF::SHT_SYMTAB: {
998 case ELF::SHT_SYMTAB_SHNDX: {
999 auto TableOrErr = EF.getSHNDXTable(Sec);
1001 return TableOrErr.takeError();
1002 ShndxTable = *TableOrErr;
1007 return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
1011 template <class ELFT>
1012 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
1013 const Elf_Shdr *DotDynSymSec,
1014 const Elf_Shdr *DotSymtabSec,
1015 ArrayRef<Elf_Word> ShndxTable)
1016 : ELFObjectFileBase(
1017 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
1019 EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
1020 ShndxTable(ShndxTable) {}
1022 template <class ELFT>
1023 ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
1024 : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
1025 Other.DotSymtabSec, Other.ShndxTable) {}
1027 template <class ELFT>
1028 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
1031 DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
1032 return basic_symbol_iterator(SymbolRef(Sym, this));
1035 template <class ELFT>
1036 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
1037 const Elf_Shdr *SymTab = DotSymtabSec;
1039 return symbol_begin();
1040 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1041 return basic_symbol_iterator(SymbolRef(Sym, this));
1044 template <class ELFT>
1045 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
1046 if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
1047 // Ignore errors here where the dynsym is empty or sh_size less than the
1048 // size of one symbol. These should be handled elsewhere.
1049 return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
1050 // Skip 0-index NULL symbol.
1051 return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
1054 template <class ELFT>
1055 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
1056 const Elf_Shdr *SymTab = DotDynSymSec;
1058 return dynamic_symbol_begin();
1059 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1060 return basic_symbol_iterator(SymbolRef(Sym, this));
1063 template <class ELFT>
1064 section_iterator ELFObjectFile<ELFT>::section_begin() const {
1065 auto SectionsOrErr = EF.sections();
1067 return section_iterator(SectionRef());
1068 return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
1071 template <class ELFT>
1072 section_iterator ELFObjectFile<ELFT>::section_end() const {
1073 auto SectionsOrErr = EF.sections();
1075 return section_iterator(SectionRef());
1076 return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
1079 template <class ELFT>
1080 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
1081 return ELFT::Is64Bits ? 8 : 4;
1084 template <class ELFT>
1085 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
1086 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1087 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1088 case ELF::ELFCLASS32:
1089 switch (EF.getHeader()->e_machine) {
1091 return "elf32-i386";
1093 return "elf32-iamcu";
1094 case ELF::EM_X86_64:
1095 return "elf32-x86-64";
1097 return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
1100 case ELF::EM_HEXAGON:
1101 return "elf32-hexagon";
1103 return "elf32-lanai";
1105 return "elf32-mips";
1106 case ELF::EM_MSP430:
1107 return "elf32-msp430";
1109 return "elf32-powerpc";
1111 return "elf32-littleriscv";
1113 case ELF::EM_SPARC32PLUS:
1114 return "elf32-sparc";
1115 case ELF::EM_AMDGPU:
1116 return "elf32-amdgpu";
1118 return "elf32-unknown";
1120 case ELF::ELFCLASS64:
1121 switch (EF.getHeader()->e_machine) {
1123 return "elf64-i386";
1124 case ELF::EM_X86_64:
1125 return "elf64-x86-64";
1126 case ELF::EM_AARCH64:
1127 return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
1129 return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
1131 return "elf64-littleriscv";
1133 return "elf64-s390";
1134 case ELF::EM_SPARCV9:
1135 return "elf64-sparc";
1137 return "elf64-mips";
1138 case ELF::EM_AMDGPU:
1139 return "elf64-amdgpu";
1145 return "elf64-unknown";
1148 // FIXME: Proper error handling.
1149 report_fatal_error("Invalid ELFCLASS!");
1153 template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
1154 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1155 switch (EF.getHeader()->e_machine) {
1159 case ELF::EM_X86_64:
1160 return Triple::x86_64;
1161 case ELF::EM_AARCH64:
1162 return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
1167 case ELF::EM_HEXAGON:
1168 return Triple::hexagon;
1170 return Triple::lanai;
1172 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1173 case ELF::ELFCLASS32:
1174 return IsLittleEndian ? Triple::mipsel : Triple::mips;
1175 case ELF::ELFCLASS64:
1176 return IsLittleEndian ? Triple::mips64el : Triple::mips64;
1178 report_fatal_error("Invalid ELFCLASS!");
1180 case ELF::EM_MSP430:
1181 return Triple::msp430;
1185 return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
1187 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1188 case ELF::ELFCLASS32:
1189 return Triple::riscv32;
1190 case ELF::ELFCLASS64:
1191 return Triple::riscv64;
1193 report_fatal_error("Invalid ELFCLASS!");
1196 return Triple::systemz;
1199 case ELF::EM_SPARC32PLUS:
1200 return IsLittleEndian ? Triple::sparcel : Triple::sparc;
1201 case ELF::EM_SPARCV9:
1202 return Triple::sparcv9;
1204 case ELF::EM_AMDGPU: {
1205 if (!IsLittleEndian)
1206 return Triple::UnknownArch;
1208 unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
1209 if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
1210 MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
1211 return Triple::r600;
1212 if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
1213 MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
1214 return Triple::amdgcn;
1216 return Triple::UnknownArch;
1220 return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
1225 return Triple::UnknownArch;
1229 template <class ELFT>
1230 Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
1231 return EF.getHeader()->e_entry;
1234 template <class ELFT>
1235 ELFObjectFileBase::elf_symbol_iterator_range
1236 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
1237 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1240 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
1241 return EF.getHeader()->e_type == ELF::ET_REL;
1244 } // end namespace object
1245 } // end namespace llvm
1247 #endif // LLVM_OBJECT_ELFOBJECTFILE_H