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
);
464 if (Name
&& !Name
->empty())
467 // If the symbol name is empty use the section name.
468 if (ESym
->getType() == ELF::STT_SECTION
) {
469 if (Expected
<section_iterator
> SecOrErr
= getSymbolSection(Sym
)) {
470 consumeError(Name
.takeError());
471 return (*SecOrErr
)->getName();
477 template <class ELFT
>
478 uint64_t ELFObjectFile
<ELFT
>::getSectionFlags(DataRefImpl Sec
) const {
479 return getSection(Sec
)->sh_flags
;
482 template <class ELFT
>
483 uint32_t ELFObjectFile
<ELFT
>::getSectionType(DataRefImpl Sec
) const {
484 return getSection(Sec
)->sh_type
;
487 template <class ELFT
>
488 uint64_t ELFObjectFile
<ELFT
>::getSectionOffset(DataRefImpl Sec
) const {
489 return getSection(Sec
)->sh_offset
;
492 template <class ELFT
>
493 uint64_t ELFObjectFile
<ELFT
>::getSymbolValueImpl(DataRefImpl Symb
) const {
494 const Elf_Sym
*ESym
= getSymbol(Symb
);
495 uint64_t Ret
= ESym
->st_value
;
496 if (ESym
->st_shndx
== ELF::SHN_ABS
)
499 const Elf_Ehdr
*Header
= EF
.getHeader();
500 // Clear the ARM/Thumb or microMIPS indicator flag.
501 if ((Header
->e_machine
== ELF::EM_ARM
|| Header
->e_machine
== ELF::EM_MIPS
) &&
502 ESym
->getType() == ELF::STT_FUNC
)
508 template <class ELFT
>
510 ELFObjectFile
<ELFT
>::getSymbolAddress(DataRefImpl Symb
) const {
511 uint64_t Result
= getSymbolValue(Symb
);
512 const Elf_Sym
*ESym
= getSymbol(Symb
);
513 switch (ESym
->st_shndx
) {
514 case ELF::SHN_COMMON
:
520 const Elf_Ehdr
*Header
= EF
.getHeader();
521 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
523 return SymTabOrErr
.takeError();
524 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
526 if (Header
->e_type
== ELF::ET_REL
) {
527 auto SectionOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
529 return SectionOrErr
.takeError();
530 const Elf_Shdr
*Section
= *SectionOrErr
;
532 Result
+= Section
->sh_addr
;
538 template <class ELFT
>
539 uint32_t ELFObjectFile
<ELFT
>::getSymbolAlignment(DataRefImpl Symb
) const {
540 const Elf_Sym
*Sym
= getSymbol(Symb
);
541 if (Sym
->st_shndx
== ELF::SHN_COMMON
)
542 return Sym
->st_value
;
546 template <class ELFT
>
547 uint16_t ELFObjectFile
<ELFT
>::getEMachine() const {
548 return EF
.getHeader()->e_machine
;
551 template <class ELFT
> uint16_t ELFObjectFile
<ELFT
>::getEType() const {
552 return EF
.getHeader()->e_type
;
555 template <class ELFT
>
556 uint64_t ELFObjectFile
<ELFT
>::getSymbolSize(DataRefImpl Sym
) const {
557 return getSymbol(Sym
)->st_size
;
560 template <class ELFT
>
561 uint64_t ELFObjectFile
<ELFT
>::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
562 return getSymbol(Symb
)->st_size
;
565 template <class ELFT
>
566 uint8_t ELFObjectFile
<ELFT
>::getSymbolBinding(DataRefImpl Symb
) const {
567 return getSymbol(Symb
)->getBinding();
570 template <class ELFT
>
571 uint8_t ELFObjectFile
<ELFT
>::getSymbolOther(DataRefImpl Symb
) const {
572 return getSymbol(Symb
)->st_other
;
575 template <class ELFT
>
576 uint8_t ELFObjectFile
<ELFT
>::getSymbolELFType(DataRefImpl Symb
) const {
577 return getSymbol(Symb
)->getType();
580 template <class ELFT
>
581 Expected
<SymbolRef::Type
>
582 ELFObjectFile
<ELFT
>::getSymbolType(DataRefImpl Symb
) const {
583 const Elf_Sym
*ESym
= getSymbol(Symb
);
585 switch (ESym
->getType()) {
586 case ELF::STT_NOTYPE
:
587 return SymbolRef::ST_Unknown
;
588 case ELF::STT_SECTION
:
589 return SymbolRef::ST_Debug
;
591 return SymbolRef::ST_File
;
593 return SymbolRef::ST_Function
;
594 case ELF::STT_OBJECT
:
595 case ELF::STT_COMMON
:
597 return SymbolRef::ST_Data
;
599 return SymbolRef::ST_Other
;
603 template <class ELFT
>
604 uint32_t ELFObjectFile
<ELFT
>::getSymbolFlags(DataRefImpl Sym
) const {
605 const Elf_Sym
*ESym
= getSymbol(Sym
);
607 uint32_t Result
= SymbolRef::SF_None
;
609 if (ESym
->getBinding() != ELF::STB_LOCAL
)
610 Result
|= SymbolRef::SF_Global
;
612 if (ESym
->getBinding() == ELF::STB_WEAK
)
613 Result
|= SymbolRef::SF_Weak
;
615 if (ESym
->st_shndx
== ELF::SHN_ABS
)
616 Result
|= SymbolRef::SF_Absolute
;
618 if (ESym
->getType() == ELF::STT_FILE
|| ESym
->getType() == ELF::STT_SECTION
)
619 Result
|= SymbolRef::SF_FormatSpecific
;
621 auto DotSymtabSecSyms
= EF
.symbols(DotSymtabSec
);
622 if (DotSymtabSecSyms
&& ESym
== (*DotSymtabSecSyms
).begin())
623 Result
|= SymbolRef::SF_FormatSpecific
;
624 auto DotDynSymSecSyms
= EF
.symbols(DotDynSymSec
);
625 if (DotDynSymSecSyms
&& ESym
== (*DotDynSymSecSyms
).begin())
626 Result
|= SymbolRef::SF_FormatSpecific
;
628 if (EF
.getHeader()->e_machine
== ELF::EM_ARM
) {
629 if (Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
)) {
630 StringRef Name
= *NameOrErr
;
631 if (Name
.startswith("$d") || Name
.startswith("$t") ||
632 Name
.startswith("$a"))
633 Result
|= SymbolRef::SF_FormatSpecific
;
635 // TODO: Actually report errors helpfully.
636 consumeError(NameOrErr
.takeError());
638 if (ESym
->getType() == ELF::STT_FUNC
&& (ESym
->st_value
& 1) == 1)
639 Result
|= SymbolRef::SF_Thumb
;
642 if (ESym
->st_shndx
== ELF::SHN_UNDEF
)
643 Result
|= SymbolRef::SF_Undefined
;
645 if (ESym
->getType() == ELF::STT_COMMON
|| ESym
->st_shndx
== ELF::SHN_COMMON
)
646 Result
|= SymbolRef::SF_Common
;
648 if (isExportedToOtherDSO(ESym
))
649 Result
|= SymbolRef::SF_Exported
;
651 if (ESym
->getVisibility() == ELF::STV_HIDDEN
)
652 Result
|= SymbolRef::SF_Hidden
;
657 template <class ELFT
>
658 Expected
<section_iterator
>
659 ELFObjectFile
<ELFT
>::getSymbolSection(const Elf_Sym
*ESym
,
660 const Elf_Shdr
*SymTab
) const {
661 auto ESecOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
663 return ESecOrErr
.takeError();
665 const Elf_Shdr
*ESec
= *ESecOrErr
;
667 return section_end();
670 Sec
.p
= reinterpret_cast<intptr_t>(ESec
);
671 return section_iterator(SectionRef(Sec
, this));
674 template <class ELFT
>
675 Expected
<section_iterator
>
676 ELFObjectFile
<ELFT
>::getSymbolSection(DataRefImpl Symb
) const {
677 const Elf_Sym
*Sym
= getSymbol(Symb
);
678 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
680 return SymTabOrErr
.takeError();
681 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
682 return getSymbolSection(Sym
, SymTab
);
685 template <class ELFT
>
686 void ELFObjectFile
<ELFT
>::moveSectionNext(DataRefImpl
&Sec
) const {
687 const Elf_Shdr
*ESec
= getSection(Sec
);
691 template <class ELFT
>
692 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSectionName(DataRefImpl Sec
) const {
693 return EF
.getSectionName(&*getSection(Sec
));
696 template <class ELFT
>
697 uint64_t ELFObjectFile
<ELFT
>::getSectionAddress(DataRefImpl Sec
) const {
698 return getSection(Sec
)->sh_addr
;
701 template <class ELFT
>
702 uint64_t ELFObjectFile
<ELFT
>::getSectionIndex(DataRefImpl Sec
) const {
703 auto SectionsOrErr
= EF
.sections();
704 handleAllErrors(std::move(SectionsOrErr
.takeError()),
705 [](const ErrorInfoBase
&) {
706 llvm_unreachable("unable to get section index");
708 const Elf_Shdr
*First
= SectionsOrErr
->begin();
709 return getSection(Sec
) - First
;
712 template <class ELFT
>
713 uint64_t ELFObjectFile
<ELFT
>::getSectionSize(DataRefImpl Sec
) const {
714 return getSection(Sec
)->sh_size
;
717 template <class ELFT
>
718 Expected
<ArrayRef
<uint8_t>>
719 ELFObjectFile
<ELFT
>::getSectionContents(DataRefImpl Sec
) const {
720 const Elf_Shdr
*EShdr
= getSection(Sec
);
721 if (std::error_code EC
=
722 checkOffset(getMemoryBufferRef(),
723 (uintptr_t)base() + EShdr
->sh_offset
, EShdr
->sh_size
))
724 return errorCodeToError(EC
);
725 return makeArrayRef((const uint8_t *)base() + EShdr
->sh_offset
,
729 template <class ELFT
>
730 uint64_t ELFObjectFile
<ELFT
>::getSectionAlignment(DataRefImpl Sec
) const {
731 return getSection(Sec
)->sh_addralign
;
734 template <class ELFT
>
735 bool ELFObjectFile
<ELFT
>::isSectionCompressed(DataRefImpl Sec
) const {
736 return getSection(Sec
)->sh_flags
& ELF::SHF_COMPRESSED
;
739 template <class ELFT
>
740 bool ELFObjectFile
<ELFT
>::isSectionText(DataRefImpl Sec
) const {
741 return getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
;
744 template <class ELFT
>
745 bool ELFObjectFile
<ELFT
>::isSectionData(DataRefImpl Sec
) const {
746 const Elf_Shdr
*EShdr
= getSection(Sec
);
747 return EShdr
->sh_type
== ELF::SHT_PROGBITS
&&
748 EShdr
->sh_flags
& ELF::SHF_ALLOC
&&
749 !(EShdr
->sh_flags
& ELF::SHF_EXECINSTR
);
752 template <class ELFT
>
753 bool ELFObjectFile
<ELFT
>::isSectionBSS(DataRefImpl Sec
) const {
754 const Elf_Shdr
*EShdr
= getSection(Sec
);
755 return EShdr
->sh_flags
& (ELF::SHF_ALLOC
| ELF::SHF_WRITE
) &&
756 EShdr
->sh_type
== ELF::SHT_NOBITS
;
759 template <class ELFT
>
760 std::vector
<SectionRef
>
761 ELFObjectFile
<ELFT
>::dynamic_relocation_sections() const {
762 std::vector
<SectionRef
> Res
;
763 std::vector
<uintptr_t> Offsets
;
765 auto SectionsOrErr
= EF
.sections();
769 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
770 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
773 reinterpret_cast<Elf_Dyn
*>((uintptr_t)base() + Sec
.sh_offset
);
774 for (; Dynamic
->d_tag
!= ELF::DT_NULL
; Dynamic
++) {
775 if (Dynamic
->d_tag
== ELF::DT_REL
|| Dynamic
->d_tag
== ELF::DT_RELA
||
776 Dynamic
->d_tag
== ELF::DT_JMPREL
) {
777 Offsets
.push_back(Dynamic
->d_un
.d_val
);
781 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
782 if (is_contained(Offsets
, Sec
.sh_addr
))
783 Res
.emplace_back(toDRI(&Sec
), this);
788 template <class ELFT
>
789 bool ELFObjectFile
<ELFT
>::isSectionVirtual(DataRefImpl Sec
) const {
790 return getSection(Sec
)->sh_type
== ELF::SHT_NOBITS
;
793 template <class ELFT
>
794 bool ELFObjectFile
<ELFT
>::isBerkeleyText(DataRefImpl Sec
) const {
795 return getSection(Sec
)->sh_flags
& ELF::SHF_ALLOC
&&
796 (getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
||
797 !(getSection(Sec
)->sh_flags
& ELF::SHF_WRITE
));
800 template <class ELFT
>
801 bool ELFObjectFile
<ELFT
>::isBerkeleyData(DataRefImpl Sec
) const {
802 const Elf_Shdr
*EShdr
= getSection(Sec
);
803 return !isBerkeleyText(Sec
) && EShdr
->sh_type
!= ELF::SHT_NOBITS
&&
804 EShdr
->sh_flags
& ELF::SHF_ALLOC
;
807 template <class ELFT
>
809 ELFObjectFile
<ELFT
>::section_rel_begin(DataRefImpl Sec
) const {
811 auto SectionsOrErr
= EF
.sections();
813 return relocation_iterator(RelocationRef());
814 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
815 RelData
.d
.a
= (Sec
.p
- SHT
) / EF
.getHeader()->e_shentsize
;
817 return relocation_iterator(RelocationRef(RelData
, this));
820 template <class ELFT
>
822 ELFObjectFile
<ELFT
>::section_rel_end(DataRefImpl Sec
) const {
823 const Elf_Shdr
*S
= reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
824 relocation_iterator Begin
= section_rel_begin(Sec
);
825 if (S
->sh_type
!= ELF::SHT_RELA
&& S
->sh_type
!= ELF::SHT_REL
)
827 DataRefImpl RelData
= Begin
->getRawDataRefImpl();
828 const Elf_Shdr
*RelSec
= getRelSection(RelData
);
830 // Error check sh_link here so that getRelocationSymbol can just use it.
831 auto SymSecOrErr
= EF
.getSection(RelSec
->sh_link
);
833 report_fatal_error(errorToErrorCode(SymSecOrErr
.takeError()).message());
835 RelData
.d
.b
+= S
->sh_size
/ S
->sh_entsize
;
836 return relocation_iterator(RelocationRef(RelData
, this));
839 template <class ELFT
>
841 ELFObjectFile
<ELFT
>::getRelocatedSection(DataRefImpl Sec
) const {
842 if (EF
.getHeader()->e_type
!= ELF::ET_REL
)
843 return section_end();
845 const Elf_Shdr
*EShdr
= getSection(Sec
);
846 uintX_t Type
= EShdr
->sh_type
;
847 if (Type
!= ELF::SHT_REL
&& Type
!= ELF::SHT_RELA
)
848 return section_end();
850 auto R
= EF
.getSection(EShdr
->sh_info
);
852 report_fatal_error(errorToErrorCode(R
.takeError()).message());
853 return section_iterator(SectionRef(toDRI(*R
), this));
857 template <class ELFT
>
858 void ELFObjectFile
<ELFT
>::moveRelocationNext(DataRefImpl
&Rel
) const {
862 template <class ELFT
>
864 ELFObjectFile
<ELFT
>::getRelocationSymbol(DataRefImpl Rel
) const {
866 const Elf_Shdr
*sec
= getRelSection(Rel
);
867 if (sec
->sh_type
== ELF::SHT_REL
)
868 symbolIdx
= getRel(Rel
)->getSymbol(EF
.isMips64EL());
870 symbolIdx
= getRela(Rel
)->getSymbol(EF
.isMips64EL());
874 // FIXME: error check symbolIdx
875 DataRefImpl SymbolData
;
876 SymbolData
.d
.a
= sec
->sh_link
;
877 SymbolData
.d
.b
= symbolIdx
;
878 return symbol_iterator(SymbolRef(SymbolData
, this));
881 template <class ELFT
>
882 uint64_t ELFObjectFile
<ELFT
>::getRelocationOffset(DataRefImpl Rel
) const {
883 const Elf_Shdr
*sec
= getRelSection(Rel
);
884 if (sec
->sh_type
== ELF::SHT_REL
)
885 return getRel(Rel
)->r_offset
;
887 return getRela(Rel
)->r_offset
;
890 template <class ELFT
>
891 uint64_t ELFObjectFile
<ELFT
>::getRelocationType(DataRefImpl Rel
) const {
892 const Elf_Shdr
*sec
= getRelSection(Rel
);
893 if (sec
->sh_type
== ELF::SHT_REL
)
894 return getRel(Rel
)->getType(EF
.isMips64EL());
896 return getRela(Rel
)->getType(EF
.isMips64EL());
899 template <class ELFT
>
900 StringRef ELFObjectFile
<ELFT
>::getRelocationTypeName(uint32_t Type
) const {
901 return getELFRelocationTypeName(EF
.getHeader()->e_machine
, Type
);
904 template <class ELFT
>
905 void ELFObjectFile
<ELFT
>::getRelocationTypeName(
906 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
907 uint32_t type
= getRelocationType(Rel
);
908 EF
.getRelocationTypeName(type
, Result
);
911 template <class ELFT
>
913 ELFObjectFile
<ELFT
>::getRelocationAddend(DataRefImpl Rel
) const {
914 if (getRelSection(Rel
)->sh_type
!= ELF::SHT_RELA
)
915 return createError("Section is not SHT_RELA");
916 return (int64_t)getRela(Rel
)->r_addend
;
919 template <class ELFT
>
920 const typename ELFObjectFile
<ELFT
>::Elf_Rel
*
921 ELFObjectFile
<ELFT
>::getRel(DataRefImpl Rel
) const {
922 assert(getRelSection(Rel
)->sh_type
== ELF::SHT_REL
);
923 auto Ret
= EF
.template getEntry
<Elf_Rel
>(Rel
.d
.a
, Rel
.d
.b
);
925 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
929 template <class ELFT
>
930 const typename ELFObjectFile
<ELFT
>::Elf_Rela
*
931 ELFObjectFile
<ELFT
>::getRela(DataRefImpl Rela
) const {
932 assert(getRelSection(Rela
)->sh_type
== ELF::SHT_RELA
);
933 auto Ret
= EF
.template getEntry
<Elf_Rela
>(Rela
.d
.a
, Rela
.d
.b
);
935 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
939 template <class ELFT
>
940 Expected
<ELFObjectFile
<ELFT
>>
941 ELFObjectFile
<ELFT
>::create(MemoryBufferRef Object
) {
942 auto EFOrErr
= ELFFile
<ELFT
>::create(Object
.getBuffer());
943 if (Error E
= EFOrErr
.takeError())
945 auto EF
= std::move(*EFOrErr
);
947 auto SectionsOrErr
= EF
.sections();
949 return SectionsOrErr
.takeError();
951 const Elf_Shdr
*DotDynSymSec
= nullptr;
952 const Elf_Shdr
*DotSymtabSec
= nullptr;
953 ArrayRef
<Elf_Word
> ShndxTable
;
954 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
955 switch (Sec
.sh_type
) {
956 case ELF::SHT_DYNSYM
: {
961 case ELF::SHT_SYMTAB
: {
966 case ELF::SHT_SYMTAB_SHNDX
: {
967 auto TableOrErr
= EF
.getSHNDXTable(Sec
);
969 return TableOrErr
.takeError();
970 ShndxTable
= *TableOrErr
;
975 return ELFObjectFile
<ELFT
>(Object
, EF
, DotDynSymSec
, DotSymtabSec
,
979 template <class ELFT
>
980 ELFObjectFile
<ELFT
>::ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
981 const Elf_Shdr
*DotDynSymSec
,
982 const Elf_Shdr
*DotSymtabSec
,
983 ArrayRef
<Elf_Word
> ShndxTable
)
985 getELFType(ELFT::TargetEndianness
== support::little
, ELFT::Is64Bits
),
987 EF(EF
), DotDynSymSec(DotDynSymSec
), DotSymtabSec(DotSymtabSec
),
988 ShndxTable(ShndxTable
) {}
990 template <class ELFT
>
991 ELFObjectFile
<ELFT
>::ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
)
992 : ELFObjectFile(Other
.Data
, Other
.EF
, Other
.DotDynSymSec
,
993 Other
.DotSymtabSec
, Other
.ShndxTable
) {}
995 template <class ELFT
>
996 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_begin() const {
999 DotSymtabSec
&& DotSymtabSec
->sh_size
>= sizeof(Elf_Sym
) ? 1 : 0);
1000 return basic_symbol_iterator(SymbolRef(Sym
, this));
1003 template <class ELFT
>
1004 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_end() const {
1005 const Elf_Shdr
*SymTab
= DotSymtabSec
;
1007 return symbol_begin();
1008 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1009 return basic_symbol_iterator(SymbolRef(Sym
, this));
1012 template <class ELFT
>
1013 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_begin() const {
1014 DataRefImpl Sym
= toDRI(DotDynSymSec
, 0);
1015 return symbol_iterator(SymbolRef(Sym
, this));
1018 template <class ELFT
>
1019 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_end() const {
1020 const Elf_Shdr
*SymTab
= DotDynSymSec
;
1022 return dynamic_symbol_begin();
1023 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1024 return basic_symbol_iterator(SymbolRef(Sym
, this));
1027 template <class ELFT
>
1028 section_iterator ELFObjectFile
<ELFT
>::section_begin() const {
1029 auto SectionsOrErr
= EF
.sections();
1031 return section_iterator(SectionRef());
1032 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).begin()), this));
1035 template <class ELFT
>
1036 section_iterator ELFObjectFile
<ELFT
>::section_end() const {
1037 auto SectionsOrErr
= EF
.sections();
1039 return section_iterator(SectionRef());
1040 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).end()), this));
1043 template <class ELFT
>
1044 uint8_t ELFObjectFile
<ELFT
>::getBytesInAddress() const {
1045 return ELFT::Is64Bits
? 8 : 4;
1048 template <class ELFT
>
1049 StringRef ELFObjectFile
<ELFT
>::getFileFormatName() const {
1050 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1051 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1052 case ELF::ELFCLASS32
:
1053 switch (EF
.getHeader()->e_machine
) {
1055 return "ELF32-i386";
1057 return "ELF32-iamcu";
1058 case ELF::EM_X86_64
:
1059 return "ELF32-x86-64";
1061 return (IsLittleEndian
? "ELF32-arm-little" : "ELF32-arm-big");
1064 case ELF::EM_HEXAGON
:
1065 return "ELF32-hexagon";
1067 return "ELF32-lanai";
1069 return "ELF32-mips";
1070 case ELF::EM_MSP430
:
1071 return "ELF32-msp430";
1075 return "ELF32-riscv";
1077 case ELF::EM_SPARC32PLUS
:
1078 return "ELF32-sparc";
1079 case ELF::EM_AMDGPU
:
1080 return "ELF32-amdgpu";
1082 return "ELF32-unknown";
1084 case ELF::ELFCLASS64
:
1085 switch (EF
.getHeader()->e_machine
) {
1087 return "ELF64-i386";
1088 case ELF::EM_X86_64
:
1089 return "ELF64-x86-64";
1090 case ELF::EM_AARCH64
:
1091 return (IsLittleEndian
? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1093 return "ELF64-ppc64";
1095 return "ELF64-riscv";
1097 return "ELF64-s390";
1098 case ELF::EM_SPARCV9
:
1099 return "ELF64-sparc";
1101 return "ELF64-mips";
1102 case ELF::EM_AMDGPU
:
1103 return "ELF64-amdgpu";
1107 return "ELF64-unknown";
1110 // FIXME: Proper error handling.
1111 report_fatal_error("Invalid ELFCLASS!");
1115 template <class ELFT
> Triple::ArchType ELFObjectFile
<ELFT
>::getArch() const {
1116 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1117 switch (EF
.getHeader()->e_machine
) {
1121 case ELF::EM_X86_64
:
1122 return Triple::x86_64
;
1123 case ELF::EM_AARCH64
:
1124 return IsLittleEndian
? Triple::aarch64
: Triple::aarch64_be
;
1129 case ELF::EM_HEXAGON
:
1130 return Triple::hexagon
;
1132 return Triple::lanai
;
1134 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1135 case ELF::ELFCLASS32
:
1136 return IsLittleEndian
? Triple::mipsel
: Triple::mips
;
1137 case ELF::ELFCLASS64
:
1138 return IsLittleEndian
? Triple::mips64el
: Triple::mips64
;
1140 report_fatal_error("Invalid ELFCLASS!");
1142 case ELF::EM_MSP430
:
1143 return Triple::msp430
;
1147 return IsLittleEndian
? Triple::ppc64le
: Triple::ppc64
;
1149 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1150 case ELF::ELFCLASS32
:
1151 return Triple::riscv32
;
1152 case ELF::ELFCLASS64
:
1153 return Triple::riscv64
;
1155 report_fatal_error("Invalid ELFCLASS!");
1158 return Triple::systemz
;
1161 case ELF::EM_SPARC32PLUS
:
1162 return IsLittleEndian
? Triple::sparcel
: Triple::sparc
;
1163 case ELF::EM_SPARCV9
:
1164 return Triple::sparcv9
;
1166 case ELF::EM_AMDGPU
: {
1167 if (!IsLittleEndian
)
1168 return Triple::UnknownArch
;
1170 unsigned MACH
= EF
.getHeader()->e_flags
& ELF::EF_AMDGPU_MACH
;
1171 if (MACH
>= ELF::EF_AMDGPU_MACH_R600_FIRST
&&
1172 MACH
<= ELF::EF_AMDGPU_MACH_R600_LAST
)
1173 return Triple::r600
;
1174 if (MACH
>= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST
&&
1175 MACH
<= ELF::EF_AMDGPU_MACH_AMDGCN_LAST
)
1176 return Triple::amdgcn
;
1178 return Triple::UnknownArch
;
1182 return IsLittleEndian
? Triple::bpfel
: Triple::bpfeb
;
1185 return Triple::UnknownArch
;
1189 template <class ELFT
>
1190 Expected
<uint64_t> ELFObjectFile
<ELFT
>::getStartAddress() const {
1191 return EF
.getHeader()->e_entry
;
1194 template <class ELFT
>
1195 ELFObjectFileBase::elf_symbol_iterator_range
1196 ELFObjectFile
<ELFT
>::getDynamicSymbolIterators() const {
1197 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1200 template <class ELFT
> bool ELFObjectFile
<ELFT
>::isRelocatableObject() const {
1201 return EF
.getHeader()->e_type
== ELF::ET_REL
;
1204 } // end namespace object
1205 } // end namespace llvm
1207 #endif // LLVM_OBJECT_ELFOBJECTFILE_H