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/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"
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(ARMAttributeParser
&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
;
243 ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
244 const Elf_Shdr
*DotDynSymSec
, const Elf_Shdr
*DotSymtabSec
,
245 ArrayRef
<Elf_Word
> ShndxTable
);
250 const Elf_Shdr
*DotDynSymSec
= nullptr; // Dynamic symbol table section.
251 const Elf_Shdr
*DotSymtabSec
= nullptr; // Symbol table section.
252 ArrayRef
<Elf_Word
> ShndxTable
;
254 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
255 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
256 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
257 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
258 uint32_t getSymbolAlignment(DataRefImpl Symb
) const override
;
259 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
260 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
261 uint8_t getSymbolBinding(DataRefImpl Symb
) const override
;
262 uint8_t getSymbolOther(DataRefImpl Symb
) const override
;
263 uint8_t getSymbolELFType(DataRefImpl Symb
) const override
;
264 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
265 Expected
<section_iterator
> getSymbolSection(const Elf_Sym
*Symb
,
266 const Elf_Shdr
*SymTab
) const;
267 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
269 void moveSectionNext(DataRefImpl
&Sec
) const override
;
270 Expected
<StringRef
> getSectionName(DataRefImpl Sec
) const override
;
271 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
272 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
273 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
274 Expected
<ArrayRef
<uint8_t>>
275 getSectionContents(DataRefImpl Sec
) const override
;
276 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
277 bool isSectionCompressed(DataRefImpl Sec
) const override
;
278 bool isSectionText(DataRefImpl Sec
) const override
;
279 bool isSectionData(DataRefImpl Sec
) const override
;
280 bool isSectionBSS(DataRefImpl Sec
) const override
;
281 bool isSectionVirtual(DataRefImpl Sec
) const override
;
282 bool isBerkeleyText(DataRefImpl Sec
) const override
;
283 bool isBerkeleyData(DataRefImpl Sec
) const override
;
284 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
285 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
286 std::vector
<SectionRef
> dynamic_relocation_sections() const override
;
287 section_iterator
getRelocatedSection(DataRefImpl Sec
) const override
;
289 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
290 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
291 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
292 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
293 void getRelocationTypeName(DataRefImpl Rel
,
294 SmallVectorImpl
<char> &Result
) const override
;
296 uint32_t getSectionType(DataRefImpl Sec
) const override
;
297 uint64_t getSectionFlags(DataRefImpl Sec
) const override
;
298 uint64_t getSectionOffset(DataRefImpl Sec
) const override
;
299 StringRef
getRelocationTypeName(uint32_t Type
) const;
301 /// Get the relocation section that contains \a Rel.
302 const Elf_Shdr
*getRelSection(DataRefImpl Rel
) const {
303 auto RelSecOrErr
= EF
.getSection(Rel
.d
.a
);
305 report_fatal_error(errorToErrorCode(RelSecOrErr
.takeError()).message());
309 DataRefImpl
toDRI(const Elf_Shdr
*SymTable
, unsigned SymbolNum
) const {
316 assert(SymTable
->sh_type
== ELF::SHT_SYMTAB
||
317 SymTable
->sh_type
== ELF::SHT_DYNSYM
);
319 auto SectionsOrErr
= EF
.sections();
320 if (!SectionsOrErr
) {
325 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
326 unsigned SymTableIndex
=
327 (reinterpret_cast<uintptr_t>(SymTable
) - SHT
) / sizeof(Elf_Shdr
);
329 DRI
.d
.a
= SymTableIndex
;
334 const Elf_Shdr
*toELFShdrIter(DataRefImpl Sec
) const {
335 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
338 DataRefImpl
toDRI(const Elf_Shdr
*Sec
) const {
340 DRI
.p
= reinterpret_cast<uintptr_t>(Sec
);
344 DataRefImpl
toDRI(const Elf_Dyn
*Dyn
) const {
346 DRI
.p
= reinterpret_cast<uintptr_t>(Dyn
);
350 bool isExportedToOtherDSO(const Elf_Sym
*ESym
) const {
351 unsigned char Binding
= ESym
->getBinding();
352 unsigned char Visibility
= ESym
->getVisibility();
354 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
355 // visibility is either DEFAULT or PROTECTED. All other symbols are not
358 (Binding
== ELF::STB_GLOBAL
|| Binding
== ELF::STB_WEAK
||
359 Binding
== ELF::STB_GNU_UNIQUE
) &&
360 (Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_PROTECTED
));
363 Error
getBuildAttributes(ARMAttributeParser
&Attributes
) const override
{
364 auto SectionsOrErr
= EF
.sections();
366 return SectionsOrErr
.takeError();
368 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
369 if (Sec
.sh_type
== ELF::SHT_ARM_ATTRIBUTES
) {
370 auto ErrorOrContents
= EF
.getSectionContents(&Sec
);
371 if (!ErrorOrContents
)
372 return ErrorOrContents
.takeError();
374 auto Contents
= ErrorOrContents
.get();
375 if (Contents
[0] != ARMBuildAttrs::Format_Version
|| Contents
.size() == 1)
376 return Error::success();
378 Attributes
.Parse(Contents
, ELFT::TargetEndianness
== support::little
);
382 return Error::success();
385 // This flag is used for classof, to distinguish ELFObjectFile from
386 // its subclass. If more subclasses will be created, this flag will
387 // have to become an enum.
388 bool isDyldELFObject
;
391 ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
);
392 static Expected
<ELFObjectFile
<ELFT
>> create(MemoryBufferRef Object
);
394 const Elf_Rel
*getRel(DataRefImpl Rel
) const;
395 const Elf_Rela
*getRela(DataRefImpl Rela
) const;
397 const Elf_Sym
*getSymbol(DataRefImpl Sym
) const {
398 auto Ret
= EF
.template getEntry
<Elf_Sym
>(Sym
.d
.a
, Sym
.d
.b
);
400 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
404 const Elf_Shdr
*getSection(DataRefImpl Sec
) const {
405 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
408 basic_symbol_iterator
symbol_begin() const override
;
409 basic_symbol_iterator
symbol_end() const override
;
411 elf_symbol_iterator
dynamic_symbol_begin() const;
412 elf_symbol_iterator
dynamic_symbol_end() const;
414 section_iterator
section_begin() const override
;
415 section_iterator
section_end() const override
;
417 Expected
<int64_t> getRelocationAddend(DataRefImpl Rel
) const override
;
419 uint8_t getBytesInAddress() const override
;
420 StringRef
getFileFormatName() const override
;
421 Triple::ArchType
getArch() const override
;
422 Expected
<uint64_t> getStartAddress() const override
;
424 unsigned getPlatformFlags() const override
{ return EF
.getHeader()->e_flags
; }
426 const ELFFile
<ELFT
> *getELFFile() const { return &EF
; }
428 bool isDyldType() const { return isDyldELFObject
; }
429 static bool classof(const Binary
*v
) {
430 return v
->getType() == getELFType(ELFT::TargetEndianness
== support::little
,
434 elf_symbol_iterator_range
getDynamicSymbolIterators() const override
;
436 bool isRelocatableObject() const override
;
439 using ELF32LEObjectFile
= ELFObjectFile
<ELF32LE
>;
440 using ELF64LEObjectFile
= ELFObjectFile
<ELF64LE
>;
441 using ELF32BEObjectFile
= ELFObjectFile
<ELF32BE
>;
442 using ELF64BEObjectFile
= ELFObjectFile
<ELF64BE
>;
444 template <class ELFT
>
445 void ELFObjectFile
<ELFT
>::moveSymbolNext(DataRefImpl
&Sym
) const {
449 template <class ELFT
>
450 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSymbolName(DataRefImpl Sym
) const {
451 const Elf_Sym
*ESym
= getSymbol(Sym
);
452 auto SymTabOrErr
= EF
.getSection(Sym
.d
.a
);
454 return SymTabOrErr
.takeError();
455 const Elf_Shdr
*SymTableSec
= *SymTabOrErr
;
456 auto StrTabOrErr
= EF
.getSection(SymTableSec
->sh_link
);
458 return StrTabOrErr
.takeError();
459 const Elf_Shdr
*StringTableSec
= *StrTabOrErr
;
460 auto SymStrTabOrErr
= EF
.getStringTable(StringTableSec
);
462 return SymStrTabOrErr
.takeError();
463 Expected
<StringRef
> Name
= ESym
->getName(*SymStrTabOrErr
);
465 // If the symbol name is empty use the section name.
466 if ((!Name
|| Name
->empty()) && ESym
->getType() == ELF::STT_SECTION
) {
468 Expected
<section_iterator
> Sec
= getSymbolSection(Sym
);
469 if (Sec
&& !(*Sec
)->getName(SecName
))
475 template <class ELFT
>
476 uint64_t ELFObjectFile
<ELFT
>::getSectionFlags(DataRefImpl Sec
) const {
477 return getSection(Sec
)->sh_flags
;
480 template <class ELFT
>
481 uint32_t ELFObjectFile
<ELFT
>::getSectionType(DataRefImpl Sec
) const {
482 return getSection(Sec
)->sh_type
;
485 template <class ELFT
>
486 uint64_t ELFObjectFile
<ELFT
>::getSectionOffset(DataRefImpl Sec
) const {
487 return getSection(Sec
)->sh_offset
;
490 template <class ELFT
>
491 uint64_t ELFObjectFile
<ELFT
>::getSymbolValueImpl(DataRefImpl Symb
) const {
492 const Elf_Sym
*ESym
= getSymbol(Symb
);
493 uint64_t Ret
= ESym
->st_value
;
494 if (ESym
->st_shndx
== ELF::SHN_ABS
)
497 const Elf_Ehdr
*Header
= EF
.getHeader();
498 // Clear the ARM/Thumb or microMIPS indicator flag.
499 if ((Header
->e_machine
== ELF::EM_ARM
|| Header
->e_machine
== ELF::EM_MIPS
) &&
500 ESym
->getType() == ELF::STT_FUNC
)
506 template <class ELFT
>
508 ELFObjectFile
<ELFT
>::getSymbolAddress(DataRefImpl Symb
) const {
509 uint64_t Result
= getSymbolValue(Symb
);
510 const Elf_Sym
*ESym
= getSymbol(Symb
);
511 switch (ESym
->st_shndx
) {
512 case ELF::SHN_COMMON
:
518 const Elf_Ehdr
*Header
= EF
.getHeader();
519 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
521 return SymTabOrErr
.takeError();
522 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
524 if (Header
->e_type
== ELF::ET_REL
) {
525 auto SectionOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
527 return SectionOrErr
.takeError();
528 const Elf_Shdr
*Section
= *SectionOrErr
;
530 Result
+= Section
->sh_addr
;
536 template <class ELFT
>
537 uint32_t ELFObjectFile
<ELFT
>::getSymbolAlignment(DataRefImpl Symb
) const {
538 const Elf_Sym
*Sym
= getSymbol(Symb
);
539 if (Sym
->st_shndx
== ELF::SHN_COMMON
)
540 return Sym
->st_value
;
544 template <class ELFT
>
545 uint16_t ELFObjectFile
<ELFT
>::getEMachine() const {
546 return EF
.getHeader()->e_machine
;
549 template <class ELFT
> uint16_t ELFObjectFile
<ELFT
>::getEType() const {
550 return EF
.getHeader()->e_type
;
553 template <class ELFT
>
554 uint64_t ELFObjectFile
<ELFT
>::getSymbolSize(DataRefImpl Sym
) const {
555 return getSymbol(Sym
)->st_size
;
558 template <class ELFT
>
559 uint64_t ELFObjectFile
<ELFT
>::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
560 return getSymbol(Symb
)->st_size
;
563 template <class ELFT
>
564 uint8_t ELFObjectFile
<ELFT
>::getSymbolBinding(DataRefImpl Symb
) const {
565 return getSymbol(Symb
)->getBinding();
568 template <class ELFT
>
569 uint8_t ELFObjectFile
<ELFT
>::getSymbolOther(DataRefImpl Symb
) const {
570 return getSymbol(Symb
)->st_other
;
573 template <class ELFT
>
574 uint8_t ELFObjectFile
<ELFT
>::getSymbolELFType(DataRefImpl Symb
) const {
575 return getSymbol(Symb
)->getType();
578 template <class ELFT
>
579 Expected
<SymbolRef::Type
>
580 ELFObjectFile
<ELFT
>::getSymbolType(DataRefImpl Symb
) const {
581 const Elf_Sym
*ESym
= getSymbol(Symb
);
583 switch (ESym
->getType()) {
584 case ELF::STT_NOTYPE
:
585 return SymbolRef::ST_Unknown
;
586 case ELF::STT_SECTION
:
587 return SymbolRef::ST_Debug
;
589 return SymbolRef::ST_File
;
591 return SymbolRef::ST_Function
;
592 case ELF::STT_OBJECT
:
593 case ELF::STT_COMMON
:
595 return SymbolRef::ST_Data
;
597 return SymbolRef::ST_Other
;
601 template <class ELFT
>
602 uint32_t ELFObjectFile
<ELFT
>::getSymbolFlags(DataRefImpl Sym
) const {
603 const Elf_Sym
*ESym
= getSymbol(Sym
);
605 uint32_t Result
= SymbolRef::SF_None
;
607 if (ESym
->getBinding() != ELF::STB_LOCAL
)
608 Result
|= SymbolRef::SF_Global
;
610 if (ESym
->getBinding() == ELF::STB_WEAK
)
611 Result
|= SymbolRef::SF_Weak
;
613 if (ESym
->st_shndx
== ELF::SHN_ABS
)
614 Result
|= SymbolRef::SF_Absolute
;
616 if (ESym
->getType() == ELF::STT_FILE
|| ESym
->getType() == ELF::STT_SECTION
)
617 Result
|= SymbolRef::SF_FormatSpecific
;
619 auto DotSymtabSecSyms
= EF
.symbols(DotSymtabSec
);
620 if (DotSymtabSecSyms
&& ESym
== (*DotSymtabSecSyms
).begin())
621 Result
|= SymbolRef::SF_FormatSpecific
;
622 auto DotDynSymSecSyms
= EF
.symbols(DotDynSymSec
);
623 if (DotDynSymSecSyms
&& ESym
== (*DotDynSymSecSyms
).begin())
624 Result
|= SymbolRef::SF_FormatSpecific
;
626 if (EF
.getHeader()->e_machine
== ELF::EM_ARM
) {
627 if (Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
)) {
628 StringRef Name
= *NameOrErr
;
629 if (Name
.startswith("$d") || Name
.startswith("$t") ||
630 Name
.startswith("$a"))
631 Result
|= SymbolRef::SF_FormatSpecific
;
633 // TODO: Actually report errors helpfully.
634 consumeError(NameOrErr
.takeError());
636 if (ESym
->getType() == ELF::STT_FUNC
&& (ESym
->st_value
& 1) == 1)
637 Result
|= SymbolRef::SF_Thumb
;
640 if (ESym
->st_shndx
== ELF::SHN_UNDEF
)
641 Result
|= SymbolRef::SF_Undefined
;
643 if (ESym
->getType() == ELF::STT_COMMON
|| ESym
->st_shndx
== ELF::SHN_COMMON
)
644 Result
|= SymbolRef::SF_Common
;
646 if (isExportedToOtherDSO(ESym
))
647 Result
|= SymbolRef::SF_Exported
;
649 if (ESym
->getVisibility() == ELF::STV_HIDDEN
)
650 Result
|= SymbolRef::SF_Hidden
;
655 template <class ELFT
>
656 Expected
<section_iterator
>
657 ELFObjectFile
<ELFT
>::getSymbolSection(const Elf_Sym
*ESym
,
658 const Elf_Shdr
*SymTab
) const {
659 auto ESecOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
661 return ESecOrErr
.takeError();
663 const Elf_Shdr
*ESec
= *ESecOrErr
;
665 return section_end();
668 Sec
.p
= reinterpret_cast<intptr_t>(ESec
);
669 return section_iterator(SectionRef(Sec
, this));
672 template <class ELFT
>
673 Expected
<section_iterator
>
674 ELFObjectFile
<ELFT
>::getSymbolSection(DataRefImpl Symb
) const {
675 const Elf_Sym
*Sym
= getSymbol(Symb
);
676 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
678 return SymTabOrErr
.takeError();
679 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
680 return getSymbolSection(Sym
, SymTab
);
683 template <class ELFT
>
684 void ELFObjectFile
<ELFT
>::moveSectionNext(DataRefImpl
&Sec
) const {
685 const Elf_Shdr
*ESec
= getSection(Sec
);
689 template <class ELFT
>
690 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSectionName(DataRefImpl Sec
) const {
691 return EF
.getSectionName(&*getSection(Sec
));
694 template <class ELFT
>
695 uint64_t ELFObjectFile
<ELFT
>::getSectionAddress(DataRefImpl Sec
) const {
696 return getSection(Sec
)->sh_addr
;
699 template <class ELFT
>
700 uint64_t ELFObjectFile
<ELFT
>::getSectionIndex(DataRefImpl Sec
) const {
701 auto SectionsOrErr
= EF
.sections();
702 handleAllErrors(std::move(SectionsOrErr
.takeError()),
703 [](const ErrorInfoBase
&) {
704 llvm_unreachable("unable to get section index");
706 const Elf_Shdr
*First
= SectionsOrErr
->begin();
707 return getSection(Sec
) - First
;
710 template <class ELFT
>
711 uint64_t ELFObjectFile
<ELFT
>::getSectionSize(DataRefImpl Sec
) const {
712 return getSection(Sec
)->sh_size
;
715 template <class ELFT
>
716 Expected
<ArrayRef
<uint8_t>>
717 ELFObjectFile
<ELFT
>::getSectionContents(DataRefImpl Sec
) const {
718 const Elf_Shdr
*EShdr
= getSection(Sec
);
719 if (std::error_code EC
=
720 checkOffset(getMemoryBufferRef(),
721 (uintptr_t)base() + EShdr
->sh_offset
, EShdr
->sh_size
))
722 return errorCodeToError(EC
);
723 return makeArrayRef((const uint8_t *)base() + EShdr
->sh_offset
,
727 template <class ELFT
>
728 uint64_t ELFObjectFile
<ELFT
>::getSectionAlignment(DataRefImpl Sec
) const {
729 return getSection(Sec
)->sh_addralign
;
732 template <class ELFT
>
733 bool ELFObjectFile
<ELFT
>::isSectionCompressed(DataRefImpl Sec
) const {
734 return getSection(Sec
)->sh_flags
& ELF::SHF_COMPRESSED
;
737 template <class ELFT
>
738 bool ELFObjectFile
<ELFT
>::isSectionText(DataRefImpl Sec
) const {
739 return getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
;
742 template <class ELFT
>
743 bool ELFObjectFile
<ELFT
>::isSectionData(DataRefImpl Sec
) const {
744 const Elf_Shdr
*EShdr
= getSection(Sec
);
745 return EShdr
->sh_type
== ELF::SHT_PROGBITS
&&
746 EShdr
->sh_flags
& ELF::SHF_ALLOC
&&
747 !(EShdr
->sh_flags
& ELF::SHF_EXECINSTR
);
750 template <class ELFT
>
751 bool ELFObjectFile
<ELFT
>::isSectionBSS(DataRefImpl Sec
) const {
752 const Elf_Shdr
*EShdr
= getSection(Sec
);
753 return EShdr
->sh_flags
& (ELF::SHF_ALLOC
| ELF::SHF_WRITE
) &&
754 EShdr
->sh_type
== ELF::SHT_NOBITS
;
757 template <class ELFT
>
758 std::vector
<SectionRef
>
759 ELFObjectFile
<ELFT
>::dynamic_relocation_sections() const {
760 std::vector
<SectionRef
> Res
;
761 std::vector
<uintptr_t> Offsets
;
763 auto SectionsOrErr
= EF
.sections();
767 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
768 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
771 reinterpret_cast<Elf_Dyn
*>((uintptr_t)base() + Sec
.sh_offset
);
772 for (; Dynamic
->d_tag
!= ELF::DT_NULL
; Dynamic
++) {
773 if (Dynamic
->d_tag
== ELF::DT_REL
|| Dynamic
->d_tag
== ELF::DT_RELA
||
774 Dynamic
->d_tag
== ELF::DT_JMPREL
) {
775 Offsets
.push_back(Dynamic
->d_un
.d_val
);
779 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
780 if (is_contained(Offsets
, Sec
.sh_addr
))
781 Res
.emplace_back(toDRI(&Sec
), this);
786 template <class ELFT
>
787 bool ELFObjectFile
<ELFT
>::isSectionVirtual(DataRefImpl Sec
) const {
788 return getSection(Sec
)->sh_type
== ELF::SHT_NOBITS
;
791 template <class ELFT
>
792 bool ELFObjectFile
<ELFT
>::isBerkeleyText(DataRefImpl Sec
) const {
793 return getSection(Sec
)->sh_flags
& ELF::SHF_ALLOC
&&
794 (getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
||
795 !(getSection(Sec
)->sh_flags
& ELF::SHF_WRITE
));
798 template <class ELFT
>
799 bool ELFObjectFile
<ELFT
>::isBerkeleyData(DataRefImpl Sec
) const {
800 const Elf_Shdr
*EShdr
= getSection(Sec
);
801 return !isBerkeleyText(Sec
) && EShdr
->sh_type
!= ELF::SHT_NOBITS
&&
802 EShdr
->sh_flags
& ELF::SHF_ALLOC
;
805 template <class ELFT
>
807 ELFObjectFile
<ELFT
>::section_rel_begin(DataRefImpl Sec
) const {
809 auto SectionsOrErr
= EF
.sections();
811 return relocation_iterator(RelocationRef());
812 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
813 RelData
.d
.a
= (Sec
.p
- SHT
) / EF
.getHeader()->e_shentsize
;
815 return relocation_iterator(RelocationRef(RelData
, this));
818 template <class ELFT
>
820 ELFObjectFile
<ELFT
>::section_rel_end(DataRefImpl Sec
) const {
821 const Elf_Shdr
*S
= reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
822 relocation_iterator Begin
= section_rel_begin(Sec
);
823 if (S
->sh_type
!= ELF::SHT_RELA
&& S
->sh_type
!= ELF::SHT_REL
)
825 DataRefImpl RelData
= Begin
->getRawDataRefImpl();
826 const Elf_Shdr
*RelSec
= getRelSection(RelData
);
828 // Error check sh_link here so that getRelocationSymbol can just use it.
829 auto SymSecOrErr
= EF
.getSection(RelSec
->sh_link
);
831 report_fatal_error(errorToErrorCode(SymSecOrErr
.takeError()).message());
833 RelData
.d
.b
+= S
->sh_size
/ S
->sh_entsize
;
834 return relocation_iterator(RelocationRef(RelData
, this));
837 template <class ELFT
>
839 ELFObjectFile
<ELFT
>::getRelocatedSection(DataRefImpl Sec
) const {
840 if (EF
.getHeader()->e_type
!= ELF::ET_REL
)
841 return section_end();
843 const Elf_Shdr
*EShdr
= getSection(Sec
);
844 uintX_t Type
= EShdr
->sh_type
;
845 if (Type
!= ELF::SHT_REL
&& Type
!= ELF::SHT_RELA
)
846 return section_end();
848 auto R
= EF
.getSection(EShdr
->sh_info
);
850 report_fatal_error(errorToErrorCode(R
.takeError()).message());
851 return section_iterator(SectionRef(toDRI(*R
), this));
855 template <class ELFT
>
856 void ELFObjectFile
<ELFT
>::moveRelocationNext(DataRefImpl
&Rel
) const {
860 template <class ELFT
>
862 ELFObjectFile
<ELFT
>::getRelocationSymbol(DataRefImpl Rel
) const {
864 const Elf_Shdr
*sec
= getRelSection(Rel
);
865 if (sec
->sh_type
== ELF::SHT_REL
)
866 symbolIdx
= getRel(Rel
)->getSymbol(EF
.isMips64EL());
868 symbolIdx
= getRela(Rel
)->getSymbol(EF
.isMips64EL());
872 // FIXME: error check symbolIdx
873 DataRefImpl SymbolData
;
874 SymbolData
.d
.a
= sec
->sh_link
;
875 SymbolData
.d
.b
= symbolIdx
;
876 return symbol_iterator(SymbolRef(SymbolData
, this));
879 template <class ELFT
>
880 uint64_t ELFObjectFile
<ELFT
>::getRelocationOffset(DataRefImpl Rel
) const {
881 const Elf_Shdr
*sec
= getRelSection(Rel
);
882 if (sec
->sh_type
== ELF::SHT_REL
)
883 return getRel(Rel
)->r_offset
;
885 return getRela(Rel
)->r_offset
;
888 template <class ELFT
>
889 uint64_t ELFObjectFile
<ELFT
>::getRelocationType(DataRefImpl Rel
) const {
890 const Elf_Shdr
*sec
= getRelSection(Rel
);
891 if (sec
->sh_type
== ELF::SHT_REL
)
892 return getRel(Rel
)->getType(EF
.isMips64EL());
894 return getRela(Rel
)->getType(EF
.isMips64EL());
897 template <class ELFT
>
898 StringRef ELFObjectFile
<ELFT
>::getRelocationTypeName(uint32_t Type
) const {
899 return getELFRelocationTypeName(EF
.getHeader()->e_machine
, Type
);
902 template <class ELFT
>
903 void ELFObjectFile
<ELFT
>::getRelocationTypeName(
904 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
905 uint32_t type
= getRelocationType(Rel
);
906 EF
.getRelocationTypeName(type
, Result
);
909 template <class ELFT
>
911 ELFObjectFile
<ELFT
>::getRelocationAddend(DataRefImpl Rel
) const {
912 if (getRelSection(Rel
)->sh_type
!= ELF::SHT_RELA
)
913 return createError("Section is not SHT_RELA");
914 return (int64_t)getRela(Rel
)->r_addend
;
917 template <class ELFT
>
918 const typename ELFObjectFile
<ELFT
>::Elf_Rel
*
919 ELFObjectFile
<ELFT
>::getRel(DataRefImpl Rel
) const {
920 assert(getRelSection(Rel
)->sh_type
== ELF::SHT_REL
);
921 auto Ret
= EF
.template getEntry
<Elf_Rel
>(Rel
.d
.a
, Rel
.d
.b
);
923 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
927 template <class ELFT
>
928 const typename ELFObjectFile
<ELFT
>::Elf_Rela
*
929 ELFObjectFile
<ELFT
>::getRela(DataRefImpl Rela
) const {
930 assert(getRelSection(Rela
)->sh_type
== ELF::SHT_RELA
);
931 auto Ret
= EF
.template getEntry
<Elf_Rela
>(Rela
.d
.a
, Rela
.d
.b
);
933 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
937 template <class ELFT
>
938 Expected
<ELFObjectFile
<ELFT
>>
939 ELFObjectFile
<ELFT
>::create(MemoryBufferRef Object
) {
940 auto EFOrErr
= ELFFile
<ELFT
>::create(Object
.getBuffer());
941 if (Error E
= EFOrErr
.takeError())
943 auto EF
= std::move(*EFOrErr
);
945 auto SectionsOrErr
= EF
.sections();
947 return SectionsOrErr
.takeError();
949 const Elf_Shdr
*DotDynSymSec
= nullptr;
950 const Elf_Shdr
*DotSymtabSec
= nullptr;
951 ArrayRef
<Elf_Word
> ShndxTable
;
952 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
953 switch (Sec
.sh_type
) {
954 case ELF::SHT_DYNSYM
: {
959 case ELF::SHT_SYMTAB
: {
964 case ELF::SHT_SYMTAB_SHNDX
: {
965 auto TableOrErr
= EF
.getSHNDXTable(Sec
);
967 return TableOrErr
.takeError();
968 ShndxTable
= *TableOrErr
;
973 return ELFObjectFile
<ELFT
>(Object
, EF
, DotDynSymSec
, DotSymtabSec
,
977 template <class ELFT
>
978 ELFObjectFile
<ELFT
>::ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
979 const Elf_Shdr
*DotDynSymSec
,
980 const Elf_Shdr
*DotSymtabSec
,
981 ArrayRef
<Elf_Word
> ShndxTable
)
983 getELFType(ELFT::TargetEndianness
== support::little
, ELFT::Is64Bits
),
985 EF(EF
), DotDynSymSec(DotDynSymSec
), DotSymtabSec(DotSymtabSec
),
986 ShndxTable(ShndxTable
) {}
988 template <class ELFT
>
989 ELFObjectFile
<ELFT
>::ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
)
990 : ELFObjectFile(Other
.Data
, Other
.EF
, Other
.DotDynSymSec
,
991 Other
.DotSymtabSec
, Other
.ShndxTable
) {}
993 template <class ELFT
>
994 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_begin() const {
997 DotSymtabSec
&& DotSymtabSec
->sh_size
>= sizeof(Elf_Sym
) ? 1 : 0);
998 return basic_symbol_iterator(SymbolRef(Sym
, this));
1001 template <class ELFT
>
1002 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_end() const {
1003 const Elf_Shdr
*SymTab
= DotSymtabSec
;
1005 return symbol_begin();
1006 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1007 return basic_symbol_iterator(SymbolRef(Sym
, this));
1010 template <class ELFT
>
1011 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_begin() const {
1012 DataRefImpl Sym
= toDRI(DotDynSymSec
, 0);
1013 return symbol_iterator(SymbolRef(Sym
, this));
1016 template <class ELFT
>
1017 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_end() const {
1018 const Elf_Shdr
*SymTab
= DotDynSymSec
;
1020 return dynamic_symbol_begin();
1021 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1022 return basic_symbol_iterator(SymbolRef(Sym
, this));
1025 template <class ELFT
>
1026 section_iterator ELFObjectFile
<ELFT
>::section_begin() const {
1027 auto SectionsOrErr
= EF
.sections();
1029 return section_iterator(SectionRef());
1030 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).begin()), this));
1033 template <class ELFT
>
1034 section_iterator ELFObjectFile
<ELFT
>::section_end() const {
1035 auto SectionsOrErr
= EF
.sections();
1037 return section_iterator(SectionRef());
1038 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).end()), this));
1041 template <class ELFT
>
1042 uint8_t ELFObjectFile
<ELFT
>::getBytesInAddress() const {
1043 return ELFT::Is64Bits
? 8 : 4;
1046 template <class ELFT
>
1047 StringRef ELFObjectFile
<ELFT
>::getFileFormatName() const {
1048 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1049 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1050 case ELF::ELFCLASS32
:
1051 switch (EF
.getHeader()->e_machine
) {
1053 return "ELF32-i386";
1055 return "ELF32-iamcu";
1056 case ELF::EM_X86_64
:
1057 return "ELF32-x86-64";
1059 return (IsLittleEndian
? "ELF32-arm-little" : "ELF32-arm-big");
1062 case ELF::EM_HEXAGON
:
1063 return "ELF32-hexagon";
1065 return "ELF32-lanai";
1067 return "ELF32-mips";
1068 case ELF::EM_MSP430
:
1069 return "ELF32-msp430";
1073 return "ELF32-riscv";
1075 case ELF::EM_SPARC32PLUS
:
1076 return "ELF32-sparc";
1077 case ELF::EM_AMDGPU
:
1078 return "ELF32-amdgpu";
1080 return "ELF32-unknown";
1082 case ELF::ELFCLASS64
:
1083 switch (EF
.getHeader()->e_machine
) {
1085 return "ELF64-i386";
1086 case ELF::EM_X86_64
:
1087 return "ELF64-x86-64";
1088 case ELF::EM_AARCH64
:
1089 return (IsLittleEndian
? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1091 return "ELF64-ppc64";
1093 return "ELF64-riscv";
1095 return "ELF64-s390";
1096 case ELF::EM_SPARCV9
:
1097 return "ELF64-sparc";
1099 return "ELF64-mips";
1100 case ELF::EM_AMDGPU
:
1101 return "ELF64-amdgpu";
1105 return "ELF64-unknown";
1108 // FIXME: Proper error handling.
1109 report_fatal_error("Invalid ELFCLASS!");
1113 template <class ELFT
> Triple::ArchType ELFObjectFile
<ELFT
>::getArch() const {
1114 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1115 switch (EF
.getHeader()->e_machine
) {
1119 case ELF::EM_X86_64
:
1120 return Triple::x86_64
;
1121 case ELF::EM_AARCH64
:
1122 return IsLittleEndian
? Triple::aarch64
: Triple::aarch64_be
;
1127 case ELF::EM_HEXAGON
:
1128 return Triple::hexagon
;
1130 return Triple::lanai
;
1132 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1133 case ELF::ELFCLASS32
:
1134 return IsLittleEndian
? Triple::mipsel
: Triple::mips
;
1135 case ELF::ELFCLASS64
:
1136 return IsLittleEndian
? Triple::mips64el
: Triple::mips64
;
1138 report_fatal_error("Invalid ELFCLASS!");
1140 case ELF::EM_MSP430
:
1141 return Triple::msp430
;
1145 return IsLittleEndian
? Triple::ppc64le
: Triple::ppc64
;
1147 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1148 case ELF::ELFCLASS32
:
1149 return Triple::riscv32
;
1150 case ELF::ELFCLASS64
:
1151 return Triple::riscv64
;
1153 report_fatal_error("Invalid ELFCLASS!");
1156 return Triple::systemz
;
1159 case ELF::EM_SPARC32PLUS
:
1160 return IsLittleEndian
? Triple::sparcel
: Triple::sparc
;
1161 case ELF::EM_SPARCV9
:
1162 return Triple::sparcv9
;
1164 case ELF::EM_AMDGPU
: {
1165 if (!IsLittleEndian
)
1166 return Triple::UnknownArch
;
1168 unsigned MACH
= EF
.getHeader()->e_flags
& ELF::EF_AMDGPU_MACH
;
1169 if (MACH
>= ELF::EF_AMDGPU_MACH_R600_FIRST
&&
1170 MACH
<= ELF::EF_AMDGPU_MACH_R600_LAST
)
1171 return Triple::r600
;
1172 if (MACH
>= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST
&&
1173 MACH
<= ELF::EF_AMDGPU_MACH_AMDGCN_LAST
)
1174 return Triple::amdgcn
;
1176 return Triple::UnknownArch
;
1180 return IsLittleEndian
? Triple::bpfel
: Triple::bpfeb
;
1183 return Triple::UnknownArch
;
1187 template <class ELFT
>
1188 Expected
<uint64_t> ELFObjectFile
<ELFT
>::getStartAddress() const {
1189 return EF
.getHeader()->e_entry
;
1192 template <class ELFT
>
1193 ELFObjectFileBase::elf_symbol_iterator_range
1194 ELFObjectFile
<ELFT
>::getDynamicSymbolIterators() const {
1195 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1198 template <class ELFT
> bool ELFObjectFile
<ELFT
>::isRelocatableObject() const {
1199 return EF
.getHeader()->e_type
== ELF::ET_REL
;
1202 } // end namespace object
1203 } // end namespace llvm
1205 #endif // LLVM_OBJECT_ELFOBJECTFILE_H