16 #define STRINGIFY_ENUM_CASE(ns, name) \
20 #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
27 #include "llvm/BinaryFormat/ELFRelocs/M68k.def"
34 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
42 #include "llvm/BinaryFormat/ELFRelocs/i386.def"
49 #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
56 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
63 #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
71 #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
78 #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
85 #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
92 #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
99 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
106 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
113 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
120 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
129 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
136 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
143 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
150 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
157 #include "llvm/BinaryFormat/ELFRelocs/VE.def"
164 #include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
171 #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
187 return ELF::R_X86_64_RELATIVE;
190 return ELF::R_386_RELATIVE;
194 return ELF::R_AARCH64_RELATIVE;
196 return ELF::R_ARM_RELATIVE;
199 return ELF::R_ARC_RELATIVE;
203 return ELF::R_HEX_RELATIVE;
209 return ELF::R_PPC64_RELATIVE;
211 return ELF::R_RISCV_RELATIVE;
213 return ELF::R_390_RELATIVE;
217 return ELF::R_SPARC_RELATIVE;
219 return ELF::R_CKCORE_RELATIVE;
221 return ELF::R_VE_RELATIVE;
309 template <
class ELFT>
310 std::vector<typename ELFT::Rel>
344 Rel.setType(getRelativeRelocationType(),
false);
345 std::vector<Elf_Rel> Relocs;
351 for (Elf_Relr R : relrs) {
353 if ((Entry & 1) == 0) {
355 Rel.r_offset = Entry;
356 Relocs.push_back(Rel);
361 for (
Addr Offset =
Base; (Entry >>= 1) != 0; Offset +=
sizeof(
Addr))
362 if ((Entry & 1) != 0) {
363 Rel.r_offset = Offset;
364 Relocs.push_back(Rel);
366 Base += (CHAR_BIT *
sizeof(Entry) - 1) *
sizeof(
Addr);
373 template <
class ELFT>
384 return createError(
"invalid packed relocation header");
395 std::vector<Elf_Rela> Relocs;
396 Relocs.reserve(NumRelocs);
401 if (NumRelocsInGroup > NumRelocs)
402 return createError(
"relocation group unexpectedly large");
403 NumRelocs -= NumRelocsInGroup;
412 if (GroupedByOffsetDelta)
413 GroupOffsetDelta =
Data.getSLEB128(Cur);
417 GroupRInfo =
Data.getSLEB128(Cur);
419 if (GroupedByAddend && GroupHasAddend)
420 Addend +=
Data.getSLEB128(Cur);
425 for (
uint64_t I = 0; Cur &&
I != NumRelocsInGroup; ++
I) {
427 Offset += GroupedByOffsetDelta ? GroupOffsetDelta :
Data.getSLEB128(Cur);
429 R.r_info = GroupedByInfo ? GroupRInfo :
Data.getSLEB128(Cur);
430 if (GroupHasAddend && !GroupedByAddend)
431 Addend +=
Data.getSLEB128(Cur);
442 template <
class ELFT>
445 #define DYNAMIC_STRINGIFY_ENUM(tag, value) \
449 #define DYNAMIC_TAG(n, v)
453 #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
454 #include "llvm/BinaryFormat/DynamicTags.def"
455 #undef AARCH64_DYNAMIC_TAG
461 #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
462 #include "llvm/BinaryFormat/DynamicTags.def"
463 #undef HEXAGON_DYNAMIC_TAG
469 #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
470 #include "llvm/BinaryFormat/DynamicTags.def"
471 #undef MIPS_DYNAMIC_TAG
477 #define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
478 #include "llvm/BinaryFormat/DynamicTags.def"
479 #undef PPC_DYNAMIC_TAG
485 #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
486 #include "llvm/BinaryFormat/DynamicTags.def"
487 #undef PPC64_DYNAMIC_TAG
493 #define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
494 #include "llvm/BinaryFormat/DynamicTags.def"
495 #undef RISCV_DYNAMIC_TAG
502 #define AARCH64_DYNAMIC_TAG(name, value)
503 #define MIPS_DYNAMIC_TAG(name, value)
504 #define HEXAGON_DYNAMIC_TAG(name, value)
505 #define PPC_DYNAMIC_TAG(name, value)
506 #define PPC64_DYNAMIC_TAG(name, value)
507 #define RISCV_DYNAMIC_TAG(name, value)
509 #define DYNAMIC_TAG_MARKER(name, value)
510 #define DYNAMIC_TAG(name, value) case value: return #name;
511 #include "llvm/BinaryFormat/DynamicTags.def"
513 #undef AARCH64_DYNAMIC_TAG
514 #undef MIPS_DYNAMIC_TAG
515 #undef HEXAGON_DYNAMIC_TAG
516 #undef PPC_DYNAMIC_TAG
517 #undef PPC64_DYNAMIC_TAG
518 #undef RISCV_DYNAMIC_TAG
519 #undef DYNAMIC_TAG_MARKER
520 #undef DYNAMIC_STRINGIFY_ENUM
522 return "<unknown:>0x" + utohexstr(
Type,
true);
526 template <
class ELFT>
528 return getDynamicTagAsString(getHeader().e_machine,
Type);
531 template <
class ELFT>
535 auto ProgramHeadersOrError = program_headers();
536 if (!ProgramHeadersOrError)
537 return ProgramHeadersOrError.takeError();
539 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
542 reinterpret_cast<const Elf_Dyn *
>(
base() + Phdr.p_offset),
543 Phdr.p_filesz /
sizeof(Elf_Dyn));
551 auto SectionsOrError = sections();
552 if (!SectionsOrError)
553 return SectionsOrError.takeError();
555 for (
const Elf_Shdr &Sec : *SectionsOrError) {
558 getSectionContentsAsArray<Elf_Dyn>(Sec);
571 return createError(
"invalid empty dynamic section");
573 if (Dyn.
back().d_tag != ELF::DT_NULL)
574 return createError(
"dynamic sections must be DT_NULL terminated");
579 template <
class ELFT>
582 auto ProgramHeadersOrError = program_headers();
583 if (!ProgramHeadersOrError)
584 return ProgramHeadersOrError.takeError();
588 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError)
590 LoadSegments.push_back(
const_cast<Elf_Phdr *
>(&Phdr));
594 return A->p_vaddr <
B->p_vaddr;
598 WarnHandler(
"loadable segments are unsorted by virtual address"))
605 return VAddr < Phdr->p_vaddr;
608 if (
I == LoadSegments.begin())
609 return createError(
"virtual address is not in any segment: 0x" +
612 const Elf_Phdr &Phdr = **
I;
613 uint64_t Delta = VAddr - Phdr.p_vaddr;
614 if (Delta >= Phdr.p_filesz)
615 return createError(
"virtual address is not in any segment: 0x" +
618 uint64_t Offset = Phdr.p_offset + Delta;
619 if (Offset >= getBufSize())
620 return createError(
"can't map virtual address 0x" +
622 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
623 ": the segment ends at 0x" +
625 ", which is greater than the file size (0x" +
628 return base() + Offset;
631 template <
class ELFT>
639 std::vector<BBAddrMap> FunctionEntries;
648 auto ReadULEB128AsUInt32 = [&
Data, &Cur, &ULEBSizeErr]() ->
uint32_t {
654 if (
Value > UINT32_MAX) {
663 while (!ULEBSizeErr && Cur && Cur.tell() <
Content.size()) {
664 uintX_t Address =
static_cast<uintX_t
>(
Data.getAddress(Cur));
665 uint32_t NumBlocks = ReadULEB128AsUInt32();
666 std::vector<BBAddrMap::BBEntry> BBEntries;
667 for (
uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks);
669 uint32_t Offset = ReadULEB128AsUInt32();
670 uint32_t Size = ReadULEB128AsUInt32();
672 BBEntries.push_back({Offset, Size,
Metadata});
674 FunctionEntries.push_back({Address, BBEntries});
678 if (!Cur || ULEBSizeErr)
680 return FunctionEntries;