1 //===- ELF.cpp - ELF object file implementation ---------------------------===//
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 #include "llvm/Object/ELF.h"
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/Support/Compiler.h"
13 #include "llvm/Support/DataExtractor.h"
16 using namespace object
;
18 #define STRINGIFY_ENUM_CASE(ns, name) \
22 #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
24 StringRef
llvm::object::getELFRelocationTypeName(uint32_t Machine
,
29 #include "llvm/BinaryFormat/ELFRelocs/M68k.def"
36 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
44 #include "llvm/BinaryFormat/ELFRelocs/i386.def"
51 #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
58 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
65 #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
70 case ELF::EM_ARC_COMPACT
:
71 case ELF::EM_ARC_COMPACT2
:
73 #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
80 #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
87 #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
94 #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
101 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
108 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
115 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
122 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
128 case ELF::EM_SPARC32PLUS
:
129 case ELF::EM_SPARCV9
:
131 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
138 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
145 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
152 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
159 #include "llvm/BinaryFormat/ELFRelocs/VE.def"
166 #include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
171 case ELF::EM_LOONGARCH
:
173 #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
180 #include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
193 uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine
) {
196 return ELF::R_X86_64_RELATIVE
;
199 return ELF::R_386_RELATIVE
;
202 case ELF::EM_AARCH64
:
203 return ELF::R_AARCH64_RELATIVE
;
205 return ELF::R_ARM_RELATIVE
;
206 case ELF::EM_ARC_COMPACT
:
207 case ELF::EM_ARC_COMPACT2
:
208 return ELF::R_ARC_RELATIVE
;
211 case ELF::EM_HEXAGON
:
212 return ELF::R_HEX_RELATIVE
;
218 return ELF::R_PPC64_RELATIVE
;
220 return ELF::R_RISCV_RELATIVE
;
222 return ELF::R_390_RELATIVE
;
224 case ELF::EM_SPARC32PLUS
:
225 case ELF::EM_SPARCV9
:
226 return ELF::R_SPARC_RELATIVE
;
228 return ELF::R_CKCORE_RELATIVE
;
230 return ELF::R_VE_RELATIVE
;
235 case ELF::EM_LOONGARCH
:
236 return ELF::R_LARCH_RELATIVE
;
243 StringRef
llvm::object::getELFSectionTypeName(uint32_t Machine
, unsigned Type
) {
247 STRINGIFY_ENUM_CASE(ELF
, SHT_ARM_EXIDX
);
248 STRINGIFY_ENUM_CASE(ELF
, SHT_ARM_PREEMPTMAP
);
249 STRINGIFY_ENUM_CASE(ELF
, SHT_ARM_ATTRIBUTES
);
250 STRINGIFY_ENUM_CASE(ELF
, SHT_ARM_DEBUGOVERLAY
);
251 STRINGIFY_ENUM_CASE(ELF
, SHT_ARM_OVERLAYSECTION
);
254 case ELF::EM_HEXAGON
:
256 STRINGIFY_ENUM_CASE(ELF
, SHT_HEX_ORDERED
);
257 STRINGIFY_ENUM_CASE(ELF
, SHT_HEXAGON_ATTRIBUTES
);
261 switch (Type
) { STRINGIFY_ENUM_CASE(ELF
, SHT_X86_64_UNWIND
); }
264 case ELF::EM_MIPS_RS3_LE
:
266 STRINGIFY_ENUM_CASE(ELF
, SHT_MIPS_REGINFO
);
267 STRINGIFY_ENUM_CASE(ELF
, SHT_MIPS_OPTIONS
);
268 STRINGIFY_ENUM_CASE(ELF
, SHT_MIPS_DWARF
);
269 STRINGIFY_ENUM_CASE(ELF
, SHT_MIPS_ABIFLAGS
);
273 switch (Type
) { STRINGIFY_ENUM_CASE(ELF
, SHT_MSP430_ATTRIBUTES
); }
276 switch (Type
) { STRINGIFY_ENUM_CASE(ELF
, SHT_RISCV_ATTRIBUTES
); }
278 case ELF::EM_AARCH64
:
280 STRINGIFY_ENUM_CASE(ELF
, SHT_AARCH64_AUTH_RELR
);
281 STRINGIFY_ENUM_CASE(ELF
, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC
);
282 STRINGIFY_ENUM_CASE(ELF
, SHT_AARCH64_MEMTAG_GLOBALS_STATIC
);
289 STRINGIFY_ENUM_CASE(ELF
, SHT_NULL
);
290 STRINGIFY_ENUM_CASE(ELF
, SHT_PROGBITS
);
291 STRINGIFY_ENUM_CASE(ELF
, SHT_SYMTAB
);
292 STRINGIFY_ENUM_CASE(ELF
, SHT_STRTAB
);
293 STRINGIFY_ENUM_CASE(ELF
, SHT_RELA
);
294 STRINGIFY_ENUM_CASE(ELF
, SHT_HASH
);
295 STRINGIFY_ENUM_CASE(ELF
, SHT_DYNAMIC
);
296 STRINGIFY_ENUM_CASE(ELF
, SHT_NOTE
);
297 STRINGIFY_ENUM_CASE(ELF
, SHT_NOBITS
);
298 STRINGIFY_ENUM_CASE(ELF
, SHT_REL
);
299 STRINGIFY_ENUM_CASE(ELF
, SHT_SHLIB
);
300 STRINGIFY_ENUM_CASE(ELF
, SHT_DYNSYM
);
301 STRINGIFY_ENUM_CASE(ELF
, SHT_INIT_ARRAY
);
302 STRINGIFY_ENUM_CASE(ELF
, SHT_FINI_ARRAY
);
303 STRINGIFY_ENUM_CASE(ELF
, SHT_PREINIT_ARRAY
);
304 STRINGIFY_ENUM_CASE(ELF
, SHT_GROUP
);
305 STRINGIFY_ENUM_CASE(ELF
, SHT_SYMTAB_SHNDX
);
306 STRINGIFY_ENUM_CASE(ELF
, SHT_RELR
);
307 STRINGIFY_ENUM_CASE(ELF
, SHT_CREL
);
308 STRINGIFY_ENUM_CASE(ELF
, SHT_ANDROID_REL
);
309 STRINGIFY_ENUM_CASE(ELF
, SHT_ANDROID_RELA
);
310 STRINGIFY_ENUM_CASE(ELF
, SHT_ANDROID_RELR
);
311 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_ODRTAB
);
312 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_LINKER_OPTIONS
);
313 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_CALL_GRAPH_PROFILE
);
314 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_ADDRSIG
);
315 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_DEPENDENT_LIBRARIES
);
316 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_SYMPART
);
317 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_PART_EHDR
);
318 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_PART_PHDR
);
319 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_BB_ADDR_MAP_V0
);
320 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_BB_ADDR_MAP
);
321 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_OFFLOADING
);
322 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_LTO
);
323 STRINGIFY_ENUM_CASE(ELF
, SHT_LLVM_JT_SIZES
)
324 STRINGIFY_ENUM_CASE(ELF
, SHT_GNU_ATTRIBUTES
);
325 STRINGIFY_ENUM_CASE(ELF
, SHT_GNU_HASH
);
326 STRINGIFY_ENUM_CASE(ELF
, SHT_GNU_verdef
);
327 STRINGIFY_ENUM_CASE(ELF
, SHT_GNU_verneed
);
328 STRINGIFY_ENUM_CASE(ELF
, SHT_GNU_versym
);
334 template <class ELFT
>
335 std::vector
<typename
ELFT::Rel
>
336 ELFFile
<ELFT
>::decode_relrs(Elf_Relr_Range relrs
) const {
337 // This function decodes the contents of an SHT_RELR packed relocation
340 // Proposal for adding SHT_RELR sections to generic-abi is here:
341 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
343 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
344 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
346 // i.e. start with an address, followed by any number of bitmaps. The address
347 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
348 // relocations each, at subsequent offsets following the last address entry.
350 // The bitmap entries must have 1 in the least significant bit. The assumption
351 // here is that an address cannot have 1 in lsb. Odd addresses are not
354 // Excluding the least significant bit in the bitmap, each non-zero bit in
355 // the bitmap represents a relocation to be applied to a corresponding machine
356 // word that follows the base address word. The second least significant bit
357 // represents the machine word immediately following the initial address, and
358 // each bit that follows represents the next word, in linear order. As such,
359 // a single bitmap can encode up to 31 relocations in a 32-bit object, and
360 // 63 relocations in a 64-bit object.
362 // This encoding has a couple of interesting properties:
363 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
364 // even means address, odd means bitmap.
365 // 2. Just a simple list of addresses is a valid encoding.
369 Rel
.setType(getRelativeRelocationType(), false);
370 std::vector
<Elf_Rel
> Relocs
;
372 // Word type: uint32_t for Elf32, and uint64_t for Elf64.
373 using Addr
= typename
ELFT::uint
;
376 for (Elf_Relr R
: relrs
) {
377 typename
ELFT::uint Entry
= R
;
378 if ((Entry
& 1) == 0) {
379 // Even entry: encodes the offset for next relocation.
380 Rel
.r_offset
= Entry
;
381 Relocs
.push_back(Rel
);
382 // Set base offset for subsequent bitmap entries.
383 Base
= Entry
+ sizeof(Addr
);
385 // Odd entry: encodes bitmap for relocations starting at base.
386 for (Addr Offset
= Base
; (Entry
>>= 1) != 0; Offset
+= sizeof(Addr
))
387 if ((Entry
& 1) != 0) {
388 Rel
.r_offset
= Offset
;
389 Relocs
.push_back(Rel
);
391 Base
+= (CHAR_BIT
* sizeof(Entry
) - 1) * sizeof(Addr
);
398 template <class ELFT
>
400 ELFFile
<ELFT
>::getCrelHeader(ArrayRef
<uint8_t> Content
) const {
401 DataExtractor
Data(Content
, isLE(), sizeof(typename
ELFT::Addr
));
402 Error Err
= Error::success();
404 Hdr
= Data
.getULEB128(&Hdr
, &Err
);
410 template <class ELFT
>
411 Expected
<typename ELFFile
<ELFT
>::RelsOrRelas
>
412 ELFFile
<ELFT
>::decodeCrel(ArrayRef
<uint8_t> Content
) const {
413 std::vector
<Elf_Rel
> Rels
;
414 std::vector
<Elf_Rela
> Relas
;
417 Error Err
= object::decodeCrel
<ELFT::Is64Bits
>(
419 [&](uint64_t Count
, bool HasA
) {
428 Relas
[I
].r_offset
= Crel
.r_offset
;
429 Relas
[I
].setSymbolAndType(Crel
.r_symidx
, Crel
.r_type
, false);
430 Relas
[I
++].r_addend
= Crel
.r_addend
;
432 Rels
[I
].r_offset
= Crel
.r_offset
;
433 Rels
[I
++].setSymbolAndType(Crel
.r_symidx
, Crel
.r_type
, false);
437 return std::move(Err
);
438 return std::make_pair(std::move(Rels
), std::move(Relas
));
441 template <class ELFT
>
442 Expected
<typename ELFFile
<ELFT
>::RelsOrRelas
>
443 ELFFile
<ELFT
>::crels(const Elf_Shdr
&Sec
) const {
444 Expected
<ArrayRef
<uint8_t>> ContentsOrErr
= getSectionContents(Sec
);
446 return ContentsOrErr
.takeError();
447 return decodeCrel(*ContentsOrErr
);
450 template <class ELFT
>
451 Expected
<std::vector
<typename
ELFT::Rela
>>
452 ELFFile
<ELFT
>::android_relas(const Elf_Shdr
&Sec
) const {
453 // This function reads relocations in Android's packed relocation format,
454 // which is based on SLEB128 and delta encoding.
455 Expected
<ArrayRef
<uint8_t>> ContentsOrErr
= getSectionContents(Sec
);
457 return ContentsOrErr
.takeError();
458 ArrayRef
<uint8_t> Content
= *ContentsOrErr
;
459 if (Content
.size() < 4 || Content
[0] != 'A' || Content
[1] != 'P' ||
460 Content
[2] != 'S' || Content
[3] != '2')
461 return createError("invalid packed relocation header");
462 DataExtractor
Data(Content
, isLE(), ELFT::Is64Bits
? 8 : 4);
463 DataExtractor::Cursor
Cur(/*Offset=*/4);
465 uint64_t NumRelocs
= Data
.getSLEB128(Cur
);
466 uint64_t Offset
= Data
.getSLEB128(Cur
);
470 return std::move(Cur
.takeError());
472 std::vector
<Elf_Rela
> Relocs
;
473 Relocs
.reserve(NumRelocs
);
475 uint64_t NumRelocsInGroup
= Data
.getSLEB128(Cur
);
477 return std::move(Cur
.takeError());
478 if (NumRelocsInGroup
> NumRelocs
)
479 return createError("relocation group unexpectedly large");
480 NumRelocs
-= NumRelocsInGroup
;
482 uint64_t GroupFlags
= Data
.getSLEB128(Cur
);
483 bool GroupedByInfo
= GroupFlags
& ELF::RELOCATION_GROUPED_BY_INFO_FLAG
;
484 bool GroupedByOffsetDelta
= GroupFlags
& ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
;
485 bool GroupedByAddend
= GroupFlags
& ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG
;
486 bool GroupHasAddend
= GroupFlags
& ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG
;
488 uint64_t GroupOffsetDelta
;
489 if (GroupedByOffsetDelta
)
490 GroupOffsetDelta
= Data
.getSLEB128(Cur
);
494 GroupRInfo
= Data
.getSLEB128(Cur
);
496 if (GroupedByAddend
&& GroupHasAddend
)
497 Addend
+= Data
.getSLEB128(Cur
);
502 for (uint64_t I
= 0; Cur
&& I
!= NumRelocsInGroup
; ++I
) {
504 Offset
+= GroupedByOffsetDelta
? GroupOffsetDelta
: Data
.getSLEB128(Cur
);
506 R
.r_info
= GroupedByInfo
? GroupRInfo
: Data
.getSLEB128(Cur
);
507 if (GroupHasAddend
&& !GroupedByAddend
)
508 Addend
+= Data
.getSLEB128(Cur
);
513 return std::move(Cur
.takeError());
519 template <class ELFT
>
520 std::string ELFFile
<ELFT
>::getDynamicTagAsString(unsigned Arch
,
521 uint64_t Type
) const {
522 #define DYNAMIC_STRINGIFY_ENUM(tag, value) \
526 #define DYNAMIC_TAG(n, v)
528 case ELF::EM_AARCH64
:
530 #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
531 #include "llvm/BinaryFormat/DynamicTags.def"
532 #undef AARCH64_DYNAMIC_TAG
536 case ELF::EM_HEXAGON
:
538 #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
539 #include "llvm/BinaryFormat/DynamicTags.def"
540 #undef HEXAGON_DYNAMIC_TAG
546 #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
547 #include "llvm/BinaryFormat/DynamicTags.def"
548 #undef MIPS_DYNAMIC_TAG
554 #define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
555 #include "llvm/BinaryFormat/DynamicTags.def"
556 #undef PPC_DYNAMIC_TAG
562 #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
563 #include "llvm/BinaryFormat/DynamicTags.def"
564 #undef PPC64_DYNAMIC_TAG
570 #define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
571 #include "llvm/BinaryFormat/DynamicTags.def"
572 #undef RISCV_DYNAMIC_TAG
578 // Now handle all dynamic tags except the architecture specific ones
579 #define AARCH64_DYNAMIC_TAG(name, value)
580 #define MIPS_DYNAMIC_TAG(name, value)
581 #define HEXAGON_DYNAMIC_TAG(name, value)
582 #define PPC_DYNAMIC_TAG(name, value)
583 #define PPC64_DYNAMIC_TAG(name, value)
584 #define RISCV_DYNAMIC_TAG(name, value)
585 // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
586 #define DYNAMIC_TAG_MARKER(name, value)
587 #define DYNAMIC_TAG(name, value) case value: return #name;
588 #include "llvm/BinaryFormat/DynamicTags.def"
590 #undef AARCH64_DYNAMIC_TAG
591 #undef MIPS_DYNAMIC_TAG
592 #undef HEXAGON_DYNAMIC_TAG
593 #undef PPC_DYNAMIC_TAG
594 #undef PPC64_DYNAMIC_TAG
595 #undef RISCV_DYNAMIC_TAG
596 #undef DYNAMIC_TAG_MARKER
597 #undef DYNAMIC_STRINGIFY_ENUM
599 return "<unknown:>0x" + utohexstr(Type
, true);
603 template <class ELFT
>
604 std::string ELFFile
<ELFT
>::getDynamicTagAsString(uint64_t Type
) const {
605 return getDynamicTagAsString(getHeader().e_machine
, Type
);
608 template <class ELFT
>
609 Expected
<typename
ELFT::DynRange
> ELFFile
<ELFT
>::dynamicEntries() const {
610 ArrayRef
<Elf_Dyn
> Dyn
;
612 auto ProgramHeadersOrError
= program_headers();
613 if (!ProgramHeadersOrError
)
614 return ProgramHeadersOrError
.takeError();
616 for (const Elf_Phdr
&Phdr
: *ProgramHeadersOrError
) {
617 if (Phdr
.p_type
== ELF::PT_DYNAMIC
) {
618 const uint8_t *DynOffset
= base() + Phdr
.p_offset
;
619 if (DynOffset
> end())
621 "dynamic section offset past file size: corrupted ELF");
622 Dyn
= ArrayRef(reinterpret_cast<const Elf_Dyn
*>(DynOffset
),
623 Phdr
.p_filesz
/ sizeof(Elf_Dyn
));
628 // If we can't find the dynamic section in the program headers, we just fall
629 // back on the sections.
631 auto SectionsOrError
= sections();
632 if (!SectionsOrError
)
633 return SectionsOrError
.takeError();
635 for (const Elf_Shdr
&Sec
: *SectionsOrError
) {
636 if (Sec
.sh_type
== ELF::SHT_DYNAMIC
) {
637 Expected
<ArrayRef
<Elf_Dyn
>> DynOrError
=
638 getSectionContentsAsArray
<Elf_Dyn
>(Sec
);
640 return DynOrError
.takeError();
647 return ArrayRef
<Elf_Dyn
>();
651 return createError("invalid empty dynamic section");
653 if (Dyn
.back().d_tag
!= ELF::DT_NULL
)
654 return createError("dynamic sections must be DT_NULL terminated");
659 template <class ELFT
>
660 Expected
<const uint8_t *>
661 ELFFile
<ELFT
>::toMappedAddr(uint64_t VAddr
, WarningHandler WarnHandler
) const {
662 auto ProgramHeadersOrError
= program_headers();
663 if (!ProgramHeadersOrError
)
664 return ProgramHeadersOrError
.takeError();
666 llvm::SmallVector
<Elf_Phdr
*, 4> LoadSegments
;
668 for (const Elf_Phdr
&Phdr
: *ProgramHeadersOrError
)
669 if (Phdr
.p_type
== ELF::PT_LOAD
)
670 LoadSegments
.push_back(const_cast<Elf_Phdr
*>(&Phdr
));
672 auto SortPred
= [](const Elf_Phdr_Impl
<ELFT
> *A
,
673 const Elf_Phdr_Impl
<ELFT
> *B
) {
674 return A
->p_vaddr
< B
->p_vaddr
;
676 if (!llvm::is_sorted(LoadSegments
, SortPred
)) {
678 WarnHandler("loadable segments are unsorted by virtual address"))
680 llvm::stable_sort(LoadSegments
, SortPred
);
683 const Elf_Phdr
*const *I
= llvm::upper_bound(
684 LoadSegments
, VAddr
, [](uint64_t VAddr
, const Elf_Phdr_Impl
<ELFT
> *Phdr
) {
685 return VAddr
< Phdr
->p_vaddr
;
688 if (I
== LoadSegments
.begin())
689 return createError("virtual address is not in any segment: 0x" +
690 Twine::utohexstr(VAddr
));
692 const Elf_Phdr
&Phdr
= **I
;
693 uint64_t Delta
= VAddr
- Phdr
.p_vaddr
;
694 if (Delta
>= Phdr
.p_filesz
)
695 return createError("virtual address is not in any segment: 0x" +
696 Twine::utohexstr(VAddr
));
698 uint64_t Offset
= Phdr
.p_offset
+ Delta
;
699 if (Offset
>= getBufSize())
700 return createError("can't map virtual address 0x" +
701 Twine::utohexstr(VAddr
) + " to the segment with index " +
702 Twine(&Phdr
- (*ProgramHeadersOrError
).data() + 1) +
703 ": the segment ends at 0x" +
704 Twine::utohexstr(Phdr
.p_offset
+ Phdr
.p_filesz
) +
705 ", which is greater than the file size (0x" +
706 Twine::utohexstr(getBufSize()) + ")");
708 return base() + Offset
;
711 // Helper to extract and decode the next ULEB128 value as unsigned int.
712 // Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned
714 // Also returns zero if ULEBSizeErr is already in an error state.
715 // ULEBSizeErr is an out variable if an error occurs.
716 template <typename IntTy
, std::enable_if_t
<std::is_unsigned_v
<IntTy
>, int> = 0>
717 static IntTy
readULEB128As(DataExtractor
&Data
, DataExtractor::Cursor
&Cur
,
718 Error
&ULEBSizeErr
) {
719 // Bail out and do not extract data if ULEBSizeErr is already set.
722 uint64_t Offset
= Cur
.tell();
723 uint64_t Value
= Data
.getULEB128(Cur
);
724 if (Value
> std::numeric_limits
<IntTy
>::max()) {
725 ULEBSizeErr
= createError("ULEB128 value at offset 0x" +
726 Twine::utohexstr(Offset
) + " exceeds UINT" +
727 Twine(std::numeric_limits
<IntTy
>::digits
) +
728 "_MAX (0x" + Twine::utohexstr(Value
) + ")");
731 return static_cast<IntTy
>(Value
);
734 template <typename ELFT
>
735 static Expected
<std::vector
<BBAddrMap
>>
736 decodeBBAddrMapImpl(const ELFFile
<ELFT
> &EF
,
737 const typename ELFFile
<ELFT
>::Elf_Shdr
&Sec
,
738 const typename ELFFile
<ELFT
>::Elf_Shdr
*RelaSec
,
739 std::vector
<PGOAnalysisMap
> *PGOAnalyses
) {
740 bool IsRelocatable
= EF
.getHeader().e_type
== ELF::ET_REL
;
742 // This DenseMap maps the offset of each function (the location of the
743 // reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the
744 // addend (the location of the function in the text section).
745 llvm::DenseMap
<uint64_t, uint64_t> FunctionOffsetTranslations
;
746 if (IsRelocatable
&& RelaSec
) {
748 "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
749 "object file without providing a relocation section.");
750 Expected
<typename ELFFile
<ELFT
>::Elf_Rela_Range
> Relas
= EF
.relas(*RelaSec
);
752 return createError("unable to read relocations for section " +
753 describe(EF
, Sec
) + ": " +
754 toString(Relas
.takeError()));
755 for (typename ELFFile
<ELFT
>::Elf_Rela Rela
: *Relas
)
756 FunctionOffsetTranslations
[Rela
.r_offset
] = Rela
.r_addend
;
758 auto GetAddressForRelocation
=
759 [&](unsigned RelocationOffsetInSection
) -> Expected
<unsigned> {
761 FunctionOffsetTranslations
.find(RelocationOffsetInSection
);
762 if (FOTIterator
== FunctionOffsetTranslations
.end()) {
763 return createError("failed to get relocation data for offset: " +
764 Twine::utohexstr(RelocationOffsetInSection
) +
765 " in section " + describe(EF
, Sec
));
767 return FOTIterator
->second
;
769 Expected
<ArrayRef
<uint8_t>> ContentsOrErr
= EF
.getSectionContents(Sec
);
771 return ContentsOrErr
.takeError();
772 ArrayRef
<uint8_t> Content
= *ContentsOrErr
;
773 DataExtractor
Data(Content
, EF
.isLE(), ELFT::Is64Bits
? 8 : 4);
774 std::vector
<BBAddrMap
> FunctionEntries
;
776 DataExtractor::Cursor
Cur(0);
777 Error ULEBSizeErr
= Error::success();
778 Error MetadataDecodeErr
= Error::success();
780 // Helper lampda to extract the (possiblly relocatable) address stored at Cur.
781 auto ExtractAddress
= [&]() -> Expected
<typename ELFFile
<ELFT
>::uintX_t
> {
782 uint64_t RelocationOffsetInSection
= Cur
.tell();
784 static_cast<typename ELFFile
<ELFT
>::uintX_t
>(Data
.getAddress(Cur
));
786 return Cur
.takeError();
789 assert(Address
== 0);
790 Expected
<unsigned> AddressOrErr
=
791 GetAddressForRelocation(RelocationOffsetInSection
);
793 return AddressOrErr
.takeError();
794 return *AddressOrErr
;
799 BBAddrMap::Features FeatEnable
{};
800 while (!ULEBSizeErr
&& !MetadataDecodeErr
&& Cur
&&
801 Cur
.tell() < Content
.size()) {
802 if (Sec
.sh_type
== ELF::SHT_LLVM_BB_ADDR_MAP
) {
803 Version
= Data
.getU8(Cur
);
807 return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
808 Twine(static_cast<int>(Version
)));
809 Feature
= Data
.getU8(Cur
); // Feature byte
812 auto FeatEnableOrErr
= BBAddrMap::Features::decode(Feature
);
813 if (!FeatEnableOrErr
)
814 return FeatEnableOrErr
.takeError();
815 FeatEnable
= *FeatEnableOrErr
;
816 if (Feature
!= 0 && Version
< 2 && Cur
)
818 "version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when "
819 "PGO features are enabled: version = " +
820 Twine(static_cast<int>(Version
)) +
821 " feature = " + Twine(static_cast<int>(Feature
)));
823 uint32_t NumBlocksInBBRange
= 0;
824 uint32_t NumBBRanges
= 1;
825 typename ELFFile
<ELFT
>::uintX_t RangeBaseAddress
= 0;
826 if (FeatEnable
.MultiBBRange
) {
827 NumBBRanges
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
828 if (!Cur
|| ULEBSizeErr
)
831 return createError("invalid zero number of BB ranges at offset " +
832 Twine::utohexstr(Cur
.tell()) + " in " +
835 auto AddressOrErr
= ExtractAddress();
837 return AddressOrErr
.takeError();
838 RangeBaseAddress
= *AddressOrErr
;
839 NumBlocksInBBRange
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
841 std::vector
<BBAddrMap::BBRangeEntry
> BBRangeEntries
;
842 uint32_t TotalNumBlocks
= 0;
843 for (uint32_t BBRangeIndex
= 0; BBRangeIndex
< NumBBRanges
;
845 uint32_t PrevBBEndOffset
= 0;
846 if (FeatEnable
.MultiBBRange
) {
847 auto AddressOrErr
= ExtractAddress();
849 return AddressOrErr
.takeError();
850 RangeBaseAddress
= *AddressOrErr
;
851 NumBlocksInBBRange
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
853 std::vector
<BBAddrMap::BBEntry
> BBEntries
;
854 if (!FeatEnable
.OmitBBEntries
) {
855 for (uint32_t BlockIndex
= 0; !MetadataDecodeErr
&& !ULEBSizeErr
&&
856 Cur
&& (BlockIndex
< NumBlocksInBBRange
);
858 uint32_t ID
= Version
>= 2
859 ? readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
)
861 uint32_t Offset
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
862 uint32_t Size
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
863 uint32_t MD
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
865 // Offset is calculated relative to the end of the previous BB.
866 Offset
+= PrevBBEndOffset
;
867 PrevBBEndOffset
= Offset
+ Size
;
869 Expected
<BBAddrMap::BBEntry::Metadata
> MetadataOrErr
=
870 BBAddrMap::BBEntry::Metadata::decode(MD
);
871 if (!MetadataOrErr
) {
872 MetadataDecodeErr
= MetadataOrErr
.takeError();
875 BBEntries
.push_back({ID
, Offset
, Size
, *MetadataOrErr
});
877 TotalNumBlocks
+= BBEntries
.size();
879 BBRangeEntries
.push_back({RangeBaseAddress
, std::move(BBEntries
)});
881 FunctionEntries
.push_back({std::move(BBRangeEntries
)});
883 if (PGOAnalyses
|| FeatEnable
.hasPGOAnalysis()) {
884 // Function entry count
885 uint64_t FuncEntryCount
=
886 FeatEnable
.FuncEntryCount
887 ? readULEB128As
<uint64_t>(Data
, Cur
, ULEBSizeErr
)
890 std::vector
<PGOAnalysisMap::PGOBBEntry
> PGOBBEntries
;
891 for (uint32_t BlockIndex
= 0;
892 FeatEnable
.hasPGOAnalysisBBData() && !MetadataDecodeErr
&&
893 !ULEBSizeErr
&& Cur
&& (BlockIndex
< TotalNumBlocks
);
896 uint64_t BBF
= FeatEnable
.BBFreq
897 ? readULEB128As
<uint64_t>(Data
, Cur
, ULEBSizeErr
)
900 // Branch probability
901 llvm::SmallVector
<PGOAnalysisMap::PGOBBEntry::SuccessorEntry
, 2>
903 if (FeatEnable
.BrProb
) {
904 auto SuccCount
= readULEB128As
<uint64_t>(Data
, Cur
, ULEBSizeErr
);
905 for (uint64_t I
= 0; I
< SuccCount
; ++I
) {
906 uint32_t BBID
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
907 uint32_t BrProb
= readULEB128As
<uint32_t>(Data
, Cur
, ULEBSizeErr
);
909 Successors
.push_back({BBID
, BranchProbability::getRaw(BrProb
)});
914 PGOBBEntries
.push_back({BlockFrequency(BBF
), std::move(Successors
)});
918 PGOAnalyses
->push_back(
919 {FuncEntryCount
, std::move(PGOBBEntries
), FeatEnable
});
922 // Either Cur is in the error state, or we have an error in ULEBSizeErr or
923 // MetadataDecodeErr (but not both), but we join all errors here to be safe.
924 if (!Cur
|| ULEBSizeErr
|| MetadataDecodeErr
)
925 return joinErrors(joinErrors(Cur
.takeError(), std::move(ULEBSizeErr
)),
926 std::move(MetadataDecodeErr
));
927 return FunctionEntries
;
930 template <class ELFT
>
931 Expected
<std::vector
<BBAddrMap
>>
932 ELFFile
<ELFT
>::decodeBBAddrMap(const Elf_Shdr
&Sec
, const Elf_Shdr
*RelaSec
,
933 std::vector
<PGOAnalysisMap
> *PGOAnalyses
) const {
934 size_t OriginalPGOSize
= PGOAnalyses
? PGOAnalyses
->size() : 0;
935 auto AddrMapsOrErr
= decodeBBAddrMapImpl(*this, Sec
, RelaSec
, PGOAnalyses
);
936 // remove new analyses when an error occurs
937 if (!AddrMapsOrErr
&& PGOAnalyses
)
938 PGOAnalyses
->resize(OriginalPGOSize
);
939 return std::move(AddrMapsOrErr
);
942 template <class ELFT
>
944 MapVector
<const typename
ELFT::Shdr
*, const typename
ELFT::Shdr
*>>
945 ELFFile
<ELFT
>::getSectionAndRelocations(
946 std::function
<Expected
<bool>(const Elf_Shdr
&)> IsMatch
) const {
947 MapVector
<const Elf_Shdr
*, const Elf_Shdr
*> SecToRelocMap
;
948 Error Errors
= Error::success();
949 for (const Elf_Shdr
&Sec
: cantFail(this->sections())) {
950 Expected
<bool> DoesSectionMatch
= IsMatch(Sec
);
951 if (!DoesSectionMatch
) {
952 Errors
= joinErrors(std::move(Errors
), DoesSectionMatch
.takeError());
955 if (*DoesSectionMatch
) {
956 if (SecToRelocMap
.insert(std::make_pair(&Sec
, (const Elf_Shdr
*)nullptr))
961 if (Sec
.sh_type
!= ELF::SHT_RELA
&& Sec
.sh_type
!= ELF::SHT_REL
)
964 Expected
<const Elf_Shdr
*> RelSecOrErr
= this->getSection(Sec
.sh_info
);
966 Errors
= joinErrors(std::move(Errors
),
967 createError(describe(*this, Sec
) +
968 ": failed to get a relocated section: " +
969 toString(RelSecOrErr
.takeError())));
972 const Elf_Shdr
*ContentsSec
= *RelSecOrErr
;
973 Expected
<bool> DoesRelTargetMatch
= IsMatch(*ContentsSec
);
974 if (!DoesRelTargetMatch
) {
975 Errors
= joinErrors(std::move(Errors
), DoesRelTargetMatch
.takeError());
978 if (*DoesRelTargetMatch
)
979 SecToRelocMap
[ContentsSec
] = &Sec
;
982 return std::move(Errors
);
983 return SecToRelocMap
;
986 template class LLVM_EXPORT_TEMPLATE
llvm::object::ELFFile
<ELF32LE
>;
987 template class LLVM_EXPORT_TEMPLATE
llvm::object::ELFFile
<ELF32BE
>;
988 template class LLVM_EXPORT_TEMPLATE
llvm::object::ELFFile
<ELF64LE
>;
989 template class LLVM_EXPORT_TEMPLATE
llvm::object::ELFFile
<ELF64BE
>;