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 class elf_symbol_iterator
;
46 class ELFObjectFileBase
: public ObjectFile
{
47 friend class ELFRelocationRef
;
48 friend class ELFSectionRef
;
49 friend class ELFSymbolRef
;
52 ELFObjectFileBase(unsigned int Type
, MemoryBufferRef Source
);
54 virtual uint16_t getEMachine() const = 0;
55 virtual uint64_t getSymbolSize(DataRefImpl Symb
) const = 0;
56 virtual uint8_t getSymbolOther(DataRefImpl Symb
) const = 0;
57 virtual uint8_t getSymbolELFType(DataRefImpl Symb
) const = 0;
59 virtual uint32_t getSectionType(DataRefImpl Sec
) const = 0;
60 virtual uint64_t getSectionFlags(DataRefImpl Sec
) const = 0;
61 virtual uint64_t getSectionOffset(DataRefImpl Sec
) const = 0;
63 virtual Expected
<int64_t> getRelocationAddend(DataRefImpl Rel
) const = 0;
66 using elf_symbol_iterator_range
= iterator_range
<elf_symbol_iterator
>;
68 virtual elf_symbol_iterator_range
getDynamicSymbolIterators() const = 0;
70 /// Returns platform-specific object flags, if any.
71 virtual unsigned getPlatformFlags() const = 0;
73 elf_symbol_iterator_range
symbols() const;
75 static bool classof(const Binary
*v
) { return v
->isELF(); }
77 SubtargetFeatures
getFeatures() const override
;
79 SubtargetFeatures
getMIPSFeatures() const;
81 SubtargetFeatures
getARMFeatures() const;
83 SubtargetFeatures
getRISCVFeatures() const;
85 void setARMSubArch(Triple
&TheTriple
) const override
;
87 virtual uint16_t getEType() const = 0;
89 std::vector
<std::pair
<DataRefImpl
, uint64_t>> getPltAddresses() const;
92 class ELFSectionRef
: public SectionRef
{
94 ELFSectionRef(const SectionRef
&B
) : SectionRef(B
) {
95 assert(isa
<ELFObjectFileBase
>(SectionRef::getObject()));
98 const ELFObjectFileBase
*getObject() const {
99 return cast
<ELFObjectFileBase
>(SectionRef::getObject());
102 uint32_t getType() const {
103 return getObject()->getSectionType(getRawDataRefImpl());
106 uint64_t getFlags() const {
107 return getObject()->getSectionFlags(getRawDataRefImpl());
110 uint64_t getOffset() const {
111 return getObject()->getSectionOffset(getRawDataRefImpl());
115 class elf_section_iterator
: public section_iterator
{
117 elf_section_iterator(const section_iterator
&B
) : section_iterator(B
) {
118 assert(isa
<ELFObjectFileBase
>(B
->getObject()));
121 const ELFSectionRef
*operator->() const {
122 return static_cast<const ELFSectionRef
*>(section_iterator::operator->());
125 const ELFSectionRef
&operator*() const {
126 return static_cast<const ELFSectionRef
&>(section_iterator::operator*());
130 class ELFSymbolRef
: public SymbolRef
{
132 ELFSymbolRef(const SymbolRef
&B
) : SymbolRef(B
) {
133 assert(isa
<ELFObjectFileBase
>(SymbolRef::getObject()));
136 const ELFObjectFileBase
*getObject() const {
137 return cast
<ELFObjectFileBase
>(BasicSymbolRef::getObject());
140 uint64_t getSize() const {
141 return getObject()->getSymbolSize(getRawDataRefImpl());
144 uint8_t getOther() const {
145 return getObject()->getSymbolOther(getRawDataRefImpl());
148 uint8_t getELFType() const {
149 return getObject()->getSymbolELFType(getRawDataRefImpl());
153 class elf_symbol_iterator
: public symbol_iterator
{
155 elf_symbol_iterator(const basic_symbol_iterator
&B
)
156 : symbol_iterator(SymbolRef(B
->getRawDataRefImpl(),
157 cast
<ELFObjectFileBase
>(B
->getObject()))) {}
159 const ELFSymbolRef
*operator->() const {
160 return static_cast<const ELFSymbolRef
*>(symbol_iterator::operator->());
163 const ELFSymbolRef
&operator*() const {
164 return static_cast<const ELFSymbolRef
&>(symbol_iterator::operator*());
168 class ELFRelocationRef
: public RelocationRef
{
170 ELFRelocationRef(const RelocationRef
&B
) : RelocationRef(B
) {
171 assert(isa
<ELFObjectFileBase
>(RelocationRef::getObject()));
174 const ELFObjectFileBase
*getObject() const {
175 return cast
<ELFObjectFileBase
>(RelocationRef::getObject());
178 Expected
<int64_t> getAddend() const {
179 return getObject()->getRelocationAddend(getRawDataRefImpl());
183 class elf_relocation_iterator
: public relocation_iterator
{
185 elf_relocation_iterator(const relocation_iterator
&B
)
186 : relocation_iterator(RelocationRef(
187 B
->getRawDataRefImpl(), cast
<ELFObjectFileBase
>(B
->getObject()))) {}
189 const ELFRelocationRef
*operator->() const {
190 return static_cast<const ELFRelocationRef
*>(
191 relocation_iterator::operator->());
194 const ELFRelocationRef
&operator*() const {
195 return static_cast<const ELFRelocationRef
&>(
196 relocation_iterator::operator*());
200 inline ELFObjectFileBase::elf_symbol_iterator_range
201 ELFObjectFileBase::symbols() const {
202 return elf_symbol_iterator_range(symbol_begin(), symbol_end());
205 template <class ELFT
> class ELFObjectFile
: public ELFObjectFileBase
{
206 uint16_t getEMachine() const override
;
207 uint16_t getEType() const override
;
208 uint64_t getSymbolSize(DataRefImpl Sym
) const override
;
211 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
213 using uintX_t
= typename
ELFT::uint
;
215 using Elf_Sym
= typename
ELFT::Sym
;
216 using Elf_Shdr
= typename
ELFT::Shdr
;
217 using Elf_Ehdr
= typename
ELFT::Ehdr
;
218 using Elf_Rel
= typename
ELFT::Rel
;
219 using Elf_Rela
= typename
ELFT::Rela
;
220 using Elf_Dyn
= typename
ELFT::Dyn
;
223 ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
224 const Elf_Shdr
*DotDynSymSec
, const Elf_Shdr
*DotSymtabSec
,
225 ArrayRef
<Elf_Word
> ShndxTable
);
230 const Elf_Shdr
*DotDynSymSec
= nullptr; // Dynamic symbol table section.
231 const Elf_Shdr
*DotSymtabSec
= nullptr; // Symbol table section.
232 ArrayRef
<Elf_Word
> ShndxTable
;
234 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
235 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
236 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
237 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
238 uint32_t getSymbolAlignment(DataRefImpl Symb
) const override
;
239 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
240 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
241 uint8_t getSymbolOther(DataRefImpl Symb
) const override
;
242 uint8_t getSymbolELFType(DataRefImpl Symb
) const override
;
243 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
244 Expected
<section_iterator
> getSymbolSection(const Elf_Sym
*Symb
,
245 const Elf_Shdr
*SymTab
) const;
246 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
248 void moveSectionNext(DataRefImpl
&Sec
) const override
;
249 std::error_code
getSectionName(DataRefImpl Sec
,
250 StringRef
&Res
) const override
;
251 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
252 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
253 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
254 std::error_code
getSectionContents(DataRefImpl Sec
,
255 StringRef
&Res
) const override
;
256 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
257 bool isSectionCompressed(DataRefImpl Sec
) const override
;
258 bool isSectionText(DataRefImpl Sec
) const override
;
259 bool isSectionData(DataRefImpl Sec
) const override
;
260 bool isSectionBSS(DataRefImpl Sec
) const override
;
261 bool isSectionVirtual(DataRefImpl Sec
) const override
;
262 bool isBerkeleyText(DataRefImpl Sec
) const override
;
263 bool isBerkeleyData(DataRefImpl Sec
) const override
;
264 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
265 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
266 std::vector
<SectionRef
> dynamic_relocation_sections() const override
;
267 section_iterator
getRelocatedSection(DataRefImpl Sec
) const override
;
269 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
270 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
271 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
272 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
273 void getRelocationTypeName(DataRefImpl Rel
,
274 SmallVectorImpl
<char> &Result
) const override
;
276 uint32_t getSectionType(DataRefImpl Sec
) const override
;
277 uint64_t getSectionFlags(DataRefImpl Sec
) const override
;
278 uint64_t getSectionOffset(DataRefImpl Sec
) const override
;
279 StringRef
getRelocationTypeName(uint32_t Type
) const;
281 /// Get the relocation section that contains \a Rel.
282 const Elf_Shdr
*getRelSection(DataRefImpl Rel
) const {
283 auto RelSecOrErr
= EF
.getSection(Rel
.d
.a
);
285 report_fatal_error(errorToErrorCode(RelSecOrErr
.takeError()).message());
289 DataRefImpl
toDRI(const Elf_Shdr
*SymTable
, unsigned SymbolNum
) const {
296 assert(SymTable
->sh_type
== ELF::SHT_SYMTAB
||
297 SymTable
->sh_type
== ELF::SHT_DYNSYM
);
299 auto SectionsOrErr
= EF
.sections();
300 if (!SectionsOrErr
) {
305 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
306 unsigned SymTableIndex
=
307 (reinterpret_cast<uintptr_t>(SymTable
) - SHT
) / sizeof(Elf_Shdr
);
309 DRI
.d
.a
= SymTableIndex
;
314 const Elf_Shdr
*toELFShdrIter(DataRefImpl Sec
) const {
315 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
318 DataRefImpl
toDRI(const Elf_Shdr
*Sec
) const {
320 DRI
.p
= reinterpret_cast<uintptr_t>(Sec
);
324 DataRefImpl
toDRI(const Elf_Dyn
*Dyn
) const {
326 DRI
.p
= reinterpret_cast<uintptr_t>(Dyn
);
330 bool isExportedToOtherDSO(const Elf_Sym
*ESym
) const {
331 unsigned char Binding
= ESym
->getBinding();
332 unsigned char Visibility
= ESym
->getVisibility();
334 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
335 // visibility is either DEFAULT or PROTECTED. All other symbols are not
338 (Binding
== ELF::STB_GLOBAL
|| Binding
== ELF::STB_WEAK
||
339 Binding
== ELF::STB_GNU_UNIQUE
) &&
340 (Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_PROTECTED
));
343 // This flag is used for classof, to distinguish ELFObjectFile from
344 // its subclass. If more subclasses will be created, this flag will
345 // have to become an enum.
346 bool isDyldELFObject
;
349 ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
);
350 static Expected
<ELFObjectFile
<ELFT
>> create(MemoryBufferRef Object
);
352 const Elf_Rel
*getRel(DataRefImpl Rel
) const;
353 const Elf_Rela
*getRela(DataRefImpl Rela
) const;
355 const Elf_Sym
*getSymbol(DataRefImpl Sym
) const {
356 auto Ret
= EF
.template getEntry
<Elf_Sym
>(Sym
.d
.a
, Sym
.d
.b
);
358 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
362 const Elf_Shdr
*getSection(DataRefImpl Sec
) const {
363 return reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
366 basic_symbol_iterator
symbol_begin() const override
;
367 basic_symbol_iterator
symbol_end() const override
;
369 elf_symbol_iterator
dynamic_symbol_begin() const;
370 elf_symbol_iterator
dynamic_symbol_end() const;
372 section_iterator
section_begin() const override
;
373 section_iterator
section_end() const override
;
375 Expected
<int64_t> getRelocationAddend(DataRefImpl Rel
) const override
;
377 uint8_t getBytesInAddress() const override
;
378 StringRef
getFileFormatName() const override
;
379 Triple::ArchType
getArch() const override
;
380 Expected
<uint64_t> getStartAddress() const override
;
382 unsigned getPlatformFlags() const override
{ return EF
.getHeader()->e_flags
; }
384 std::error_code
getBuildAttributes(ARMAttributeParser
&Attributes
) const override
{
385 auto SectionsOrErr
= EF
.sections();
387 return errorToErrorCode(SectionsOrErr
.takeError());
389 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
390 if (Sec
.sh_type
== ELF::SHT_ARM_ATTRIBUTES
) {
391 auto ErrorOrContents
= EF
.getSectionContents(&Sec
);
392 if (!ErrorOrContents
)
393 return errorToErrorCode(ErrorOrContents
.takeError());
395 auto Contents
= ErrorOrContents
.get();
396 if (Contents
[0] != ARMBuildAttrs::Format_Version
|| Contents
.size() == 1)
397 return std::error_code();
399 Attributes
.Parse(Contents
, ELFT::TargetEndianness
== support::little
);
403 return std::error_code();
406 const ELFFile
<ELFT
> *getELFFile() const { return &EF
; }
408 bool isDyldType() const { return isDyldELFObject
; }
409 static bool classof(const Binary
*v
) {
410 return v
->getType() == getELFType(ELFT::TargetEndianness
== support::little
,
414 elf_symbol_iterator_range
getDynamicSymbolIterators() const override
;
416 bool isRelocatableObject() const override
;
419 using ELF32LEObjectFile
= ELFObjectFile
<ELF32LE
>;
420 using ELF64LEObjectFile
= ELFObjectFile
<ELF64LE
>;
421 using ELF32BEObjectFile
= ELFObjectFile
<ELF32BE
>;
422 using ELF64BEObjectFile
= ELFObjectFile
<ELF64BE
>;
424 template <class ELFT
>
425 void ELFObjectFile
<ELFT
>::moveSymbolNext(DataRefImpl
&Sym
) const {
429 template <class ELFT
>
430 Expected
<StringRef
> ELFObjectFile
<ELFT
>::getSymbolName(DataRefImpl Sym
) const {
431 const Elf_Sym
*ESym
= getSymbol(Sym
);
432 auto SymTabOrErr
= EF
.getSection(Sym
.d
.a
);
434 return SymTabOrErr
.takeError();
435 const Elf_Shdr
*SymTableSec
= *SymTabOrErr
;
436 auto StrTabOrErr
= EF
.getSection(SymTableSec
->sh_link
);
438 return StrTabOrErr
.takeError();
439 const Elf_Shdr
*StringTableSec
= *StrTabOrErr
;
440 auto SymStrTabOrErr
= EF
.getStringTable(StringTableSec
);
442 return SymStrTabOrErr
.takeError();
443 Expected
<StringRef
> Name
= ESym
->getName(*SymStrTabOrErr
);
445 // If the symbol name is empty use the section name.
446 if ((!Name
|| Name
->empty()) && ESym
->getType() == ELF::STT_SECTION
) {
448 Expected
<section_iterator
> Sec
= getSymbolSection(Sym
);
449 if (Sec
&& !(*Sec
)->getName(SecName
))
455 template <class ELFT
>
456 uint64_t ELFObjectFile
<ELFT
>::getSectionFlags(DataRefImpl Sec
) const {
457 return getSection(Sec
)->sh_flags
;
460 template <class ELFT
>
461 uint32_t ELFObjectFile
<ELFT
>::getSectionType(DataRefImpl Sec
) const {
462 return getSection(Sec
)->sh_type
;
465 template <class ELFT
>
466 uint64_t ELFObjectFile
<ELFT
>::getSectionOffset(DataRefImpl Sec
) const {
467 return getSection(Sec
)->sh_offset
;
470 template <class ELFT
>
471 uint64_t ELFObjectFile
<ELFT
>::getSymbolValueImpl(DataRefImpl Symb
) const {
472 const Elf_Sym
*ESym
= getSymbol(Symb
);
473 uint64_t Ret
= ESym
->st_value
;
474 if (ESym
->st_shndx
== ELF::SHN_ABS
)
477 const Elf_Ehdr
*Header
= EF
.getHeader();
478 // Clear the ARM/Thumb or microMIPS indicator flag.
479 if ((Header
->e_machine
== ELF::EM_ARM
|| Header
->e_machine
== ELF::EM_MIPS
) &&
480 ESym
->getType() == ELF::STT_FUNC
)
486 template <class ELFT
>
488 ELFObjectFile
<ELFT
>::getSymbolAddress(DataRefImpl Symb
) const {
489 uint64_t Result
= getSymbolValue(Symb
);
490 const Elf_Sym
*ESym
= getSymbol(Symb
);
491 switch (ESym
->st_shndx
) {
492 case ELF::SHN_COMMON
:
498 const Elf_Ehdr
*Header
= EF
.getHeader();
499 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
501 return SymTabOrErr
.takeError();
502 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
504 if (Header
->e_type
== ELF::ET_REL
) {
505 auto SectionOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
507 return SectionOrErr
.takeError();
508 const Elf_Shdr
*Section
= *SectionOrErr
;
510 Result
+= Section
->sh_addr
;
516 template <class ELFT
>
517 uint32_t ELFObjectFile
<ELFT
>::getSymbolAlignment(DataRefImpl Symb
) const {
518 const Elf_Sym
*Sym
= getSymbol(Symb
);
519 if (Sym
->st_shndx
== ELF::SHN_COMMON
)
520 return Sym
->st_value
;
524 template <class ELFT
>
525 uint16_t ELFObjectFile
<ELFT
>::getEMachine() const {
526 return EF
.getHeader()->e_machine
;
529 template <class ELFT
> uint16_t ELFObjectFile
<ELFT
>::getEType() const {
530 return EF
.getHeader()->e_type
;
533 template <class ELFT
>
534 uint64_t ELFObjectFile
<ELFT
>::getSymbolSize(DataRefImpl Sym
) const {
535 return getSymbol(Sym
)->st_size
;
538 template <class ELFT
>
539 uint64_t ELFObjectFile
<ELFT
>::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
540 return getSymbol(Symb
)->st_size
;
543 template <class ELFT
>
544 uint8_t ELFObjectFile
<ELFT
>::getSymbolOther(DataRefImpl Symb
) const {
545 return getSymbol(Symb
)->st_other
;
548 template <class ELFT
>
549 uint8_t ELFObjectFile
<ELFT
>::getSymbolELFType(DataRefImpl Symb
) const {
550 return getSymbol(Symb
)->getType();
553 template <class ELFT
>
554 Expected
<SymbolRef::Type
>
555 ELFObjectFile
<ELFT
>::getSymbolType(DataRefImpl Symb
) const {
556 const Elf_Sym
*ESym
= getSymbol(Symb
);
558 switch (ESym
->getType()) {
559 case ELF::STT_NOTYPE
:
560 return SymbolRef::ST_Unknown
;
561 case ELF::STT_SECTION
:
562 return SymbolRef::ST_Debug
;
564 return SymbolRef::ST_File
;
566 return SymbolRef::ST_Function
;
567 case ELF::STT_OBJECT
:
568 case ELF::STT_COMMON
:
570 return SymbolRef::ST_Data
;
572 return SymbolRef::ST_Other
;
576 template <class ELFT
>
577 uint32_t ELFObjectFile
<ELFT
>::getSymbolFlags(DataRefImpl Sym
) const {
578 const Elf_Sym
*ESym
= getSymbol(Sym
);
580 uint32_t Result
= SymbolRef::SF_None
;
582 if (ESym
->getBinding() != ELF::STB_LOCAL
)
583 Result
|= SymbolRef::SF_Global
;
585 if (ESym
->getBinding() == ELF::STB_WEAK
)
586 Result
|= SymbolRef::SF_Weak
;
588 if (ESym
->st_shndx
== ELF::SHN_ABS
)
589 Result
|= SymbolRef::SF_Absolute
;
591 if (ESym
->getType() == ELF::STT_FILE
|| ESym
->getType() == ELF::STT_SECTION
)
592 Result
|= SymbolRef::SF_FormatSpecific
;
594 auto DotSymtabSecSyms
= EF
.symbols(DotSymtabSec
);
595 if (DotSymtabSecSyms
&& ESym
== (*DotSymtabSecSyms
).begin())
596 Result
|= SymbolRef::SF_FormatSpecific
;
597 auto DotDynSymSecSyms
= EF
.symbols(DotDynSymSec
);
598 if (DotDynSymSecSyms
&& ESym
== (*DotDynSymSecSyms
).begin())
599 Result
|= SymbolRef::SF_FormatSpecific
;
601 if (EF
.getHeader()->e_machine
== ELF::EM_ARM
) {
602 if (Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
)) {
603 StringRef Name
= *NameOrErr
;
604 if (Name
.startswith("$d") || Name
.startswith("$t") ||
605 Name
.startswith("$a"))
606 Result
|= SymbolRef::SF_FormatSpecific
;
608 // TODO: Actually report errors helpfully.
609 consumeError(NameOrErr
.takeError());
611 if (ESym
->getType() == ELF::STT_FUNC
&& (ESym
->st_value
& 1) == 1)
612 Result
|= SymbolRef::SF_Thumb
;
615 if (ESym
->st_shndx
== ELF::SHN_UNDEF
)
616 Result
|= SymbolRef::SF_Undefined
;
618 if (ESym
->getType() == ELF::STT_COMMON
|| ESym
->st_shndx
== ELF::SHN_COMMON
)
619 Result
|= SymbolRef::SF_Common
;
621 if (isExportedToOtherDSO(ESym
))
622 Result
|= SymbolRef::SF_Exported
;
624 if (ESym
->getVisibility() == ELF::STV_HIDDEN
)
625 Result
|= SymbolRef::SF_Hidden
;
630 template <class ELFT
>
631 Expected
<section_iterator
>
632 ELFObjectFile
<ELFT
>::getSymbolSection(const Elf_Sym
*ESym
,
633 const Elf_Shdr
*SymTab
) const {
634 auto ESecOrErr
= EF
.getSection(ESym
, SymTab
, ShndxTable
);
636 return ESecOrErr
.takeError();
638 const Elf_Shdr
*ESec
= *ESecOrErr
;
640 return section_end();
643 Sec
.p
= reinterpret_cast<intptr_t>(ESec
);
644 return section_iterator(SectionRef(Sec
, this));
647 template <class ELFT
>
648 Expected
<section_iterator
>
649 ELFObjectFile
<ELFT
>::getSymbolSection(DataRefImpl Symb
) const {
650 const Elf_Sym
*Sym
= getSymbol(Symb
);
651 auto SymTabOrErr
= EF
.getSection(Symb
.d
.a
);
653 return SymTabOrErr
.takeError();
654 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
655 return getSymbolSection(Sym
, SymTab
);
658 template <class ELFT
>
659 void ELFObjectFile
<ELFT
>::moveSectionNext(DataRefImpl
&Sec
) const {
660 const Elf_Shdr
*ESec
= getSection(Sec
);
664 template <class ELFT
>
665 std::error_code ELFObjectFile
<ELFT
>::getSectionName(DataRefImpl Sec
,
666 StringRef
&Result
) const {
667 auto Name
= EF
.getSectionName(&*getSection(Sec
));
669 return errorToErrorCode(Name
.takeError());
671 return std::error_code();
674 template <class ELFT
>
675 uint64_t ELFObjectFile
<ELFT
>::getSectionAddress(DataRefImpl Sec
) const {
676 return getSection(Sec
)->sh_addr
;
679 template <class ELFT
>
680 uint64_t ELFObjectFile
<ELFT
>::getSectionIndex(DataRefImpl Sec
) const {
681 auto SectionsOrErr
= EF
.sections();
682 handleAllErrors(std::move(SectionsOrErr
.takeError()),
683 [](const ErrorInfoBase
&) {
684 llvm_unreachable("unable to get section index");
686 const Elf_Shdr
*First
= SectionsOrErr
->begin();
687 return getSection(Sec
) - First
;
690 template <class ELFT
>
691 uint64_t ELFObjectFile
<ELFT
>::getSectionSize(DataRefImpl Sec
) const {
692 return getSection(Sec
)->sh_size
;
695 template <class ELFT
>
697 ELFObjectFile
<ELFT
>::getSectionContents(DataRefImpl Sec
,
698 StringRef
&Result
) const {
699 const Elf_Shdr
*EShdr
= getSection(Sec
);
700 if (std::error_code EC
=
701 checkOffset(getMemoryBufferRef(),
702 (uintptr_t)base() + EShdr
->sh_offset
, EShdr
->sh_size
))
704 Result
= StringRef((const char *)base() + EShdr
->sh_offset
, EShdr
->sh_size
);
705 return std::error_code();
708 template <class ELFT
>
709 uint64_t ELFObjectFile
<ELFT
>::getSectionAlignment(DataRefImpl Sec
) const {
710 return getSection(Sec
)->sh_addralign
;
713 template <class ELFT
>
714 bool ELFObjectFile
<ELFT
>::isSectionCompressed(DataRefImpl Sec
) const {
715 return getSection(Sec
)->sh_flags
& ELF::SHF_COMPRESSED
;
718 template <class ELFT
>
719 bool ELFObjectFile
<ELFT
>::isSectionText(DataRefImpl Sec
) const {
720 return getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
;
723 template <class ELFT
>
724 bool ELFObjectFile
<ELFT
>::isSectionData(DataRefImpl Sec
) const {
725 const Elf_Shdr
*EShdr
= getSection(Sec
);
726 return EShdr
->sh_type
== ELF::SHT_PROGBITS
&&
727 EShdr
->sh_flags
& ELF::SHF_ALLOC
&&
728 !(EShdr
->sh_flags
& ELF::SHF_EXECINSTR
);
731 template <class ELFT
>
732 bool ELFObjectFile
<ELFT
>::isSectionBSS(DataRefImpl Sec
) const {
733 const Elf_Shdr
*EShdr
= getSection(Sec
);
734 return EShdr
->sh_flags
& (ELF::SHF_ALLOC
| ELF::SHF_WRITE
) &&
735 EShdr
->sh_type
== ELF::SHT_NOBITS
;
738 template <class ELFT
>
739 std::vector
<SectionRef
>
740 ELFObjectFile
<ELFT
>::dynamic_relocation_sections() const {
741 std::vector
<SectionRef
> Res
;
742 std::vector
<uintptr_t> Offsets
;
744 auto SectionsOrErr
= EF
.sections();
748 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
749 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
752 reinterpret_cast<Elf_Dyn
*>((uintptr_t)base() + Sec
.sh_offset
);
753 for (; Dynamic
->d_tag
!= ELF::DT_NULL
; Dynamic
++) {
754 if (Dynamic
->d_tag
== ELF::DT_REL
|| Dynamic
->d_tag
== ELF::DT_RELA
||
755 Dynamic
->d_tag
== ELF::DT_JMPREL
) {
756 Offsets
.push_back(Dynamic
->d_un
.d_val
);
760 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
761 if (is_contained(Offsets
, Sec
.sh_offset
))
762 Res
.emplace_back(toDRI(&Sec
), this);
767 template <class ELFT
>
768 bool ELFObjectFile
<ELFT
>::isSectionVirtual(DataRefImpl Sec
) const {
769 return getSection(Sec
)->sh_type
== ELF::SHT_NOBITS
;
772 template <class ELFT
>
773 bool ELFObjectFile
<ELFT
>::isBerkeleyText(DataRefImpl Sec
) const {
774 return getSection(Sec
)->sh_flags
& ELF::SHF_ALLOC
&&
775 (getSection(Sec
)->sh_flags
& ELF::SHF_EXECINSTR
||
776 !(getSection(Sec
)->sh_flags
& ELF::SHF_WRITE
));
779 template <class ELFT
>
780 bool ELFObjectFile
<ELFT
>::isBerkeleyData(DataRefImpl Sec
) const {
781 const Elf_Shdr
*EShdr
= getSection(Sec
);
782 return !isBerkeleyText(Sec
) && EShdr
->sh_type
!= ELF::SHT_NOBITS
&&
783 EShdr
->sh_flags
& ELF::SHF_ALLOC
;
786 template <class ELFT
>
788 ELFObjectFile
<ELFT
>::section_rel_begin(DataRefImpl Sec
) const {
790 auto SectionsOrErr
= EF
.sections();
792 return relocation_iterator(RelocationRef());
793 uintptr_t SHT
= reinterpret_cast<uintptr_t>((*SectionsOrErr
).begin());
794 RelData
.d
.a
= (Sec
.p
- SHT
) / EF
.getHeader()->e_shentsize
;
796 return relocation_iterator(RelocationRef(RelData
, this));
799 template <class ELFT
>
801 ELFObjectFile
<ELFT
>::section_rel_end(DataRefImpl Sec
) const {
802 const Elf_Shdr
*S
= reinterpret_cast<const Elf_Shdr
*>(Sec
.p
);
803 relocation_iterator Begin
= section_rel_begin(Sec
);
804 if (S
->sh_type
!= ELF::SHT_RELA
&& S
->sh_type
!= ELF::SHT_REL
)
806 DataRefImpl RelData
= Begin
->getRawDataRefImpl();
807 const Elf_Shdr
*RelSec
= getRelSection(RelData
);
809 // Error check sh_link here so that getRelocationSymbol can just use it.
810 auto SymSecOrErr
= EF
.getSection(RelSec
->sh_link
);
812 report_fatal_error(errorToErrorCode(SymSecOrErr
.takeError()).message());
814 RelData
.d
.b
+= S
->sh_size
/ S
->sh_entsize
;
815 return relocation_iterator(RelocationRef(RelData
, this));
818 template <class ELFT
>
820 ELFObjectFile
<ELFT
>::getRelocatedSection(DataRefImpl Sec
) const {
821 if (EF
.getHeader()->e_type
!= ELF::ET_REL
)
822 return section_end();
824 const Elf_Shdr
*EShdr
= getSection(Sec
);
825 uintX_t Type
= EShdr
->sh_type
;
826 if (Type
!= ELF::SHT_REL
&& Type
!= ELF::SHT_RELA
)
827 return section_end();
829 auto R
= EF
.getSection(EShdr
->sh_info
);
831 report_fatal_error(errorToErrorCode(R
.takeError()).message());
832 return section_iterator(SectionRef(toDRI(*R
), this));
836 template <class ELFT
>
837 void ELFObjectFile
<ELFT
>::moveRelocationNext(DataRefImpl
&Rel
) const {
841 template <class ELFT
>
843 ELFObjectFile
<ELFT
>::getRelocationSymbol(DataRefImpl Rel
) const {
845 const Elf_Shdr
*sec
= getRelSection(Rel
);
846 if (sec
->sh_type
== ELF::SHT_REL
)
847 symbolIdx
= getRel(Rel
)->getSymbol(EF
.isMips64EL());
849 symbolIdx
= getRela(Rel
)->getSymbol(EF
.isMips64EL());
853 // FIXME: error check symbolIdx
854 DataRefImpl SymbolData
;
855 SymbolData
.d
.a
= sec
->sh_link
;
856 SymbolData
.d
.b
= symbolIdx
;
857 return symbol_iterator(SymbolRef(SymbolData
, this));
860 template <class ELFT
>
861 uint64_t ELFObjectFile
<ELFT
>::getRelocationOffset(DataRefImpl Rel
) const {
862 const Elf_Shdr
*sec
= getRelSection(Rel
);
863 if (sec
->sh_type
== ELF::SHT_REL
)
864 return getRel(Rel
)->r_offset
;
866 return getRela(Rel
)->r_offset
;
869 template <class ELFT
>
870 uint64_t ELFObjectFile
<ELFT
>::getRelocationType(DataRefImpl Rel
) const {
871 const Elf_Shdr
*sec
= getRelSection(Rel
);
872 if (sec
->sh_type
== ELF::SHT_REL
)
873 return getRel(Rel
)->getType(EF
.isMips64EL());
875 return getRela(Rel
)->getType(EF
.isMips64EL());
878 template <class ELFT
>
879 StringRef ELFObjectFile
<ELFT
>::getRelocationTypeName(uint32_t Type
) const {
880 return getELFRelocationTypeName(EF
.getHeader()->e_machine
, Type
);
883 template <class ELFT
>
884 void ELFObjectFile
<ELFT
>::getRelocationTypeName(
885 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
886 uint32_t type
= getRelocationType(Rel
);
887 EF
.getRelocationTypeName(type
, Result
);
890 template <class ELFT
>
892 ELFObjectFile
<ELFT
>::getRelocationAddend(DataRefImpl Rel
) const {
893 if (getRelSection(Rel
)->sh_type
!= ELF::SHT_RELA
)
894 return createError("Section is not SHT_RELA");
895 return (int64_t)getRela(Rel
)->r_addend
;
898 template <class ELFT
>
899 const typename ELFObjectFile
<ELFT
>::Elf_Rel
*
900 ELFObjectFile
<ELFT
>::getRel(DataRefImpl Rel
) const {
901 assert(getRelSection(Rel
)->sh_type
== ELF::SHT_REL
);
902 auto Ret
= EF
.template getEntry
<Elf_Rel
>(Rel
.d
.a
, Rel
.d
.b
);
904 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
908 template <class ELFT
>
909 const typename ELFObjectFile
<ELFT
>::Elf_Rela
*
910 ELFObjectFile
<ELFT
>::getRela(DataRefImpl Rela
) const {
911 assert(getRelSection(Rela
)->sh_type
== ELF::SHT_RELA
);
912 auto Ret
= EF
.template getEntry
<Elf_Rela
>(Rela
.d
.a
, Rela
.d
.b
);
914 report_fatal_error(errorToErrorCode(Ret
.takeError()).message());
918 template <class ELFT
>
919 Expected
<ELFObjectFile
<ELFT
>>
920 ELFObjectFile
<ELFT
>::create(MemoryBufferRef Object
) {
921 auto EFOrErr
= ELFFile
<ELFT
>::create(Object
.getBuffer());
922 if (Error E
= EFOrErr
.takeError())
924 auto EF
= std::move(*EFOrErr
);
926 auto SectionsOrErr
= EF
.sections();
928 return SectionsOrErr
.takeError();
930 const Elf_Shdr
*DotDynSymSec
= nullptr;
931 const Elf_Shdr
*DotSymtabSec
= nullptr;
932 ArrayRef
<Elf_Word
> ShndxTable
;
933 for (const Elf_Shdr
&Sec
: *SectionsOrErr
) {
934 switch (Sec
.sh_type
) {
935 case ELF::SHT_DYNSYM
: {
937 return createError("More than one dynamic symbol table!");
941 case ELF::SHT_SYMTAB
: {
943 return createError("More than one static symbol table!");
947 case ELF::SHT_SYMTAB_SHNDX
: {
948 auto TableOrErr
= EF
.getSHNDXTable(Sec
);
950 return TableOrErr
.takeError();
951 ShndxTable
= *TableOrErr
;
956 return ELFObjectFile
<ELFT
>(Object
, EF
, DotDynSymSec
, DotSymtabSec
,
960 template <class ELFT
>
961 ELFObjectFile
<ELFT
>::ELFObjectFile(MemoryBufferRef Object
, ELFFile
<ELFT
> EF
,
962 const Elf_Shdr
*DotDynSymSec
,
963 const Elf_Shdr
*DotSymtabSec
,
964 ArrayRef
<Elf_Word
> ShndxTable
)
966 getELFType(ELFT::TargetEndianness
== support::little
, ELFT::Is64Bits
),
968 EF(EF
), DotDynSymSec(DotDynSymSec
), DotSymtabSec(DotSymtabSec
),
969 ShndxTable(ShndxTable
) {}
971 template <class ELFT
>
972 ELFObjectFile
<ELFT
>::ELFObjectFile(ELFObjectFile
<ELFT
> &&Other
)
973 : ELFObjectFile(Other
.Data
, Other
.EF
, Other
.DotDynSymSec
,
974 Other
.DotSymtabSec
, Other
.ShndxTable
) {}
976 template <class ELFT
>
977 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_begin() const {
978 DataRefImpl Sym
= toDRI(DotSymtabSec
, 0);
979 return basic_symbol_iterator(SymbolRef(Sym
, this));
982 template <class ELFT
>
983 basic_symbol_iterator ELFObjectFile
<ELFT
>::symbol_end() const {
984 const Elf_Shdr
*SymTab
= DotSymtabSec
;
986 return symbol_begin();
987 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
988 return basic_symbol_iterator(SymbolRef(Sym
, this));
991 template <class ELFT
>
992 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_begin() const {
993 DataRefImpl Sym
= toDRI(DotDynSymSec
, 0);
994 return symbol_iterator(SymbolRef(Sym
, this));
997 template <class ELFT
>
998 elf_symbol_iterator ELFObjectFile
<ELFT
>::dynamic_symbol_end() const {
999 const Elf_Shdr
*SymTab
= DotDynSymSec
;
1001 return dynamic_symbol_begin();
1002 DataRefImpl Sym
= toDRI(SymTab
, SymTab
->sh_size
/ sizeof(Elf_Sym
));
1003 return basic_symbol_iterator(SymbolRef(Sym
, this));
1006 template <class ELFT
>
1007 section_iterator ELFObjectFile
<ELFT
>::section_begin() const {
1008 auto SectionsOrErr
= EF
.sections();
1010 return section_iterator(SectionRef());
1011 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).begin()), this));
1014 template <class ELFT
>
1015 section_iterator ELFObjectFile
<ELFT
>::section_end() const {
1016 auto SectionsOrErr
= EF
.sections();
1018 return section_iterator(SectionRef());
1019 return section_iterator(SectionRef(toDRI((*SectionsOrErr
).end()), this));
1022 template <class ELFT
>
1023 uint8_t ELFObjectFile
<ELFT
>::getBytesInAddress() const {
1024 return ELFT::Is64Bits
? 8 : 4;
1027 template <class ELFT
>
1028 StringRef ELFObjectFile
<ELFT
>::getFileFormatName() const {
1029 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1030 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1031 case ELF::ELFCLASS32
:
1032 switch (EF
.getHeader()->e_machine
) {
1034 return "ELF32-i386";
1036 return "ELF32-iamcu";
1037 case ELF::EM_X86_64
:
1038 return "ELF32-x86-64";
1040 return (IsLittleEndian
? "ELF32-arm-little" : "ELF32-arm-big");
1043 case ELF::EM_HEXAGON
:
1044 return "ELF32-hexagon";
1046 return "ELF32-lanai";
1048 return "ELF32-mips";
1049 case ELF::EM_MSP430
:
1050 return "ELF32-msp430";
1054 return "ELF32-riscv";
1056 case ELF::EM_SPARC32PLUS
:
1057 return "ELF32-sparc";
1058 case ELF::EM_AMDGPU
:
1059 return "ELF32-amdgpu";
1061 return "ELF32-unknown";
1063 case ELF::ELFCLASS64
:
1064 switch (EF
.getHeader()->e_machine
) {
1066 return "ELF64-i386";
1067 case ELF::EM_X86_64
:
1068 return "ELF64-x86-64";
1069 case ELF::EM_AARCH64
:
1070 return (IsLittleEndian
? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1072 return "ELF64-ppc64";
1074 return "ELF64-riscv";
1076 return "ELF64-s390";
1077 case ELF::EM_SPARCV9
:
1078 return "ELF64-sparc";
1080 return "ELF64-mips";
1081 case ELF::EM_AMDGPU
:
1082 return "ELF64-amdgpu";
1086 return "ELF64-unknown";
1089 // FIXME: Proper error handling.
1090 report_fatal_error("Invalid ELFCLASS!");
1094 template <class ELFT
> Triple::ArchType ELFObjectFile
<ELFT
>::getArch() const {
1095 bool IsLittleEndian
= ELFT::TargetEndianness
== support::little
;
1096 switch (EF
.getHeader()->e_machine
) {
1100 case ELF::EM_X86_64
:
1101 return Triple::x86_64
;
1102 case ELF::EM_AARCH64
:
1103 return IsLittleEndian
? Triple::aarch64
: Triple::aarch64_be
;
1108 case ELF::EM_HEXAGON
:
1109 return Triple::hexagon
;
1111 return Triple::lanai
;
1113 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1114 case ELF::ELFCLASS32
:
1115 return IsLittleEndian
? Triple::mipsel
: Triple::mips
;
1116 case ELF::ELFCLASS64
:
1117 return IsLittleEndian
? Triple::mips64el
: Triple::mips64
;
1119 report_fatal_error("Invalid ELFCLASS!");
1121 case ELF::EM_MSP430
:
1122 return Triple::msp430
;
1126 return IsLittleEndian
? Triple::ppc64le
: Triple::ppc64
;
1128 switch (EF
.getHeader()->e_ident
[ELF::EI_CLASS
]) {
1129 case ELF::ELFCLASS32
:
1130 return Triple::riscv32
;
1131 case ELF::ELFCLASS64
:
1132 return Triple::riscv64
;
1134 report_fatal_error("Invalid ELFCLASS!");
1137 return Triple::systemz
;
1140 case ELF::EM_SPARC32PLUS
:
1141 return IsLittleEndian
? Triple::sparcel
: Triple::sparc
;
1142 case ELF::EM_SPARCV9
:
1143 return Triple::sparcv9
;
1145 case ELF::EM_AMDGPU
: {
1146 if (!IsLittleEndian
)
1147 return Triple::UnknownArch
;
1149 unsigned MACH
= EF
.getHeader()->e_flags
& ELF::EF_AMDGPU_MACH
;
1150 if (MACH
>= ELF::EF_AMDGPU_MACH_R600_FIRST
&&
1151 MACH
<= ELF::EF_AMDGPU_MACH_R600_LAST
)
1152 return Triple::r600
;
1153 if (MACH
>= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST
&&
1154 MACH
<= ELF::EF_AMDGPU_MACH_AMDGCN_LAST
)
1155 return Triple::amdgcn
;
1157 return Triple::UnknownArch
;
1161 return IsLittleEndian
? Triple::bpfel
: Triple::bpfeb
;
1164 return Triple::UnknownArch
;
1168 template <class ELFT
>
1169 Expected
<uint64_t> ELFObjectFile
<ELFT
>::getStartAddress() const {
1170 return EF
.getHeader()->e_entry
;
1173 template <class ELFT
>
1174 ELFObjectFileBase::elf_symbol_iterator_range
1175 ELFObjectFile
<ELFT
>::getDynamicSymbolIterators() const {
1176 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1179 template <class ELFT
> bool ELFObjectFile
<ELFT
>::isRelocatableObject() const {
1180 return EF
.getHeader()->e_type
== ELF::ET_REL
;
1183 } // end namespace object
1184 } // end namespace llvm
1186 #endif // LLVM_OBJECT_ELFOBJECTFILE_H