Go to the documentation of this file.
16 #define STRINGIFY_ENUM_CASE(ns, name) \
20 #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
27 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
35 #include "llvm/BinaryFormat/ELFRelocs/i386.def"
42 #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
49 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
56 #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
64 #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
71 #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
78 #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
85 #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
92 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
99 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
106 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
113 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
122 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
129 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
136 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
143 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
150 #include "llvm/BinaryFormat/ELFRelocs/VE.def"
157 #include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
173 return ELF::R_X86_64_RELATIVE;
176 return ELF::R_386_RELATIVE;
180 return ELF::R_AARCH64_RELATIVE;
182 return ELF::R_ARM_RELATIVE;
185 return ELF::R_ARC_RELATIVE;
189 return ELF::R_HEX_RELATIVE;
195 return ELF::R_PPC64_RELATIVE;
197 return ELF::R_RISCV_RELATIVE;
199 return ELF::R_390_RELATIVE;
203 return ELF::R_SPARC_RELATIVE;
205 return ELF::R_CKCORE_RELATIVE;
290 template <
class ELFT>
291 std::vector<typename ELFT::Rel>
325 Rel.setType(getRelativeRelocationType(),
false);
326 std::vector<Elf_Rel> Relocs;
332 const size_t WordSize =
sizeof(
Word);
336 const size_t NBits = 8*WordSize - 1;
339 for (
const Elf_Relr &R : relrs) {
341 if ((Entry&1) == 0) {
343 Rel.r_offset = Entry;
344 Relocs.push_back(Rel);
346 Base = Entry + WordSize;
354 if ((Entry&1) != 0) {
356 Relocs.push_back(Rel);
362 Base += NBits * WordSize;
368 template <
class ELFT>
379 return createError(
"invalid packed relocation header");
383 uint64_t NumRelocs =
Data.getSLEB128(Cur);
390 std::vector<Elf_Rela> Relocs;
391 Relocs.reserve(NumRelocs);
393 uint64_t NumRelocsInGroup =
Data.getSLEB128(Cur);
396 if (NumRelocsInGroup > NumRelocs)
397 return createError(
"relocation group unexpectedly large");
398 NumRelocs -= NumRelocsInGroup;
400 uint64_t GroupFlags =
Data.getSLEB128(Cur);
406 uint64_t GroupOffsetDelta;
407 if (GroupedByOffsetDelta)
408 GroupOffsetDelta =
Data.getSLEB128(Cur);
412 GroupRInfo =
Data.getSLEB128(Cur);
414 if (GroupedByAddend && GroupHasAddend)
415 Addend +=
Data.getSLEB128(Cur);
420 for (uint64_t
I = 0; Cur &&
I != NumRelocsInGroup; ++
I) {
422 Offset += GroupedByOffsetDelta ? GroupOffsetDelta :
Data.getSLEB128(Cur);
424 R.r_info = GroupedByInfo ? GroupRInfo :
Data.getSLEB128(Cur);
425 if (GroupHasAddend && !GroupedByAddend)
426 Addend +=
Data.getSLEB128(Cur);
437 template <
class ELFT>
439 uint64_t
Type)
const {
440 #define DYNAMIC_STRINGIFY_ENUM(tag, value) \
444 #define DYNAMIC_TAG(n, v)
448 #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
449 #include "llvm/BinaryFormat/DynamicTags.def"
450 #undef AARCH64_DYNAMIC_TAG
456 #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
457 #include "llvm/BinaryFormat/DynamicTags.def"
458 #undef HEXAGON_DYNAMIC_TAG
464 #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
465 #include "llvm/BinaryFormat/DynamicTags.def"
466 #undef MIPS_DYNAMIC_TAG
472 #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
473 #include "llvm/BinaryFormat/DynamicTags.def"
474 #undef PPC64_DYNAMIC_TAG
481 #define AARCH64_DYNAMIC_TAG(name, value)
482 #define MIPS_DYNAMIC_TAG(name, value)
483 #define HEXAGON_DYNAMIC_TAG(name, value)
484 #define PPC64_DYNAMIC_TAG(name, value)
486 #define DYNAMIC_TAG_MARKER(name, value)
487 #define DYNAMIC_TAG(name, value) case value: return #name;
488 #include "llvm/BinaryFormat/DynamicTags.def"
490 #undef AARCH64_DYNAMIC_TAG
491 #undef MIPS_DYNAMIC_TAG
492 #undef HEXAGON_DYNAMIC_TAG
493 #undef PPC64_DYNAMIC_TAG
494 #undef DYNAMIC_TAG_MARKER
495 #undef DYNAMIC_STRINGIFY_ENUM
497 return "<unknown:>0x" + utohexstr(
Type,
true);
501 template <
class ELFT>
503 return getDynamicTagAsString(getHeader().e_machine,
Type);
506 template <
class ELFT>
510 auto ProgramHeadersOrError = program_headers();
511 if (!ProgramHeadersOrError)
512 return ProgramHeadersOrError.takeError();
514 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
517 reinterpret_cast<const Elf_Dyn *
>(
base() + Phdr.p_offset),
518 Phdr.p_filesz /
sizeof(Elf_Dyn));
526 auto SectionsOrError = sections();
527 if (!SectionsOrError)
528 return SectionsOrError.takeError();
530 for (
const Elf_Shdr &Sec : *SectionsOrError) {
533 getSectionContentsAsArray<Elf_Dyn>(Sec);
547 return createError(
"invalid empty dynamic section");
549 if (Dyn.
back().d_tag != ELF::DT_NULL)
551 return createError(
"dynamic sections must be DT_NULL terminated");
556 template <
class ELFT>
559 auto ProgramHeadersOrError = program_headers();
560 if (!ProgramHeadersOrError)
561 return ProgramHeadersOrError.takeError();
565 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError)
567 LoadSegments.push_back(
const_cast<Elf_Phdr *
>(&Phdr));
571 return A->p_vaddr <
B->p_vaddr;
575 WarnHandler(
"loadable segments are unsorted by virtual address"))
582 return VAddr < Phdr->p_vaddr;
585 if (
I == LoadSegments.begin())
586 return createError(
"virtual address is not in any segment: 0x" +
589 const Elf_Phdr &Phdr = **
I;
590 uint64_t Delta = VAddr - Phdr.p_vaddr;
591 if (Delta >= Phdr.p_filesz)
592 return createError(
"virtual address is not in any segment: 0x" +
595 uint64_t
Offset = Phdr.p_offset + Delta;
596 if (
Offset >= getBufSize())
597 return createError(
"can't map virtual address 0x" +
599 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
600 ": the segment ends at 0x" +
602 ", which is greater than the file size (0x" +
@ SHT_LLVM_LINKER_OPTIONS
This class represents lattice values for constants.
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static Error createError(const Twine &Err)
The instances of the Type class are immutable: once they are created, they are never changed.
#define STRINGIFY_ENUM_CASE(ns, name)
Tagged union holding either a T or a Error.
bool empty() const
empty - Check if the array is empty.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint
const T & back() const
back - Get the last element.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
@ RELOCATION_GROUP_HAS_ADDEND_FLAG
@ SHT_LLVM_DEPENDENT_LIBRARIES
An efficient, type-erasing, non-owning reference to a callable.
@ RELOCATION_GROUPED_BY_ADDEND_FLAG
@ SHT_LLVM_CALL_GRAPH_PROFILE
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
bar al al movzbl eax ret Missed when stored in a memory object
static Twine utohexstr(const uint64_t &Val)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
Expected< Elf_Dyn_Range > dynamicEntries() const
therefore end up llgh r3 lr r0 br r14 but truncating the load would lh r3 br r14 Functions ret i64 and ought to be implemented ngr r0 br r14 but two address optimizations reverse the order of the AND and ngr r2 lgr r0 br r14 CodeGen SystemZ and ll has several examples of this Out of range displacements are usually handled by loading the full address into a register In many cases it would be better to create an anchor point instead E g i64 base
support::ulittle32_t Word
StringRef - Represent a constant reference to a string, i.e.
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void stable_sort(R &&Range)
@ RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
Lightweight error class with error context and mandatory checking.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
uint32_t getELFRelativeRelocationType(uint32_t Machine)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Error takeError()
Take ownership of the stored error.
COFF::MachineTypes Machine
std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const
@ RELOCATION_GROUPED_BY_INFO_FLAG