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 Expected
<section_iterator
>
292 getRelocatedSection(DataRefImpl Sec
) const override
;
294 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
295 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
296 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
297 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
298 void getRelocationTypeName(DataRefImpl Rel
,
299 SmallVectorImpl
<char> &Result
) const override
;
301 uint32_t getSectionType(DataRefImpl Sec
) const override
;
302 uint64_t getSectionFlags(DataRefImpl Sec
) const override
;
303 uint64_t getSectionOffset(DataRefImpl Sec
) const override
;
304 StringRef
getRelocationTypeName(uint32_t Type
) const;
306 /// Get the relocation section that contains \a Rel.
307 const Elf_Shdr
*getRelSection(DataRefImpl Rel
) const {
308 auto RelSecOrErr
= EF
.getSection(Rel
.d
.a
);
310 report_fatal_error(errorToErrorCode(RelSecOrErr
.takeError()).message());
314 DataRefImpl
toDRI(const Elf_Shdr
*SymTable
, unsigned SymbolNum
) const {
321 assert(SymTable
->sh_type
== ELF::SHT_SYMTAB
||
322 SymTable
->sh_type
== ELF::SHT_DYNSYM
);
324 auto SectionsOrErr
= EF
.sections();
325 if (!SectionsOrErr
) {
330 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
331 unsigned SymTableIndex
=
332 (reinterpret_cast<uintptr_t>(SymTable
) - SHT
) / sizeof(Elf_Shdr
);
334 DRI
.d
.a
= SymTableIndex
;
339 const Elf_Shdr
*toELFShdrIter(DataRefImpl Sec
) const {
340 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
343 DataRefImpl
toDRI(const Elf_Shdr
*Sec
) const {
345 DRI
.p
= reinterpret_cast<uintptr_t>(Sec
);
349 DataRefImpl
toDRI(const Elf_Dyn
*Dyn
) const {
351 DRI
.p
= reinterpret_cast<uintptr_t>(Dyn
);
355 bool isExportedToOtherDSO(const Elf_Sym
*ESym
) const {
356 unsigned char Binding
= ESym
->getBinding();
357 unsigned char Visibility
= ESym
->getVisibility();
359 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
360 // visibility is either DEFAULT or PROTECTED. All other symbols are not
363 (Binding
== ELF::STB_GLOBAL
|| Binding
== ELF::STB_WEAK
||
364 Binding
== ELF::STB_GNU_UNIQUE
) &&
365 (Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_PROTECTED
));
368 Error
getBuildAttributes(ARMAttributeParser
&Attributes
) const override
{
369 auto SectionsOrErr
= EF
.sections();
371 return SectionsOrErr
.takeError();
373 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
374 if (Sec
.sh_type
== ELF::SHT_ARM_ATTRIBUTES
) {
375 auto ErrorOrContents
= EF
.getSectionContents(&Sec
);
376 if (!ErrorOrContents
)
377 return ErrorOrContents
.takeError();
379 auto Contents
= ErrorOrContents
.get();
380 if (Contents
[0] != ARMBuildAttrs::Format_Version
|| Contents
.size() == 1)
381 return Error::success();
383 Attributes
.Parse(Contents
, ELFT::TargetEndianness
== support::little
);
387 return Error::success();
390 // This flag is used for classof, to distinguish ELFObjectFile from
391 // its subclass. If more subclasses will be created, this flag will
392 // have to become an enum.
393 bool isDyldELFObject
;
396 ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
);
397 static Expected
<ELFObjectFile
<ELFT
>> create(MemoryBufferRef Object
);
399 const Elf_Rel
*getRel(DataRefImpl Rel
) const;
400 const Elf_Rela
*getRela(DataRefImpl Rela
) const;
402 const Elf_Sym
*getSymbol(DataRefImpl Sym
) const {
403 auto Ret
= EF
.template getEntry
<Elf_Sym
>(Sym
.d
.a
, Sym
.d
.b
);
405 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
409 const Elf_Shdr
*getSection(DataRefImpl Sec
) const {
410 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
413 basic_symbol_iterator
symbol_begin() const override
;
414 basic_symbol_iterator
symbol_end() const override
;
416 elf_symbol_iterator
dynamic_symbol_begin() const;
417 elf_symbol_iterator
dynamic_symbol_end() const;
419 section_iterator
section_begin() const override
;
420 section_iterator
section_end() const override
;
422 Expected
<int64_t> getRelocationAddend(DataRefImpl Rel
) const override
;
424 uint8_t getBytesInAddress() const override
;
425 StringRef
getFileFormatName() const override
;
426 Triple::ArchType
getArch() const override
;
427 Expected
<uint64_t> getStartAddress() const override
;
429 unsigned getPlatformFlags() const override
{ return EF
.getHeader()->e_flags
; }
431 const ELFFile
<ELFT
> *getELFFile() const { return &EF
; }
433 bool isDyldType() const { return isDyldELFObject
; }
434 static bool classof(const Binary
*v
) {
435 return v
->getType() == getELFType(ELFT::TargetEndianness
== support::little
,
439 elf_symbol_iterator_range
getDynamicSymbolIterators() const override
;
441 bool isRelocatableObject() const override
;
444 using ELF32LEObjectFile
= ELFObjectFile
<ELF32LE
>;
445 using ELF64LEObjectFile
= ELFObjectFile
<ELF64LE
>;
446 using ELF32BEObjectFile
= ELFObjectFile
<ELF32BE
>;
447 using ELF64BEObjectFile
= ELFObjectFile
<ELF64BE
>;
449 template <class ELFT
>
450 void ELFObjectFile
<ELFT
>::moveSymbolNext(DataRefImpl
&Sym
) const {
454 template <class ELFT
>
455 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSymbolName(DataRefImpl Sym
) const {
456 const Elf_Sym
*ESym
= getSymbol(Sym
);
457 auto SymTabOrErr
= EF
.getSection(Sym
.d
.a
);
459 return SymTabOrErr
.takeError();
460 const Elf_Shdr
*SymTableSec
= *SymTabOrErr
;
461 auto StrTabOrErr
= EF
.getSection(SymTableSec
->sh_link
);
463 return StrTabOrErr
.takeError();
464 const Elf_Shdr
*StringTableSec
= *StrTabOrErr
;
465 auto SymStrTabOrErr
= EF
.getStringTable(StringTableSec
);
467 return SymStrTabOrErr
.takeError();
468 Expected
<StringRef
> Name
= ESym
->getName(*SymStrTabOrErr
);
469 if (Name
&& !Name
->empty())
472 // If the symbol name is empty use the section name.
473 if (ESym
->getType() == ELF::STT_SECTION
) {
474 if (Expected
<section_iterator
> SecOrErr
= getSymbolSection(Sym
)) {
475 consumeError(Name
.takeError());
476 return (*SecOrErr
)->getName();
482 template <class ELFT
>
483 uint64_t ELFObjectFile
<ELFT
>::getSectionFlags(DataRefImpl Sec
) const {
484 return getSection(Sec
)->sh_flags
;
487 template <class ELFT
>
488 uint32_t ELFObjectFile
<ELFT
>::getSectionType(DataRefImpl Sec
) const {
489 return getSection(Sec
)->sh_type
;
492 template <class ELFT
>
493 uint64_t ELFObjectFile
<ELFT
>::getSectionOffset(DataRefImpl Sec
) const {
494 return getSection(Sec
)->sh_offset
;
497 template <class ELFT
>
498 uint64_t ELFObjectFile
<ELFT
>::getSymbolValueImpl(DataRefImpl Symb
) const {
499 const Elf_Sym
*ESym
= getSymbol(Symb
);
500 uint64_t Ret
= ESym
->st_value
;
501 if (ESym
->st_shndx
== ELF::SHN_ABS
)
504 const Elf_Ehdr
*Header
= EF
.getHeader();
505 // Clear the ARM/Thumb or microMIPS indicator flag.
506 if ((Header
->e_machine
== ELF::EM_ARM
|| Header
->e_machine
== ELF::EM_MIPS
) &&
507 ESym
->getType() == ELF::STT_FUNC
)
513 template <class ELFT
>
515 ELFObjectFile
<ELFT
>::getSymbolAddress(DataRefImpl Symb
) const {
516 uint64_t Result
= getSymbolValue(Symb
);
517 const Elf_Sym
*ESym
= getSymbol(Symb
);
518 switch (ESym
->st_shndx
) {
519 case ELF::SHN_COMMON
:
525 const Elf_Ehdr
*Header
= EF
.getHeader();
526 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
528 return SymTabOrErr
.takeError();
529 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
531 if (Header
->e_type
== ELF::ET_REL
) {
532 auto SectionOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
534 return SectionOrErr
.takeError();
535 const Elf_Shdr
*Section
= *SectionOrErr
;
537 Result
+= Section
->sh_addr
;
543 template <class ELFT
>
544 uint32_t ELFObjectFile
<ELFT
>::getSymbolAlignment(DataRefImpl Symb
) const {
545 const Elf_Sym
*Sym
= getSymbol(Symb
);
546 if (Sym
->st_shndx
== ELF::SHN_COMMON
)
547 return Sym
->st_value
;
551 template <class ELFT
>
552 uint16_t ELFObjectFile
<ELFT
>::getEMachine() const {
553 return EF
.getHeader()->e_machine
;
556 template <class ELFT
> uint16_t ELFObjectFile
<ELFT
>::getEType() const {
557 return EF
.getHeader()->e_type
;
560 template <class ELFT
>
561 uint64_t ELFObjectFile
<ELFT
>::getSymbolSize(DataRefImpl Sym
) const {
562 return getSymbol(Sym
)->st_size
;
565 template <class ELFT
>
566 uint64_t ELFObjectFile
<ELFT
>::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
567 return getSymbol(Symb
)->st_size
;
570 template <class ELFT
>
571 uint8_t ELFObjectFile
<ELFT
>::getSymbolBinding(DataRefImpl Symb
) const {
572 return getSymbol(Symb
)->getBinding();
575 template <class ELFT
>
576 uint8_t ELFObjectFile
<ELFT
>::getSymbolOther(DataRefImpl Symb
) const {
577 return getSymbol(Symb
)->st_other
;
580 template <class ELFT
>
581 uint8_t ELFObjectFile
<ELFT
>::getSymbolELFType(DataRefImpl Symb
) const {
582 return getSymbol(Symb
)->getType();
585 template <class ELFT
>
586 Expected
<SymbolRef::Type
>
587 ELFObjectFile
<ELFT
>::getSymbolType(DataRefImpl Symb
) const {
588 const Elf_Sym
*ESym
= getSymbol(Symb
);
590 switch (ESym
->getType()) {
591 case ELF::STT_NOTYPE
:
592 return SymbolRef::ST_Unknown
;
593 case ELF::STT_SECTION
:
594 return SymbolRef::ST_Debug
;
596 return SymbolRef::ST_File
;
598 return SymbolRef::ST_Function
;
599 case ELF::STT_OBJECT
:
600 case ELF::STT_COMMON
:
602 return SymbolRef::ST_Data
;
604 return SymbolRef::ST_Other
;
608 template <class ELFT
>
609 uint32_t ELFObjectFile
<ELFT
>::getSymbolFlags(DataRefImpl Sym
) const {
610 const Elf_Sym
*ESym
= getSymbol(Sym
);
612 uint32_t Result
= SymbolRef::SF_None
;
614 if (ESym
->getBinding() != ELF::STB_LOCAL
)
615 Result
|= SymbolRef::SF_Global
;
617 if (ESym
->getBinding() == ELF::STB_WEAK
)
618 Result
|= SymbolRef::SF_Weak
;
620 if (ESym
->st_shndx
== ELF::SHN_ABS
)
621 Result
|= SymbolRef::SF_Absolute
;
623 if (ESym
->getType() == ELF::STT_FILE
|| ESym
->getType() == ELF::STT_SECTION
)
624 Result
|= SymbolRef::SF_FormatSpecific
;
626 auto DotSymtabSecSyms
= EF
.symbols(DotSymtabSec
);
627 if (DotSymtabSecSyms
&& ESym
== (*DotSymtabSecSyms
).begin())
628 Result
|= SymbolRef::SF_FormatSpecific
;
629 auto DotDynSymSecSyms
= EF
.symbols(DotDynSymSec
);
630 if (DotDynSymSecSyms
&& ESym
== (*DotDynSymSecSyms
).begin())
631 Result
|= SymbolRef::SF_FormatSpecific
;
633 if (EF
.getHeader()->e_machine
== ELF::EM_ARM
) {
634 if (Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
)) {
635 StringRef Name
= *NameOrErr
;
636 if (Name
.startswith("$d") || Name
.startswith("$t") ||
637 Name
.startswith("$a"))
638 Result
|= SymbolRef::SF_FormatSpecific
;
640 // TODO: Actually report errors helpfully.
641 consumeError(NameOrErr
.takeError());
643 if (ESym
->getType() == ELF::STT_FUNC
&& (ESym
->st_value
& 1) == 1)
644 Result
|= SymbolRef::SF_Thumb
;
647 if (ESym
->st_shndx
== ELF::SHN_UNDEF
)
648 Result
|= SymbolRef::SF_Undefined
;
650 if (ESym
->getType() == ELF::STT_COMMON
|| ESym
->st_shndx
== ELF::SHN_COMMON
)
651 Result
|= SymbolRef::SF_Common
;
653 if (isExportedToOtherDSO(ESym
))
654 Result
|= SymbolRef::SF_Exported
;
656 if (ESym
->getVisibility() == ELF::STV_HIDDEN
)
657 Result
|= SymbolRef::SF_Hidden
;
662 template <class ELFT
>
663 Expected
<section_iterator
>
664 ELFObjectFile
<ELFT
>::getSymbolSection(const Elf_Sym
*ESym
,
665 const Elf_Shdr
*SymTab
) const {
666 auto ESecOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
668 return ESecOrErr
.takeError();
670 const Elf_Shdr
*ESec
= *ESecOrErr
;
672 return section_end();
675 Sec
.p
= reinterpret_cast<intptr_t>(ESec
);
676 return section_iterator(SectionRef(Sec
, this));
679 template <class ELFT
>
680 Expected
<section_iterator
>
681 ELFObjectFile
<ELFT
>::getSymbolSection(DataRefImpl Symb
) const {
682 const Elf_Sym
*Sym
= getSymbol(Symb
);
683 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
685 return SymTabOrErr
.takeError();
686 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
687 return getSymbolSection(Sym
, SymTab
);
690 template <class ELFT
>
691 void ELFObjectFile
<ELFT
>::moveSectionNext(DataRefImpl
&Sec
) const {
692 const Elf_Shdr
*ESec
= getSection(Sec
);
696 template <class ELFT
>
697 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSectionName(DataRefImpl Sec
) const {
698 return EF
.getSectionName(&*getSection(Sec
));
701 template <class ELFT
>
702 uint64_t ELFObjectFile
<ELFT
>::getSectionAddress(DataRefImpl Sec
) const {
703 return getSection(Sec
)->sh_addr
;
706 template <class ELFT
>
707 uint64_t ELFObjectFile
<ELFT
>::getSectionIndex(DataRefImpl Sec
) const {
708 auto SectionsOrErr
= EF
.sections();
709 handleAllErrors(std::move(SectionsOrErr
.takeError()),
710 [](const ErrorInfoBase
&) {
711 llvm_unreachable("unable to get section index");
713 const Elf_Shdr
*First
= SectionsOrErr
->begin();
714 return getSection(Sec
) - First
;
717 template <class ELFT
>
718 uint64_t ELFObjectFile
<ELFT
>::getSectionSize(DataRefImpl Sec
) const {
719 return getSection(Sec
)->sh_size
;
722 template <class ELFT
>
723 Expected
<ArrayRef
<uint8_t>>
724 ELFObjectFile
<ELFT
>::getSectionContents(DataRefImpl Sec
) const {
725 const Elf_Shdr
*EShdr
= getSection(Sec
);
726 if (std::error_code EC
=
727 checkOffset(getMemoryBufferRef(),
728 (uintptr_t)base() + EShdr
->sh_offset
, EShdr
->sh_size
))
729 return errorCodeToError(EC
);
730 return makeArrayRef((const uint8_t *)base() + EShdr
->sh_offset
,
734 template <class ELFT
>
735 uint64_t ELFObjectFile
<ELFT
>::getSectionAlignment(DataRefImpl Sec
) const {
736 return getSection(Sec
)->sh_addralign
;
739 template <class ELFT
>
740 bool ELFObjectFile
<ELFT
>::isSectionCompressed(DataRefImpl Sec
) const {
741 return getSection(Sec
)->sh_flags
& ELF::SHF_COMPRESSED
;
744 template <class ELFT
>
745 bool ELFObjectFile
<ELFT
>::isSectionText(DataRefImpl Sec
) const {
746 return getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
;
749 template <class ELFT
>
750 bool ELFObjectFile
<ELFT
>::isSectionData(DataRefImpl Sec
) const {
751 const Elf_Shdr
*EShdr
= getSection(Sec
);
752 return EShdr
->sh_type
== ELF::SHT_PROGBITS
&&
753 EShdr
->sh_flags
& ELF::SHF_ALLOC
&&
754 !(EShdr
->sh_flags
& ELF::SHF_EXECINSTR
);
757 template <class ELFT
>
758 bool ELFObjectFile
<ELFT
>::isSectionBSS(DataRefImpl Sec
) const {
759 const Elf_Shdr
*EShdr
= getSection(Sec
);
760 return EShdr
->sh_flags
& (ELF::SHF_ALLOC
| ELF::SHF_WRITE
) &&
761 EShdr
->sh_type
== ELF::SHT_NOBITS
;
764 template <class ELFT
>
765 std::vector
<SectionRef
>
766 ELFObjectFile
<ELFT
>::dynamic_relocation_sections() const {
767 std::vector
<SectionRef
> Res
;
768 std::vector
<uintptr_t> Offsets
;
770 auto SectionsOrErr
= EF
.sections();
774 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
775 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
778 reinterpret_cast<Elf_Dyn
*>((uintptr_t)base() + Sec
.sh_offset
);
779 for (; Dynamic
->d_tag
!= ELF::DT_NULL
; Dynamic
++) {
780 if (Dynamic
->d_tag
== ELF::DT_REL
|| Dynamic
->d_tag
== ELF::DT_RELA
||
781 Dynamic
->d_tag
== ELF::DT_JMPREL
) {
782 Offsets
.push_back(Dynamic
->d_un
.d_val
);
786 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
787 if (is_contained(Offsets
, Sec
.sh_addr
))
788 Res
.emplace_back(toDRI(&Sec
), this);
793 template <class ELFT
>
794 bool ELFObjectFile
<ELFT
>::isSectionVirtual(DataRefImpl Sec
) const {
795 return getSection(Sec
)->sh_type
== ELF::SHT_NOBITS
;
798 template <class ELFT
>
799 bool ELFObjectFile
<ELFT
>::isBerkeleyText(DataRefImpl Sec
) const {
800 return getSection(Sec
)->sh_flags
& ELF::SHF_ALLOC
&&
801 (getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
||
802 !(getSection(Sec
)->sh_flags
& ELF::SHF_WRITE
));
805 template <class ELFT
>
806 bool ELFObjectFile
<ELFT
>::isBerkeleyData(DataRefImpl Sec
) const {
807 const Elf_Shdr
*EShdr
= getSection(Sec
);
808 return !isBerkeleyText(Sec
) && EShdr
->sh_type
!= ELF::SHT_NOBITS
&&
809 EShdr
->sh_flags
& ELF::SHF_ALLOC
;
812 template <class ELFT
>
814 ELFObjectFile
<ELFT
>::section_rel_begin(DataRefImpl Sec
) const {
816 auto SectionsOrErr
= EF
.sections();
818 return relocation_iterator(RelocationRef());
819 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
820 RelData
.d
.a
= (Sec
.p
- SHT
) / EF
.getHeader()->e_shentsize
;
822 return relocation_iterator(RelocationRef(RelData
, this));
825 template <class ELFT
>
827 ELFObjectFile
<ELFT
>::section_rel_end(DataRefImpl Sec
) const {
828 const Elf_Shdr
*S
= reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
829 relocation_iterator Begin
= section_rel_begin(Sec
);
830 if (S
->sh_type
!= ELF::SHT_RELA
&& S
->sh_type
!= ELF::SHT_REL
)
832 DataRefImpl RelData
= Begin
->getRawDataRefImpl();
833 const Elf_Shdr
*RelSec
= getRelSection(RelData
);
835 // Error check sh_link here so that getRelocationSymbol can just use it.
836 auto SymSecOrErr
= EF
.getSection(RelSec
->sh_link
);
838 report_fatal_error(errorToErrorCode(SymSecOrErr
.takeError()).message());
840 RelData
.d
.b
+= S
->sh_size
/ S
->sh_entsize
;
841 return relocation_iterator(RelocationRef(RelData
, this));
844 template <class ELFT
>
845 Expected
<section_iterator
>
846 ELFObjectFile
<ELFT
>::getRelocatedSection(DataRefImpl Sec
) const {
847 if (EF
.getHeader()->e_type
!= ELF::ET_REL
)
848 return section_end();
850 const Elf_Shdr
*EShdr
= getSection(Sec
);
851 uintX_t Type
= EShdr
->sh_type
;
852 if (Type
!= ELF::SHT_REL
&& Type
!= ELF::SHT_RELA
)
853 return section_end();
855 Expected
<const Elf_Shdr
*> SecOrErr
= EF
.getSection(EShdr
->sh_info
);
857 return SecOrErr
.takeError();
858 return section_iterator(SectionRef(toDRI(*SecOrErr
), this));
862 template <class ELFT
>
863 void ELFObjectFile
<ELFT
>::moveRelocationNext(DataRefImpl
&Rel
) const {
867 template <class ELFT
>
869 ELFObjectFile
<ELFT
>::getRelocationSymbol(DataRefImpl Rel
) const {
871 const Elf_Shdr
*sec
= getRelSection(Rel
);
872 if (sec
->sh_type
== ELF::SHT_REL
)
873 symbolIdx
= getRel(Rel
)->getSymbol(EF
.isMips64EL());
875 symbolIdx
= getRela(Rel
)->getSymbol(EF
.isMips64EL());
879 // FIXME: error check symbolIdx
880 DataRefImpl SymbolData
;
881 SymbolData
.d
.a
= sec
->sh_link
;
882 SymbolData
.d
.b
= symbolIdx
;
883 return symbol_iterator(SymbolRef(SymbolData
, this));
886 template <class ELFT
>
887 uint64_t ELFObjectFile
<ELFT
>::getRelocationOffset(DataRefImpl Rel
) const {
888 const Elf_Shdr
*sec
= getRelSection(Rel
);
889 if (sec
->sh_type
== ELF::SHT_REL
)
890 return getRel(Rel
)->r_offset
;
892 return getRela(Rel
)->r_offset
;
895 template <class ELFT
>
896 uint64_t ELFObjectFile
<ELFT
>::getRelocationType(DataRefImpl Rel
) const {
897 const Elf_Shdr
*sec
= getRelSection(Rel
);
898 if (sec
->sh_type
== ELF::SHT_REL
)
899 return getRel(Rel
)->getType(EF
.isMips64EL());
901 return getRela(Rel
)->getType(EF
.isMips64EL());
904 template <class ELFT
>
905 StringRef ELFObjectFile
<ELFT
>::getRelocationTypeName(uint32_t Type
) const {
906 return getELFRelocationTypeName(EF
.getHeader()->e_machine
, Type
);
909 template <class ELFT
>
910 void ELFObjectFile
<ELFT
>::getRelocationTypeName(
911 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
912 uint32_t type
= getRelocationType(Rel
);
913 EF
.getRelocationTypeName(type
, Result
);
916 template <class ELFT
>
918 ELFObjectFile
<ELFT
>::getRelocationAddend(DataRefImpl Rel
) const {
919 if (getRelSection(Rel
)->sh_type
!= ELF::SHT_RELA
)
920 return createError("Section is not SHT_RELA");
921 return (int64_t)getRela(Rel
)->r_addend
;
924 template <class ELFT
>
925 const typename ELFObjectFile
<ELFT
>::Elf_Rel
*
926 ELFObjectFile
<ELFT
>::getRel(DataRefImpl Rel
) const {
927 assert(getRelSection(Rel
)->sh_type
== ELF::SHT_REL
);
928 auto Ret
= EF
.template getEntry
<Elf_Rel
>(Rel
.d
.a
, Rel
.d
.b
);
930 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
934 template <class ELFT
>
935 const typename ELFObjectFile
<ELFT
>::Elf_Rela
*
936 ELFObjectFile
<ELFT
>::getRela(DataRefImpl Rela
) const {
937 assert(getRelSection(Rela
)->sh_type
== ELF::SHT_RELA
);
938 auto Ret
= EF
.template getEntry
<Elf_Rela
>(Rela
.d
.a
, Rela
.d
.b
);
940 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
944 template <class ELFT
>
945 Expected
<ELFObjectFile
<ELFT
>>
946 ELFObjectFile
<ELFT
>::create(MemoryBufferRef Object
) {
947 auto EFOrErr
= ELFFile
<ELFT
>::create(Object
.getBuffer());
948 if (Error E
= EFOrErr
.takeError())
950 auto EF
= std::move(*EFOrErr
);
952 auto SectionsOrErr
= EF
.sections();
954 return SectionsOrErr
.takeError();
956 const Elf_Shdr
*DotDynSymSec
= nullptr;
957 const Elf_Shdr
*DotSymtabSec
= nullptr;
958 ArrayRef
<Elf_Word
> ShndxTable
;
959 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
960 switch (Sec
.sh_type
) {
961 case ELF::SHT_DYNSYM
: {
966 case ELF::SHT_SYMTAB
: {
971 case ELF::SHT_SYMTAB_SHNDX
: {
972 auto TableOrErr
= EF
.getSHNDXTable(Sec
);
974 return TableOrErr
.takeError();
975 ShndxTable
= *TableOrErr
;
980 return ELFObjectFile
<ELFT
>(Object
, EF
, DotDynSymSec
, DotSymtabSec
,
984 template <class ELFT
>
985 ELFObjectFile
<ELFT
>::ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
986 const Elf_Shdr
*DotDynSymSec
,
987 const Elf_Shdr
*DotSymtabSec
,
988 ArrayRef
<Elf_Word
> ShndxTable
)
990 getELFType(ELFT::TargetEndianness
== support::little
, ELFT::Is64Bits
),
992 EF(EF
), DotDynSymSec(DotDynSymSec
), DotSymtabSec(DotSymtabSec
),
993 ShndxTable(ShndxTable
) {}
995 template <class ELFT
>
996 ELFObjectFile
<ELFT
>::ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
)
997 : ELFObjectFile(Other
.Data
, Other
.EF
, Other
.DotDynSymSec
,
998 Other
.DotSymtabSec
, Other
.ShndxTable
) {}
1000 template <class ELFT
>
1001 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_begin() const {
1004 DotSymtabSec
&& DotSymtabSec
->sh_size
>= sizeof(Elf_Sym
) ? 1 : 0);
1005 return basic_symbol_iterator(SymbolRef(Sym
, this));
1008 template <class ELFT
>
1009 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_end() const {
1010 const Elf_Shdr
*SymTab
= DotSymtabSec
;
1012 return symbol_begin();
1013 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1014 return basic_symbol_iterator(SymbolRef(Sym
, this));
1017 template <class ELFT
>
1018 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_begin() const {
1019 DataRefImpl Sym
= toDRI(DotDynSymSec
, 0);
1020 return symbol_iterator(SymbolRef(Sym
, this));
1023 template <class ELFT
>
1024 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_end() const {
1025 const Elf_Shdr
*SymTab
= DotDynSymSec
;
1027 return dynamic_symbol_begin();
1028 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1029 return basic_symbol_iterator(SymbolRef(Sym
, this));
1032 template <class ELFT
>
1033 section_iterator ELFObjectFile
<ELFT
>::section_begin() const {
1034 auto SectionsOrErr
= EF
.sections();
1036 return section_iterator(SectionRef());
1037 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).begin()), this));
1040 template <class ELFT
>
1041 section_iterator ELFObjectFile
<ELFT
>::section_end() const {
1042 auto SectionsOrErr
= EF
.sections();
1044 return section_iterator(SectionRef());
1045 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).end()), this));
1048 template <class ELFT
>
1049 uint8_t ELFObjectFile
<ELFT
>::getBytesInAddress() const {
1050 return ELFT::Is64Bits
? 8 : 4;
1053 template <class ELFT
>
1054 StringRef ELFObjectFile
<ELFT
>::getFileFormatName() const {
1055 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1056 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1057 case ELF::ELFCLASS32
:
1058 switch (EF
.getHeader()->e_machine
) {
1060 return "ELF32-i386";
1062 return "ELF32-iamcu";
1063 case ELF::EM_X86_64
:
1064 return "ELF32-x86-64";
1066 return (IsLittleEndian
? "ELF32-arm-little" : "ELF32-arm-big");
1069 case ELF::EM_HEXAGON
:
1070 return "ELF32-hexagon";
1072 return "ELF32-lanai";
1074 return "ELF32-mips";
1075 case ELF::EM_MSP430
:
1076 return "ELF32-msp430";
1080 return "ELF32-riscv";
1082 case ELF::EM_SPARC32PLUS
:
1083 return "ELF32-sparc";
1084 case ELF::EM_AMDGPU
:
1085 return "ELF32-amdgpu";
1087 return "ELF32-unknown";
1089 case ELF::ELFCLASS64
:
1090 switch (EF
.getHeader()->e_machine
) {
1092 return "ELF64-i386";
1093 case ELF::EM_X86_64
:
1094 return "ELF64-x86-64";
1095 case ELF::EM_AARCH64
:
1096 return (IsLittleEndian
? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1098 return "ELF64-ppc64";
1100 return "ELF64-riscv";
1102 return "ELF64-s390";
1103 case ELF::EM_SPARCV9
:
1104 return "ELF64-sparc";
1106 return "ELF64-mips";
1107 case ELF::EM_AMDGPU
:
1108 return "ELF64-amdgpu";
1112 return "ELF64-unknown";
1115 // FIXME: Proper error handling.
1116 report_fatal_error("Invalid ELFCLASS!");
1120 template <class ELFT
> Triple::ArchType ELFObjectFile
<ELFT
>::getArch() const {
1121 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1122 switch (EF
.getHeader()->e_machine
) {
1126 case ELF::EM_X86_64
:
1127 return Triple::x86_64
;
1128 case ELF::EM_AARCH64
:
1129 return IsLittleEndian
? Triple::aarch64
: Triple::aarch64_be
;
1134 case ELF::EM_HEXAGON
:
1135 return Triple::hexagon
;
1137 return Triple::lanai
;
1139 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1140 case ELF::ELFCLASS32
:
1141 return IsLittleEndian
? Triple::mipsel
: Triple::mips
;
1142 case ELF::ELFCLASS64
:
1143 return IsLittleEndian
? Triple::mips64el
: Triple::mips64
;
1145 report_fatal_error("Invalid ELFCLASS!");
1147 case ELF::EM_MSP430
:
1148 return Triple::msp430
;
1152 return IsLittleEndian
? Triple::ppc64le
: Triple::ppc64
;
1154 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1155 case ELF::ELFCLASS32
:
1156 return Triple::riscv32
;
1157 case ELF::ELFCLASS64
:
1158 return Triple::riscv64
;
1160 report_fatal_error("Invalid ELFCLASS!");
1163 return Triple::systemz
;
1166 case ELF::EM_SPARC32PLUS
:
1167 return IsLittleEndian
? Triple::sparcel
: Triple::sparc
;
1168 case ELF::EM_SPARCV9
:
1169 return Triple::sparcv9
;
1171 case ELF::EM_AMDGPU
: {
1172 if (!IsLittleEndian
)
1173 return Triple::UnknownArch
;
1175 unsigned MACH
= EF
.getHeader()->e_flags
& ELF::EF_AMDGPU_MACH
;
1176 if (MACH
>= ELF::EF_AMDGPU_MACH_R600_FIRST
&&
1177 MACH
<= ELF::EF_AMDGPU_MACH_R600_LAST
)
1178 return Triple::r600
;
1179 if (MACH
>= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST
&&
1180 MACH
<= ELF::EF_AMDGPU_MACH_AMDGCN_LAST
)
1181 return Triple::amdgcn
;
1183 return Triple::UnknownArch
;
1187 return IsLittleEndian
? Triple::bpfel
: Triple::bpfeb
;
1190 return Triple::UnknownArch
;
1194 template <class ELFT
>
1195 Expected
<uint64_t> ELFObjectFile
<ELFT
>::getStartAddress() const {
1196 return EF
.getHeader()->e_entry
;
1199 template <class ELFT
>
1200 ELFObjectFileBase::elf_symbol_iterator_range
1201 ELFObjectFile
<ELFT
>::getDynamicSymbolIterators() const {
1202 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1205 template <class ELFT
> bool ELFObjectFile
<ELFT
>::isRelocatableObject() const {
1206 return EF
.getHeader()->e_type
== ELF::ET_REL
;
1209 } // end namespace object
1210 } // end namespace llvm
1212 #endif // LLVM_OBJECT_ELFOBJECTFILE_H