17 #define STRINGIFY_ENUM_CASE(ns, name) \ 21 #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name) 28 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" 36 #include "llvm/BinaryFormat/ELFRelocs/i386.def" 43 #include "llvm/BinaryFormat/ELFRelocs/Mips.def" 50 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" 57 #include "llvm/BinaryFormat/ELFRelocs/ARM.def" 65 #include "llvm/BinaryFormat/ELFRelocs/ARC.def" 72 #include "llvm/BinaryFormat/ELFRelocs/AVR.def" 79 #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" 86 #include "llvm/BinaryFormat/ELFRelocs/Lanai.def" 93 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def" 100 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" 107 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def" 114 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def" 123 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" 130 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" 137 #include "llvm/BinaryFormat/ELFRelocs/BPF.def" 144 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def" 160 return ELF::R_X86_64_RELATIVE;
163 return ELF::R_386_RELATIVE;
167 return ELF::R_AARCH64_RELATIVE;
169 return ELF::R_ARM_RELATIVE;
172 return ELF::R_ARC_RELATIVE;
176 return ELF::R_HEX_RELATIVE;
182 return ELF::R_PPC64_RELATIVE;
184 return ELF::R_RISCV_RELATIVE;
186 return ELF::R_390_RELATIVE;
190 return ELF::R_SPARC_RELATIVE;
267 template <
class ELFT>
303 Rela.setType(getRelativeRelocationType(),
false);
304 std::vector<Elf_Rela> Relocs;
307 typedef typename ELFT::uint
Word;
310 const size_t WordSize =
sizeof(
Word);
314 const size_t NBits = 8*WordSize - 1;
319 if ((Entry&1) == 0) {
321 Rela.r_offset = Entry;
322 Relocs.push_back(Rela);
324 Base = Entry + WordSize;
332 if ((Entry&1) != 0) {
334 Relocs.push_back(Rela);
340 Base += NBits * WordSize;
346 template <
class ELFT>
354 const uint8_t *Cur = ContentsOrErr->begin();
355 const uint8_t *End = ContentsOrErr->end();
356 if (ContentsOrErr->size() < 4 || Cur[0] !=
'A' || Cur[1] !=
'P' ||
357 Cur[2] !=
'S' || Cur[3] !=
'2')
358 return createError(
"invalid packed relocation header");
361 const char *ErrStr =
nullptr;
362 auto ReadSLEB = [&]() -> int64_t {
371 uint64_t NumRelocs = ReadSLEB();
372 uint64_t
Offset = ReadSLEB();
378 std::vector<Elf_Rela> Relocs;
379 Relocs.reserve(NumRelocs);
381 uint64_t NumRelocsInGroup = ReadSLEB();
382 if (NumRelocsInGroup > NumRelocs)
383 return createError(
"relocation group unexpectedly large");
384 NumRelocs -= NumRelocsInGroup;
386 uint64_t GroupFlags = ReadSLEB();
392 uint64_t GroupOffsetDelta;
393 if (GroupedByOffsetDelta)
394 GroupOffsetDelta = ReadSLEB();
398 GroupRInfo = ReadSLEB();
400 if (GroupedByAddend && GroupHasAddend)
401 Addend += ReadSLEB();
406 for (uint64_t
I = 0;
I != NumRelocsInGroup; ++
I) {
408 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
410 R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
411 if (GroupHasAddend && !GroupedByAddend)
412 Addend += ReadSLEB();
427 template <
class ELFT>
429 uint64_t Type)
const {
430 #define DYNAMIC_STRINGIFY_ENUM(tag, value) \ 434 #define DYNAMIC_TAG(n, v) 438 #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 439 #include "llvm/BinaryFormat/DynamicTags.def" 440 #undef HEXAGON_DYNAMIC_TAG 445 #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 446 #include "llvm/BinaryFormat/DynamicTags.def" 447 #undef MIPS_DYNAMIC_TAG 452 #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 453 #include "llvm/BinaryFormat/DynamicTags.def" 454 #undef PPC64_DYNAMIC_TAG 460 #define MIPS_DYNAMIC_TAG(name, value) 461 #define HEXAGON_DYNAMIC_TAG(name, value) 462 #define PPC64_DYNAMIC_TAG(name, value) 464 #define DYNAMIC_TAG_MARKER(name, value) 465 #define DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) 466 #include "llvm/BinaryFormat/DynamicTags.def" 468 #undef MIPS_DYNAMIC_TAG 469 #undef HEXAGON_DYNAMIC_TAG 470 #undef PPC64_DYNAMIC_TAG 471 #undef DYNAMIC_TAG_MARKER 472 #undef DYNAMIC_STRINGIFY_ENUM 478 template <
class ELFT>
480 return getDynamicTagAsString(getHeader()->e_machine, Type);
483 template <
class ELFT>
486 size_t DynSecSize = 0;
488 auto ProgramHeadersOrError = program_headers();
489 if (!ProgramHeadersOrError)
490 return ProgramHeadersOrError.takeError();
492 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
495 reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset),
496 Phdr.p_filesz /
sizeof(
Elf_Dyn));
497 DynSecSize = Phdr.p_filesz;
505 auto SectionsOrError = sections();
506 if (!SectionsOrError)
507 return SectionsOrError.takeError();
509 for (
const Elf_Shdr &Sec : *SectionsOrError) {
512 getSectionContentsAsArray<Elf_Dyn>(&Sec);
516 DynSecSize = Sec.sh_size;
526 return createError(
"invalid empty dynamic section");
528 if (DynSecSize %
sizeof(
Elf_Dyn) != 0)
531 if (Dyn.
back().d_tag != ELF::DT_NULL)
532 return createError(
"dynamic sections must be DT_NULL terminated");
537 template <
class ELFT>
539 auto ProgramHeadersOrError = program_headers();
540 if (!ProgramHeadersOrError)
541 return ProgramHeadersOrError.takeError();
545 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError)
547 LoadSegments.
push_back(const_cast<Elf_Phdr *>(&Phdr));
552 return VAddr < Phdr->p_vaddr;
555 if (I == LoadSegments.
begin())
556 return createError(
"Virtual address is not in any segment");
559 uint64_t Delta = VAddr - Phdr.p_vaddr;
560 if (Delta >= Phdr.p_filesz)
561 return createError(
"Virtual address is not in any segment");
562 return base() + Phdr.p_offset + Delta;
typename ELFT::Dyn Elf_Dyn
const T & back() const
back - Get the last element.
This class represents lattice values for constants.
void push_back(const T &Elt)
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
const char * getDynamicTagAsString(unsigned Arch, uint64_t Type) const
static Error createError(StringRef Err)
Expected< std::vector< Elf_Rela > > decode_relrs(Elf_Relr_Range relrs) const
Error takeError()
Take ownership of the stored error.
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr) const
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
support::ulittle32_t Word
typename ELFT::Phdr Elf_Phdr
Tagged union holding either a T or a Error.
uint32_t getELFRelativeRelocationType(uint32_t Machine)
typename ELFT::Relr Elf_Relr
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
COFF::MachineTypes Machine
The instances of the Type class are immutable: once they are created, they are never changed...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
typename ELFT::RelrRange Elf_Relr_Range
typename ELFT::Rela Elf_Rela
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
#define STRINGIFY_ENUM_CASE(ns, name)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr *Sec) const
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Expected< Elf_Dyn_Range > dynamicEntries() const
StringRef - Represent a constant reference to a string, i.e.
typename ELFT::Shdr Elf_Shdr
bool empty() const
empty - Check if the array is empty.