14using namespace object;
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"
178#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
194 return ELF::R_X86_64_RELATIVE;
197 return ELF::R_386_RELATIVE;
201 return ELF::R_AARCH64_RELATIVE;
203 return ELF::R_ARM_RELATIVE;
206 return ELF::R_ARC_RELATIVE;
210 return ELF::R_HEX_RELATIVE;
216 return ELF::R_PPC64_RELATIVE;
218 return ELF::R_RISCV_RELATIVE;
220 return ELF::R_390_RELATIVE;
224 return ELF::R_SPARC_RELATIVE;
226 return ELF::R_CKCORE_RELATIVE;
228 return ELF::R_VE_RELATIVE;
234 return ELF::R_LARCH_RELATIVE;
326std::vector<typename ELFT::Rel>
360 Rel.setType(getRelativeRelocationType(),
false);
361 std::vector<Elf_Rel> Relocs;
364 using Addr =
typename ELFT::uint;
367 for (Elf_Relr R : relrs) {
368 typename ELFT::uint Entry = R;
369 if ((Entry & 1) == 0) {
371 Rel.r_offset = Entry;
372 Relocs.push_back(Rel);
378 if ((Entry & 1) != 0) {
380 Relocs.push_back(Rel);
382 Base += (CHAR_BIT *
sizeof(Entry) - 1) *
sizeof(
Addr);
400 return createError(
"invalid packed relocation header");
411 std::vector<Elf_Rela> Relocs;
412 Relocs.reserve(NumRelocs);
417 if (NumRelocsInGroup > NumRelocs)
418 return createError(
"relocation group unexpectedly large");
419 NumRelocs -= NumRelocsInGroup;
428 if (GroupedByOffsetDelta)
429 GroupOffsetDelta =
Data.getSLEB128(Cur);
433 GroupRInfo =
Data.getSLEB128(Cur);
435 if (GroupedByAddend && GroupHasAddend)
436 Addend +=
Data.getSLEB128(Cur);
441 for (
uint64_t I = 0; Cur &&
I != NumRelocsInGroup; ++
I) {
443 Offset += GroupedByOffsetDelta ? GroupOffsetDelta :
Data.getSLEB128(Cur);
445 R.r_info = GroupedByInfo ? GroupRInfo :
Data.getSLEB128(Cur);
446 if (GroupHasAddend && !GroupedByAddend)
447 Addend +=
Data.getSLEB128(Cur);
461#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
465#define DYNAMIC_TAG(n, v)
469#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
470#include "llvm/BinaryFormat/DynamicTags.def"
471#undef AARCH64_DYNAMIC_TAG
477#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
478#include "llvm/BinaryFormat/DynamicTags.def"
479#undef HEXAGON_DYNAMIC_TAG
485#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
486#include "llvm/BinaryFormat/DynamicTags.def"
487#undef MIPS_DYNAMIC_TAG
493#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
494#include "llvm/BinaryFormat/DynamicTags.def"
495#undef PPC_DYNAMIC_TAG
501#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
502#include "llvm/BinaryFormat/DynamicTags.def"
503#undef PPC64_DYNAMIC_TAG
509#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
510#include "llvm/BinaryFormat/DynamicTags.def"
511#undef RISCV_DYNAMIC_TAG
518#define AARCH64_DYNAMIC_TAG(name, value)
519#define MIPS_DYNAMIC_TAG(name, value)
520#define HEXAGON_DYNAMIC_TAG(name, value)
521#define PPC_DYNAMIC_TAG(name, value)
522#define PPC64_DYNAMIC_TAG(name, value)
523#define RISCV_DYNAMIC_TAG(name, value)
525#define DYNAMIC_TAG_MARKER(name, value)
526#define DYNAMIC_TAG(name, value) case value: return #name;
527#include "llvm/BinaryFormat/DynamicTags.def"
529#undef AARCH64_DYNAMIC_TAG
530#undef MIPS_DYNAMIC_TAG
531#undef HEXAGON_DYNAMIC_TAG
532#undef PPC_DYNAMIC_TAG
533#undef PPC64_DYNAMIC_TAG
534#undef RISCV_DYNAMIC_TAG
535#undef DYNAMIC_TAG_MARKER
536#undef DYNAMIC_STRINGIFY_ENUM
538 return "<unknown:>0x" + utohexstr(
Type,
true);
544 return getDynamicTagAsString(getHeader().e_machine,
Type);
551 auto ProgramHeadersOrError = program_headers();
552 if (!ProgramHeadersOrError)
553 return ProgramHeadersOrError.takeError();
555 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
557 Dyn =
ArrayRef(
reinterpret_cast<const Elf_Dyn *
>(base() + Phdr.p_offset),
558 Phdr.p_filesz /
sizeof(Elf_Dyn));
566 auto SectionsOrError = sections();
567 if (!SectionsOrError)
568 return SectionsOrError.takeError();
570 for (
const Elf_Shdr &Sec : *SectionsOrError) {
573 getSectionContentsAsArray<Elf_Dyn>(Sec);
586 return createError(
"invalid empty dynamic section");
588 if (Dyn.
back().d_tag != ELF::DT_NULL)
589 return createError(
"dynamic sections must be DT_NULL terminated");
597 auto ProgramHeadersOrError = program_headers();
598 if (!ProgramHeadersOrError)
599 return ProgramHeadersOrError.takeError();
603 for (
const Elf_Phdr &Phdr : *ProgramHeadersOrError)
605 LoadSegments.
push_back(
const_cast<Elf_Phdr *
>(&Phdr));
609 return A->p_vaddr <
B->p_vaddr;
613 WarnHandler(
"loadable segments are unsorted by virtual address"))
620 return VAddr < Phdr->p_vaddr;
623 if (
I == LoadSegments.
begin())
624 return createError(
"virtual address is not in any segment: 0x" +
627 const Elf_Phdr &Phdr = **
I;
628 uint64_t Delta = VAddr - Phdr.p_vaddr;
629 if (Delta >= Phdr.p_filesz)
630 return createError(
"virtual address is not in any segment: 0x" +
634 if (
Offset >= getBufSize())
635 return createError(
"can't map virtual address 0x" +
637 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
638 ": the segment ends at 0x" +
640 ", which is greater than the file size (0x" +
649 const Elf_Shdr *RelaSec)
const {
650 bool IsRelocatable = getHeader().e_type ==
ELF::ET_REL;
656 if (IsRelocatable && RelaSec) {
658 "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
659 "object file without providing a relocation section.");
662 return createError(
"unable to read relocations for section " +
665 for (Elf_Rela Rela : *Relas)
666 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
673 std::vector<BBAddrMap> FunctionEntries;
682 auto ReadULEB128AsUInt32 = [&
Data, &Cur, &ULEBSizeErr]() ->
uint32_t {
688 if (
Value > UINT32_MAX) {
698 while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
701 Version =
Data.getU8(Cur);
705 return createError(
"unsupported SHT_LLVM_BB_ADDR_MAP version: " +
706 Twine(
static_cast<int>(Version)));
710 uintX_t Address =
static_cast<uintX_t
>(
Data.getAddress(Cur));
715 auto FOTIterator = FunctionOffsetTranslations.
find(SectionOffset);
716 if (FOTIterator == FunctionOffsetTranslations.
end()) {
717 return createError(
"failed to get relocation data for offset: " +
721 Address = FOTIterator->second;
723 uint32_t NumBlocks = ReadULEB128AsUInt32();
724 std::vector<BBAddrMap::BBEntry> BBEntries;
727 !MetadataDecodeErr && !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
729 uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex;
732 uint32_t MD = ReadULEB128AsUInt32();
735 Offset += PrevBBEndOffset;
740 if (!MetadataOrErr) {
741 MetadataDecodeErr = MetadataOrErr.
takeError();
744 BBEntries.push_back({
ID,
Offset,
Size, *MetadataOrErr});
746 FunctionEntries.push_back({Address, std::move(BBEntries)});
750 if (!Cur || ULEBSizeErr || MetadataDecodeErr)
752 std::move(MetadataDecodeErr));
753 return FunctionEntries;
763 for (
const Elf_Shdr &Sec :
cantFail(this->sections())) {
765 if (!DoesSectionMatch) {
769 if (*DoesSectionMatch) {
770 if (SecToRelocMap.
insert(std::make_pair(&Sec, (
const Elf_Shdr *)
nullptr))
782 ": failed to get a relocated section: " +
786 const Elf_Shdr *ContentsSec = *RelSecOrErr;
788 if (!DoesRelTargetMatch) {
792 if (*DoesRelTargetMatch)
793 SecToRelocMap[ContentsSec] = &Sec;
796 return std::move(Errors);
797 return SecToRelocMap;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define STRINGIFY_ENUM_CASE(ns, name)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
bool empty() const
empty - Check if the array is empty.
iterator find(const_arg_type_t< KeyT > Val)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Expected< std::vector< BBAddrMap > > decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec=nullptr) const
Returns a vector of BBAddrMap structs corresponding to each function within the text section that the...
Expected< Elf_Dyn_Range > dynamicEntries() const
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
Expected< MapVector< const Elf_Shdr *, const Elf_Shdr * > > getSectionAndRelocations(std::function< Expected< bool >(const Elf_Shdr &)> IsMatch) const
Returns a map from every section matching IsMatch to its relocation section, or nullptr if it has no ...
std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
@ RELOCATION_GROUPED_BY_INFO_FLAG
@ RELOCATION_GROUPED_BY_ADDEND_FLAG
@ RELOCATION_GROUP_HAS_ADDEND_FLAG
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Error createError(const Twine &Err)
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
uint32_t getELFRelativeRelocationType(uint32_t Machine)
static std::string describe(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Error joinErrors(Error E1, Error E2)
Concatenate errors.
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...
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
static Expected< Metadata > decode(uint32_t V)