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
;
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 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 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
289 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
290 std::vector
<SectionRef
> dynamic_relocation_sections() const override
;
291 section_iterator
getRelocatedSection(DataRefImpl Sec
) const override
;
293 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
294 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
295 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
296 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
297 void getRelocationTypeName(DataRefImpl Rel
,
298 SmallVectorImpl
<char> &Result
) const override
;
300 uint32_t getSectionType(DataRefImpl Sec
) const override
;
301 uint64_t getSectionFlags(DataRefImpl Sec
) const override
;
302 uint64_t getSectionOffset(DataRefImpl Sec
) const override
;
303 StringRef
getRelocationTypeName(uint32_t Type
) const;
305 /// Get the relocation section that contains \a Rel.
306 const Elf_Shdr
*getRelSection(DataRefImpl Rel
) const {
307 auto RelSecOrErr
= EF
.getSection(Rel
.d
.a
);
309 report_fatal_error(errorToErrorCode(RelSecOrErr
.takeError()).message());
313 DataRefImpl
toDRI(const Elf_Shdr
*SymTable
, unsigned SymbolNum
) const {
320 assert(SymTable
->sh_type
== ELF::SHT_SYMTAB
||
321 SymTable
->sh_type
== ELF::SHT_DYNSYM
);
323 auto SectionsOrErr
= EF
.sections();
324 if (!SectionsOrErr
) {
329 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
330 unsigned SymTableIndex
=
331 (reinterpret_cast<uintptr_t>(SymTable
) - SHT
) / sizeof(Elf_Shdr
);
333 DRI
.d
.a
= SymTableIndex
;
338 const Elf_Shdr
*toELFShdrIter(DataRefImpl Sec
) const {
339 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
342 DataRefImpl
toDRI(const Elf_Shdr
*Sec
) const {
344 DRI
.p
= reinterpret_cast<uintptr_t>(Sec
);
348 DataRefImpl
toDRI(const Elf_Dyn
*Dyn
) const {
350 DRI
.p
= reinterpret_cast<uintptr_t>(Dyn
);
354 bool isExportedToOtherDSO(const Elf_Sym
*ESym
) const {
355 unsigned char Binding
= ESym
->getBinding();
356 unsigned char Visibility
= ESym
->getVisibility();
358 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
359 // visibility is either DEFAULT or PROTECTED. All other symbols are not
362 (Binding
== ELF::STB_GLOBAL
|| Binding
== ELF::STB_WEAK
||
363 Binding
== ELF::STB_GNU_UNIQUE
) &&
364 (Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_PROTECTED
));
367 Error
getBuildAttributes(ARMAttributeParser
&Attributes
) const override
{
368 auto SectionsOrErr
= EF
.sections();
370 return SectionsOrErr
.takeError();
372 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
373 if (Sec
.sh_type
== ELF::SHT_ARM_ATTRIBUTES
) {
374 auto ErrorOrContents
= EF
.getSectionContents(&Sec
);
375 if (!ErrorOrContents
)
376 return ErrorOrContents
.takeError();
378 auto Contents
= ErrorOrContents
.get();
379 if (Contents
[0] != ARMBuildAttrs::Format_Version
|| Contents
.size() == 1)
380 return Error::success();
382 Attributes
.Parse(Contents
, ELFT::TargetEndianness
== support::little
);
386 return Error::success();
389 // This flag is used for classof, to distinguish ELFObjectFile from
390 // its subclass. If more subclasses will be created, this flag will
391 // have to become an enum.
392 bool isDyldELFObject
;
395 ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
);
396 static Expected
<ELFObjectFile
<ELFT
>> create(MemoryBufferRef Object
);
398 const Elf_Rel
*getRel(DataRefImpl Rel
) const;
399 const Elf_Rela
*getRela(DataRefImpl Rela
) const;
401 const Elf_Sym
*getSymbol(DataRefImpl Sym
) const {
402 auto Ret
= EF
.template getEntry
<Elf_Sym
>(Sym
.d
.a
, Sym
.d
.b
);
404 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
408 const Elf_Shdr
*getSection(DataRefImpl Sec
) const {
409 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
412 basic_symbol_iterator
symbol_begin() const override
;
413 basic_symbol_iterator
symbol_end() const override
;
415 elf_symbol_iterator
dynamic_symbol_begin() const;
416 elf_symbol_iterator
dynamic_symbol_end() const;
418 section_iterator
section_begin() const override
;
419 section_iterator
section_end() const override
;
421 Expected
<int64_t> getRelocationAddend(DataRefImpl Rel
) const override
;
423 uint8_t getBytesInAddress() const override
;
424 StringRef
getFileFormatName() const override
;
425 Triple::ArchType
getArch() const override
;
426 Expected
<uint64_t> getStartAddress() const override
;
428 unsigned getPlatformFlags() const override
{ return EF
.getHeader()->e_flags
; }
430 const ELFFile
<ELFT
> *getELFFile() const { return &EF
; }
432 bool isDyldType() const { return isDyldELFObject
; }
433 static bool classof(const Binary
*v
) {
434 return v
->getType() == getELFType(ELFT::TargetEndianness
== support::little
,
438 elf_symbol_iterator_range
getDynamicSymbolIterators() const override
;
440 bool isRelocatableObject() const override
;
443 using ELF32LEObjectFile
= ELFObjectFile
<ELF32LE
>;
444 using ELF64LEObjectFile
= ELFObjectFile
<ELF64LE
>;
445 using ELF32BEObjectFile
= ELFObjectFile
<ELF32BE
>;
446 using ELF64BEObjectFile
= ELFObjectFile
<ELF64BE
>;
448 template <class ELFT
>
449 void ELFObjectFile
<ELFT
>::moveSymbolNext(DataRefImpl
&Sym
) const {
453 template <class ELFT
>
454 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSymbolName(DataRefImpl Sym
) const {
455 const Elf_Sym
*ESym
= getSymbol(Sym
);
456 auto SymTabOrErr
= EF
.getSection(Sym
.d
.a
);
458 return SymTabOrErr
.takeError();
459 const Elf_Shdr
*SymTableSec
= *SymTabOrErr
;
460 auto StrTabOrErr
= EF
.getSection(SymTableSec
->sh_link
);
462 return StrTabOrErr
.takeError();
463 const Elf_Shdr
*StringTableSec
= *StrTabOrErr
;
464 auto SymStrTabOrErr
= EF
.getStringTable(StringTableSec
);
466 return SymStrTabOrErr
.takeError();
467 Expected
<StringRef
> Name
= ESym
->getName(*SymStrTabOrErr
);
468 if (Name
&& !Name
->empty())
471 // If the symbol name is empty use the section name.
472 if (ESym
->getType() == ELF::STT_SECTION
) {
473 if (Expected
<section_iterator
> SecOrErr
= getSymbolSection(Sym
)) {
474 consumeError(Name
.takeError());
475 return (*SecOrErr
)->getName();
481 template <class ELFT
>
482 uint64_t ELFObjectFile
<ELFT
>::getSectionFlags(DataRefImpl Sec
) const {
483 return getSection(Sec
)->sh_flags
;
486 template <class ELFT
>
487 uint32_t ELFObjectFile
<ELFT
>::getSectionType(DataRefImpl Sec
) const {
488 return getSection(Sec
)->sh_type
;
491 template <class ELFT
>
492 uint64_t ELFObjectFile
<ELFT
>::getSectionOffset(DataRefImpl Sec
) const {
493 return getSection(Sec
)->sh_offset
;
496 template <class ELFT
>
497 uint64_t ELFObjectFile
<ELFT
>::getSymbolValueImpl(DataRefImpl Symb
) const {
498 const Elf_Sym
*ESym
= getSymbol(Symb
);
499 uint64_t Ret
= ESym
->st_value
;
500 if (ESym
->st_shndx
== ELF::SHN_ABS
)
503 const Elf_Ehdr
*Header
= EF
.getHeader();
504 // Clear the ARM/Thumb or microMIPS indicator flag.
505 if ((Header
->e_machine
== ELF::EM_ARM
|| Header
->e_machine
== ELF::EM_MIPS
) &&
506 ESym
->getType() == ELF::STT_FUNC
)
512 template <class ELFT
>
514 ELFObjectFile
<ELFT
>::getSymbolAddress(DataRefImpl Symb
) const {
515 uint64_t Result
= getSymbolValue(Symb
);
516 const Elf_Sym
*ESym
= getSymbol(Symb
);
517 switch (ESym
->st_shndx
) {
518 case ELF::SHN_COMMON
:
524 const Elf_Ehdr
*Header
= EF
.getHeader();
525 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
527 return SymTabOrErr
.takeError();
528 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
530 if (Header
->e_type
== ELF::ET_REL
) {
531 auto SectionOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
533 return SectionOrErr
.takeError();
534 const Elf_Shdr
*Section
= *SectionOrErr
;
536 Result
+= Section
->sh_addr
;
542 template <class ELFT
>
543 uint32_t ELFObjectFile
<ELFT
>::getSymbolAlignment(DataRefImpl Symb
) const {
544 const Elf_Sym
*Sym
= getSymbol(Symb
);
545 if (Sym
->st_shndx
== ELF::SHN_COMMON
)
546 return Sym
->st_value
;
550 template <class ELFT
>
551 uint16_t ELFObjectFile
<ELFT
>::getEMachine() const {
552 return EF
.getHeader()->e_machine
;
555 template <class ELFT
> uint16_t ELFObjectFile
<ELFT
>::getEType() const {
556 return EF
.getHeader()->e_type
;
559 template <class ELFT
>
560 uint64_t ELFObjectFile
<ELFT
>::getSymbolSize(DataRefImpl Sym
) const {
561 return getSymbol(Sym
)->st_size
;
564 template <class ELFT
>
565 uint64_t ELFObjectFile
<ELFT
>::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
566 return getSymbol(Symb
)->st_size
;
569 template <class ELFT
>
570 uint8_t ELFObjectFile
<ELFT
>::getSymbolBinding(DataRefImpl Symb
) const {
571 return getSymbol(Symb
)->getBinding();
574 template <class ELFT
>
575 uint8_t ELFObjectFile
<ELFT
>::getSymbolOther(DataRefImpl Symb
) const {
576 return getSymbol(Symb
)->st_other
;
579 template <class ELFT
>
580 uint8_t ELFObjectFile
<ELFT
>::getSymbolELFType(DataRefImpl Symb
) const {
581 return getSymbol(Symb
)->getType();
584 template <class ELFT
>
585 Expected
<SymbolRef::Type
>
586 ELFObjectFile
<ELFT
>::getSymbolType(DataRefImpl Symb
) const {
587 const Elf_Sym
*ESym
= getSymbol(Symb
);
589 switch (ESym
->getType()) {
590 case ELF::STT_NOTYPE
:
591 return SymbolRef::ST_Unknown
;
592 case ELF::STT_SECTION
:
593 return SymbolRef::ST_Debug
;
595 return SymbolRef::ST_File
;
597 return SymbolRef::ST_Function
;
598 case ELF::STT_OBJECT
:
599 case ELF::STT_COMMON
:
601 return SymbolRef::ST_Data
;
603 return SymbolRef::ST_Other
;
607 template <class ELFT
>
608 uint32_t ELFObjectFile
<ELFT
>::getSymbolFlags(DataRefImpl Sym
) const {
609 const Elf_Sym
*ESym
= getSymbol(Sym
);
611 uint32_t Result
= SymbolRef::SF_None
;
613 if (ESym
->getBinding() != ELF::STB_LOCAL
)
614 Result
|= SymbolRef::SF_Global
;
616 if (ESym
->getBinding() == ELF::STB_WEAK
)
617 Result
|= SymbolRef::SF_Weak
;
619 if (ESym
->st_shndx
== ELF::SHN_ABS
)
620 Result
|= SymbolRef::SF_Absolute
;
622 if (ESym
->getType() == ELF::STT_FILE
|| ESym
->getType() == ELF::STT_SECTION
)
623 Result
|= SymbolRef::SF_FormatSpecific
;
625 auto DotSymtabSecSyms
= EF
.symbols(DotSymtabSec
);
626 if (DotSymtabSecSyms
&& ESym
== (*DotSymtabSecSyms
).begin())
627 Result
|= SymbolRef::SF_FormatSpecific
;
628 auto DotDynSymSecSyms
= EF
.symbols(DotDynSymSec
);
629 if (DotDynSymSecSyms
&& ESym
== (*DotDynSymSecSyms
).begin())
630 Result
|= SymbolRef::SF_FormatSpecific
;
632 if (EF
.getHeader()->e_machine
== ELF::EM_ARM
) {
633 if (Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
)) {
634 StringRef Name
= *NameOrErr
;
635 if (Name
.startswith("$d") || Name
.startswith("$t") ||
636 Name
.startswith("$a"))
637 Result
|= SymbolRef::SF_FormatSpecific
;
639 // TODO: Actually report errors helpfully.
640 consumeError(NameOrErr
.takeError());
642 if (ESym
->getType() == ELF::STT_FUNC
&& (ESym
->st_value
& 1) == 1)
643 Result
|= SymbolRef::SF_Thumb
;
646 if (ESym
->st_shndx
== ELF::SHN_UNDEF
)
647 Result
|= SymbolRef::SF_Undefined
;
649 if (ESym
->getType() == ELF::STT_COMMON
|| ESym
->st_shndx
== ELF::SHN_COMMON
)
650 Result
|= SymbolRef::SF_Common
;
652 if (isExportedToOtherDSO(ESym
))
653 Result
|= SymbolRef::SF_Exported
;
655 if (ESym
->getVisibility() == ELF::STV_HIDDEN
)
656 Result
|= SymbolRef::SF_Hidden
;
661 template <class ELFT
>
662 Expected
<section_iterator
>
663 ELFObjectFile
<ELFT
>::getSymbolSection(const Elf_Sym
*ESym
,
664 const Elf_Shdr
*SymTab
) const {
665 auto ESecOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
667 return ESecOrErr
.takeError();
669 const Elf_Shdr
*ESec
= *ESecOrErr
;
671 return section_end();
674 Sec
.p
= reinterpret_cast<intptr_t>(ESec
);
675 return section_iterator(SectionRef(Sec
, this));
678 template <class ELFT
>
679 Expected
<section_iterator
>
680 ELFObjectFile
<ELFT
>::getSymbolSection(DataRefImpl Symb
) const {
681 const Elf_Sym
*Sym
= getSymbol(Symb
);
682 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
684 return SymTabOrErr
.takeError();
685 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
686 return getSymbolSection(Sym
, SymTab
);
689 template <class ELFT
>
690 void ELFObjectFile
<ELFT
>::moveSectionNext(DataRefImpl
&Sec
) const {
691 const Elf_Shdr
*ESec
= getSection(Sec
);
695 template <class ELFT
>
696 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSectionName(DataRefImpl Sec
) const {
697 return EF
.getSectionName(&*getSection(Sec
));
700 template <class ELFT
>
701 uint64_t ELFObjectFile
<ELFT
>::getSectionAddress(DataRefImpl Sec
) const {
702 return getSection(Sec
)->sh_addr
;
705 template <class ELFT
>
706 uint64_t ELFObjectFile
<ELFT
>::getSectionIndex(DataRefImpl Sec
) const {
707 auto SectionsOrErr
= EF
.sections();
708 handleAllErrors(std::move(SectionsOrErr
.takeError()),
709 [](const ErrorInfoBase
&) {
710 llvm_unreachable("unable to get section index");
712 const Elf_Shdr
*First
= SectionsOrErr
->begin();
713 return getSection(Sec
) - First
;
716 template <class ELFT
>
717 uint64_t ELFObjectFile
<ELFT
>::getSectionSize(DataRefImpl Sec
) const {
718 return getSection(Sec
)->sh_size
;
721 template <class ELFT
>
722 Expected
<ArrayRef
<uint8_t>>
723 ELFObjectFile
<ELFT
>::getSectionContents(DataRefImpl Sec
) const {
724 const Elf_Shdr
*EShdr
= getSection(Sec
);
725 if (std::error_code EC
=
726 checkOffset(getMemoryBufferRef(),
727 (uintptr_t)base() + EShdr
->sh_offset
, EShdr
->sh_size
))
728 return errorCodeToError(EC
);
729 return makeArrayRef((const uint8_t *)base() + EShdr
->sh_offset
,
733 template <class ELFT
>
734 uint64_t ELFObjectFile
<ELFT
>::getSectionAlignment(DataRefImpl Sec
) const {
735 return getSection(Sec
)->sh_addralign
;
738 template <class ELFT
>
739 bool ELFObjectFile
<ELFT
>::isSectionCompressed(DataRefImpl Sec
) const {
740 return getSection(Sec
)->sh_flags
& ELF::SHF_COMPRESSED
;
743 template <class ELFT
>
744 bool ELFObjectFile
<ELFT
>::isSectionText(DataRefImpl Sec
) const {
745 return getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
;
748 template <class ELFT
>
749 bool ELFObjectFile
<ELFT
>::isSectionData(DataRefImpl Sec
) const {
750 const Elf_Shdr
*EShdr
= getSection(Sec
);
751 return EShdr
->sh_type
== ELF::SHT_PROGBITS
&&
752 EShdr
->sh_flags
& ELF::SHF_ALLOC
&&
753 !(EShdr
->sh_flags
& ELF::SHF_EXECINSTR
);
756 template <class ELFT
>
757 bool ELFObjectFile
<ELFT
>::isSectionBSS(DataRefImpl Sec
) const {
758 const Elf_Shdr
*EShdr
= getSection(Sec
);
759 return EShdr
->sh_flags
& (ELF::SHF_ALLOC
| ELF::SHF_WRITE
) &&
760 EShdr
->sh_type
== ELF::SHT_NOBITS
;
763 template <class ELFT
>
764 std::vector
<SectionRef
>
765 ELFObjectFile
<ELFT
>::dynamic_relocation_sections() const {
766 std::vector
<SectionRef
> Res
;
767 std::vector
<uintptr_t> Offsets
;
769 auto SectionsOrErr
= EF
.sections();
773 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
774 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
777 reinterpret_cast<Elf_Dyn
*>((uintptr_t)base() + Sec
.sh_offset
);
778 for (; Dynamic
->d_tag
!= ELF::DT_NULL
; Dynamic
++) {
779 if (Dynamic
->d_tag
== ELF::DT_REL
|| Dynamic
->d_tag
== ELF::DT_RELA
||
780 Dynamic
->d_tag
== ELF::DT_JMPREL
) {
781 Offsets
.push_back(Dynamic
->d_un
.d_val
);
785 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
786 if (is_contained(Offsets
, Sec
.sh_addr
))
787 Res
.emplace_back(toDRI(&Sec
), this);
792 template <class ELFT
>
793 bool ELFObjectFile
<ELFT
>::isSectionVirtual(DataRefImpl Sec
) const {
794 return getSection(Sec
)->sh_type
== ELF::SHT_NOBITS
;
797 template <class ELFT
>
798 bool ELFObjectFile
<ELFT
>::isBerkeleyText(DataRefImpl Sec
) const {
799 return getSection(Sec
)->sh_flags
& ELF::SHF_ALLOC
&&
800 (getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
||
801 !(getSection(Sec
)->sh_flags
& ELF::SHF_WRITE
));
804 template <class ELFT
>
805 bool ELFObjectFile
<ELFT
>::isBerkeleyData(DataRefImpl Sec
) const {
806 const Elf_Shdr
*EShdr
= getSection(Sec
);
807 return !isBerkeleyText(Sec
) && EShdr
->sh_type
!= ELF::SHT_NOBITS
&&
808 EShdr
->sh_flags
& ELF::SHF_ALLOC
;
811 template <class ELFT
>
813 ELFObjectFile
<ELFT
>::section_rel_begin(DataRefImpl Sec
) const {
815 auto SectionsOrErr
= EF
.sections();
817 return relocation_iterator(RelocationRef());
818 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
819 RelData
.d
.a
= (Sec
.p
- SHT
) / EF
.getHeader()->e_shentsize
;
821 return relocation_iterator(RelocationRef(RelData
, this));
824 template <class ELFT
>
826 ELFObjectFile
<ELFT
>::section_rel_end(DataRefImpl Sec
) const {
827 const Elf_Shdr
*S
= reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
828 relocation_iterator Begin
= section_rel_begin(Sec
);
829 if (S
->sh_type
!= ELF::SHT_RELA
&& S
->sh_type
!= ELF::SHT_REL
)
831 DataRefImpl RelData
= Begin
->getRawDataRefImpl();
832 const Elf_Shdr
*RelSec
= getRelSection(RelData
);
834 // Error check sh_link here so that getRelocationSymbol can just use it.
835 auto SymSecOrErr
= EF
.getSection(RelSec
->sh_link
);
837 report_fatal_error(errorToErrorCode(SymSecOrErr
.takeError()).message());
839 RelData
.d
.b
+= S
->sh_size
/ S
->sh_entsize
;
840 return relocation_iterator(RelocationRef(RelData
, this));
843 template <class ELFT
>
845 ELFObjectFile
<ELFT
>::getRelocatedSection(DataRefImpl Sec
) const {
846 if (EF
.getHeader()->e_type
!= ELF::ET_REL
)
847 return section_end();
849 const Elf_Shdr
*EShdr
= getSection(Sec
);
850 uintX_t Type
= EShdr
->sh_type
;
851 if (Type
!= ELF::SHT_REL
&& Type
!= ELF::SHT_RELA
)
852 return section_end();
854 auto R
= EF
.getSection(EShdr
->sh_info
);
856 report_fatal_error(errorToErrorCode(R
.takeError()).message());
857 return section_iterator(SectionRef(toDRI(*R
), this));
861 template <class ELFT
>
862 void ELFObjectFile
<ELFT
>::moveRelocationNext(DataRefImpl
&Rel
) const {
866 template <class ELFT
>
868 ELFObjectFile
<ELFT
>::getRelocationSymbol(DataRefImpl Rel
) const {
870 const Elf_Shdr
*sec
= getRelSection(Rel
);
871 if (sec
->sh_type
== ELF::SHT_REL
)
872 symbolIdx
= getRel(Rel
)->getSymbol(EF
.isMips64EL());
874 symbolIdx
= getRela(Rel
)->getSymbol(EF
.isMips64EL());
878 // FIXME: error check symbolIdx
879 DataRefImpl SymbolData
;
880 SymbolData
.d
.a
= sec
->sh_link
;
881 SymbolData
.d
.b
= symbolIdx
;
882 return symbol_iterator(SymbolRef(SymbolData
, this));
885 template <class ELFT
>
886 uint64_t ELFObjectFile
<ELFT
>::getRelocationOffset(DataRefImpl Rel
) const {
887 const Elf_Shdr
*sec
= getRelSection(Rel
);
888 if (sec
->sh_type
== ELF::SHT_REL
)
889 return getRel(Rel
)->r_offset
;
891 return getRela(Rel
)->r_offset
;
894 template <class ELFT
>
895 uint64_t ELFObjectFile
<ELFT
>::getRelocationType(DataRefImpl Rel
) const {
896 const Elf_Shdr
*sec
= getRelSection(Rel
);
897 if (sec
->sh_type
== ELF::SHT_REL
)
898 return getRel(Rel
)->getType(EF
.isMips64EL());
900 return getRela(Rel
)->getType(EF
.isMips64EL());
903 template <class ELFT
>
904 StringRef ELFObjectFile
<ELFT
>::getRelocationTypeName(uint32_t Type
) const {
905 return getELFRelocationTypeName(EF
.getHeader()->e_machine
, Type
);
908 template <class ELFT
>
909 void ELFObjectFile
<ELFT
>::getRelocationTypeName(
910 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
911 uint32_t type
= getRelocationType(Rel
);
912 EF
.getRelocationTypeName(type
, Result
);
915 template <class ELFT
>
917 ELFObjectFile
<ELFT
>::getRelocationAddend(DataRefImpl Rel
) const {
918 if (getRelSection(Rel
)->sh_type
!= ELF::SHT_RELA
)
919 return createError("Section is not SHT_RELA");
920 return (int64_t)getRela(Rel
)->r_addend
;
923 template <class ELFT
>
924 const typename ELFObjectFile
<ELFT
>::Elf_Rel
*
925 ELFObjectFile
<ELFT
>::getRel(DataRefImpl Rel
) const {
926 assert(getRelSection(Rel
)->sh_type
== ELF::SHT_REL
);
927 auto Ret
= EF
.template getEntry
<Elf_Rel
>(Rel
.d
.a
, Rel
.d
.b
);
929 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
933 template <class ELFT
>
934 const typename ELFObjectFile
<ELFT
>::Elf_Rela
*
935 ELFObjectFile
<ELFT
>::getRela(DataRefImpl Rela
) const {
936 assert(getRelSection(Rela
)->sh_type
== ELF::SHT_RELA
);
937 auto Ret
= EF
.template getEntry
<Elf_Rela
>(Rela
.d
.a
, Rela
.d
.b
);
939 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
943 template <class ELFT
>
944 Expected
<ELFObjectFile
<ELFT
>>
945 ELFObjectFile
<ELFT
>::create(MemoryBufferRef Object
) {
946 auto EFOrErr
= ELFFile
<ELFT
>::create(Object
.getBuffer());
947 if (Error E
= EFOrErr
.takeError())
949 auto EF
= std::move(*EFOrErr
);
951 auto SectionsOrErr
= EF
.sections();
953 return SectionsOrErr
.takeError();
955 const Elf_Shdr
*DotDynSymSec
= nullptr;
956 const Elf_Shdr
*DotSymtabSec
= nullptr;
957 ArrayRef
<Elf_Word
> ShndxTable
;
958 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
959 switch (Sec
.sh_type
) {
960 case ELF::SHT_DYNSYM
: {
965 case ELF::SHT_SYMTAB
: {
970 case ELF::SHT_SYMTAB_SHNDX
: {
971 auto TableOrErr
= EF
.getSHNDXTable(Sec
);
973 return TableOrErr
.takeError();
974 ShndxTable
= *TableOrErr
;
979 return ELFObjectFile
<ELFT
>(Object
, EF
, DotDynSymSec
, DotSymtabSec
,
983 template <class ELFT
>
984 ELFObjectFile
<ELFT
>::ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
985 const Elf_Shdr
*DotDynSymSec
,
986 const Elf_Shdr
*DotSymtabSec
,
987 ArrayRef
<Elf_Word
> ShndxTable
)
989 getELFType(ELFT::TargetEndianness
== support::little
, ELFT::Is64Bits
),
991 EF(EF
), DotDynSymSec(DotDynSymSec
), DotSymtabSec(DotSymtabSec
),
992 ShndxTable(ShndxTable
) {}
994 template <class ELFT
>
995 ELFObjectFile
<ELFT
>::ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
)
996 : ELFObjectFile(Other
.Data
, Other
.EF
, Other
.DotDynSymSec
,
997 Other
.DotSymtabSec
, Other
.ShndxTable
) {}
999 template <class ELFT
>
1000 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_begin() const {
1003 DotSymtabSec
&& DotSymtabSec
->sh_size
>= sizeof(Elf_Sym
) ? 1 : 0);
1004 return basic_symbol_iterator(SymbolRef(Sym
, this));
1007 template <class ELFT
>
1008 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_end() const {
1009 const Elf_Shdr
*SymTab
= DotSymtabSec
;
1011 return symbol_begin();
1012 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1013 return basic_symbol_iterator(SymbolRef(Sym
, this));
1016 template <class ELFT
>
1017 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_begin() const {
1018 DataRefImpl Sym
= toDRI(DotDynSymSec
, 0);
1019 return symbol_iterator(SymbolRef(Sym
, this));
1022 template <class ELFT
>
1023 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_end() const {
1024 const Elf_Shdr
*SymTab
= DotDynSymSec
;
1026 return dynamic_symbol_begin();
1027 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1028 return basic_symbol_iterator(SymbolRef(Sym
, this));
1031 template <class ELFT
>
1032 section_iterator ELFObjectFile
<ELFT
>::section_begin() const {
1033 auto SectionsOrErr
= EF
.sections();
1035 return section_iterator(SectionRef());
1036 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).begin()), this));
1039 template <class ELFT
>
1040 section_iterator ELFObjectFile
<ELFT
>::section_end() const {
1041 auto SectionsOrErr
= EF
.sections();
1043 return section_iterator(SectionRef());
1044 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).end()), this));
1047 template <class ELFT
>
1048 uint8_t ELFObjectFile
<ELFT
>::getBytesInAddress() const {
1049 return ELFT::Is64Bits
? 8 : 4;
1052 template <class ELFT
>
1053 StringRef ELFObjectFile
<ELFT
>::getFileFormatName() const {
1054 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1055 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1056 case ELF::ELFCLASS32
:
1057 switch (EF
.getHeader()->e_machine
) {
1059 return "ELF32-i386";
1061 return "ELF32-iamcu";
1062 case ELF::EM_X86_64
:
1063 return "ELF32-x86-64";
1065 return (IsLittleEndian
? "ELF32-arm-little" : "ELF32-arm-big");
1068 case ELF::EM_HEXAGON
:
1069 return "ELF32-hexagon";
1071 return "ELF32-lanai";
1073 return "ELF32-mips";
1074 case ELF::EM_MSP430
:
1075 return "ELF32-msp430";
1079 return "ELF32-riscv";
1081 case ELF::EM_SPARC32PLUS
:
1082 return "ELF32-sparc";
1083 case ELF::EM_AMDGPU
:
1084 return "ELF32-amdgpu";
1086 return "ELF32-unknown";
1088 case ELF::ELFCLASS64
:
1089 switch (EF
.getHeader()->e_machine
) {
1091 return "ELF64-i386";
1092 case ELF::EM_X86_64
:
1093 return "ELF64-x86-64";
1094 case ELF::EM_AARCH64
:
1095 return (IsLittleEndian
? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1097 return "ELF64-ppc64";
1099 return "ELF64-riscv";
1101 return "ELF64-s390";
1102 case ELF::EM_SPARCV9
:
1103 return "ELF64-sparc";
1105 return "ELF64-mips";
1106 case ELF::EM_AMDGPU
:
1107 return "ELF64-amdgpu";
1111 return "ELF64-unknown";
1114 // FIXME: Proper error handling.
1115 report_fatal_error("Invalid ELFCLASS!");
1119 template <class ELFT
> Triple::ArchType ELFObjectFile
<ELFT
>::getArch() const {
1120 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1121 switch (EF
.getHeader()->e_machine
) {
1125 case ELF::EM_X86_64
:
1126 return Triple::x86_64
;
1127 case ELF::EM_AARCH64
:
1128 return IsLittleEndian
? Triple::aarch64
: Triple::aarch64_be
;
1133 case ELF::EM_HEXAGON
:
1134 return Triple::hexagon
;
1136 return Triple::lanai
;
1138 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1139 case ELF::ELFCLASS32
:
1140 return IsLittleEndian
? Triple::mipsel
: Triple::mips
;
1141 case ELF::ELFCLASS64
:
1142 return IsLittleEndian
? Triple::mips64el
: Triple::mips64
;
1144 report_fatal_error("Invalid ELFCLASS!");
1146 case ELF::EM_MSP430
:
1147 return Triple::msp430
;
1151 return IsLittleEndian
? Triple::ppc64le
: Triple::ppc64
;
1153 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1154 case ELF::ELFCLASS32
:
1155 return Triple::riscv32
;
1156 case ELF::ELFCLASS64
:
1157 return Triple::riscv64
;
1159 report_fatal_error("Invalid ELFCLASS!");
1162 return Triple::systemz
;
1165 case ELF::EM_SPARC32PLUS
:
1166 return IsLittleEndian
? Triple::sparcel
: Triple::sparc
;
1167 case ELF::EM_SPARCV9
:
1168 return Triple::sparcv9
;
1170 case ELF::EM_AMDGPU
: {
1171 if (!IsLittleEndian
)
1172 return Triple::UnknownArch
;
1174 unsigned MACH
= EF
.getHeader()->e_flags
& ELF::EF_AMDGPU_MACH
;
1175 if (MACH
>= ELF::EF_AMDGPU_MACH_R600_FIRST
&&
1176 MACH
<= ELF::EF_AMDGPU_MACH_R600_LAST
)
1177 return Triple::r600
;
1178 if (MACH
>= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST
&&
1179 MACH
<= ELF::EF_AMDGPU_MACH_AMDGCN_LAST
)
1180 return Triple::amdgcn
;
1182 return Triple::UnknownArch
;
1186 return IsLittleEndian
? Triple::bpfel
: Triple::bpfeb
;
1189 return Triple::UnknownArch
;
1193 template <class ELFT
>
1194 Expected
<uint64_t> ELFObjectFile
<ELFT
>::getStartAddress() const {
1195 return EF
.getHeader()->e_entry
;
1198 template <class ELFT
>
1199 ELFObjectFileBase::elf_symbol_iterator_range
1200 ELFObjectFile
<ELFT
>::getDynamicSymbolIterators() const {
1201 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1204 template <class ELFT
> bool ELFObjectFile
<ELFT
>::isRelocatableObject() const {
1205 return EF
.getHeader()->e_type
== ELF::ET_REL
;
1208 } // end namespace object
1209 } // end namespace llvm
1211 #endif // LLVM_OBJECT_ELFOBJECTFILE_H