29 using namespace llvm::object;
31 #define DEBUG_TYPE "dyld"
33 static inline std::error_code
check(std::error_code Err) {
42 template <
class ELFT>
class DyldELFObject :
public ELFObjectFile<ELFT> {
78 DyldELFObject<ELFT>::DyldELFObject(
MemoryBufferRef Wrapper, std::error_code &EC)
80 this->isDyldELFObject =
true;
84 void DyldELFObject<ELFT>::updateSectionAddress(
const SectionRef &Sec,
88 const_cast<Elf_Shdr *
>(
reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
92 shdr->sh_addr =
static_cast<addr_type
>(Addr);
96 void DyldELFObject<ELFT>::updateSymbolAddress(
const SymbolRef &SymRef,
99 Elf_Sym *sym =
const_cast<Elf_Sym *
>(
104 sym->st_value =
static_cast<addr_type
>(Addr);
107 class LoadedELFObjectInfo
112 : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
118 template <
typename ELFT>
119 std::unique_ptr<DyldELFObject<ELFT>>
121 const LoadedELFObjectInfo &L,
122 std::error_code &ec) {
126 std::unique_ptr<DyldELFObject<ELFT>> Obj =
127 llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
130 for (
const auto &Sec : Obj->sections()) {
133 if (SectionName !=
"") {
135 Elf_Shdr *shdr =
const_cast<Elf_Shdr *
>(
136 reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
138 if (uint64_t SecLoadAddr = L.getSectionLoadAddress(SectionName)) {
141 shdr->sh_addr =
static_cast<addr_type
>(SecLoadAddr);
150 const LoadedELFObjectInfo &L) {
151 assert(Obj.
isELF() &&
"Not an ELF object file.");
153 std::unique_ptr<MemoryBuffer> Buffer =
158 std::unique_ptr<ObjectFile> DebugObj;
161 DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), L, ec);
164 DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), L, ec);
167 DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), L, ec);
170 DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), L, ec);
174 assert(!ec &&
"Could not construct copy ELF object file");
180 LoadedELFObjectInfo::getObjectForDebug(
const ObjectFile &Obj)
const {
181 return createELFDebugObject(Obj, *
this);
190 :
RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
194 for (
int i = 0, e = UnregisteredEHFrameSections.
size(); i != e; ++i) {
195 SID EHFrameSID = UnregisteredEHFrameSections[i];
196 uint8_t *EHFrameAddr =
Sections[EHFrameSID].Address;
197 uint64_t EHFrameLoadAddr =
Sections[EHFrameSID].LoadAddress;
198 size_t EHFrameSize =
Sections[EHFrameSID].Size;
200 RegisteredEHFrameSections.
push_back(EHFrameSID);
202 UnregisteredEHFrameSections.
clear();
206 for (
int i = 0, e = RegisteredEHFrameSections.
size(); i != e; ++i) {
207 SID EHFrameSID = RegisteredEHFrameSections[i];
208 uint8_t *EHFrameAddr =
Sections[EHFrameSID].Address;
209 uint64_t EHFrameLoadAddr =
Sections[EHFrameSID].LoadAddress;
210 size_t EHFrameSize =
Sections[EHFrameSID].Size;
213 RegisteredEHFrameSections.
clear();
216 std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
218 unsigned SectionStartIdx, SectionEndIdx;
220 return llvm::make_unique<LoadedELFObjectInfo>(*
this, SectionStartIdx,
225 uint64_t Offset, uint64_t
Value,
226 uint32_t
Type, int64_t Addend,
227 uint64_t SymOffset) {
232 case ELF::R_X86_64_64: {
238 case ELF::R_X86_64_32:
239 case ELF::R_X86_64_32S: {
241 assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
242 (Type == ELF::R_X86_64_32S &&
243 ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
244 uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
250 case ELF::R_X86_64_PC32: {
251 uint64_t FinalAddress = Section.
LoadAddress + Offset;
252 int64_t RealOffset = Value + Addend - FinalAddress;
254 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
258 case ELF::R_X86_64_PC64: {
259 uint64_t FinalAddress = Section.
LoadAddress + Offset;
260 int64_t RealOffset = Value + Addend - FinalAddress;
267 void RuntimeDyldELF::resolveX86Relocation(
const SectionEntry &Section,
268 uint64_t Offset, uint32_t Value,
269 uint32_t Type, int32_t Addend) {
271 case ELF::R_386_32: {
275 case ELF::R_386_PC32: {
276 uint32_t FinalAddress = ((Section.
LoadAddress + Offset) & 0xFFFFFFFF);
277 uint32_t RealOffset = Value + Addend - FinalAddress;
289 void RuntimeDyldELF::resolveAArch64Relocation(
const SectionEntry &Section,
290 uint64_t Offset, uint64_t Value,
291 uint32_t Type, int64_t Addend) {
292 uint32_t *TargetPtr =
reinterpret_cast<uint32_t *
>(Section.
Address + Offset);
293 uint64_t FinalAddress = Section.
LoadAddress + Offset;
295 DEBUG(
dbgs() <<
"resolveAArch64Relocation, LocalAddress: 0x"
297 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
298 <<
" Value: 0x" <<
format(
"%llx", Value) <<
" Type: 0x"
299 <<
format(
"%x", Type) <<
" Addend: 0x" <<
format(
"%llx", Addend)
306 case ELF::R_AARCH64_ABS64: {
307 uint64_t *TargetPtr =
308 reinterpret_cast<uint64_t *
>(Section.
Address + Offset);
309 *TargetPtr = Value + Addend;
312 case ELF::R_AARCH64_PREL32: {
313 uint64_t Result = Value + Addend - FinalAddress;
314 assert(static_cast<int64_t>(Result) >= INT32_MIN &&
315 static_cast<int64_t>(Result) <= UINT32_MAX);
316 *TargetPtr =
static_cast<uint32_t
>(Result & 0xffffffffU);
319 case ELF::R_AARCH64_CALL26:
320 case ELF::R_AARCH64_JUMP26: {
323 uint64_t BranchImm = Value + Addend - FinalAddress;
326 assert(isInt<28>(BranchImm));
330 *TargetPtr &= 0xfc000000U;
332 *TargetPtr |=
static_cast<uint32_t
>(BranchImm & 0xffffffcU) >> 2;
335 case ELF::R_AARCH64_MOVW_UABS_G3: {
336 uint64_t Result = Value + Addend;
340 *TargetPtr &= 0xffe0001fU;
342 *TargetPtr |= Result >> (48 - 5);
344 assert((*TargetPtr >> 21 & 0x3) == 3 &&
"invalid shift for relocation");
347 case ELF::R_AARCH64_MOVW_UABS_G2_NC: {
348 uint64_t Result = Value + Addend;
352 *TargetPtr &= 0xffe0001fU;
354 *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5));
356 assert((*TargetPtr >> 21 & 0x3) == 2 &&
"invalid shift for relocation");
359 case ELF::R_AARCH64_MOVW_UABS_G1_NC: {
360 uint64_t Result = Value + Addend;
364 *TargetPtr &= 0xffe0001fU;
366 *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5));
368 assert((*TargetPtr >> 21 & 0x3) == 1 &&
"invalid shift for relocation");
371 case ELF::R_AARCH64_MOVW_UABS_G0_NC: {
372 uint64_t Result = Value + Addend;
376 *TargetPtr &= 0xffe0001fU;
378 *TargetPtr |= ((Result & 0xffffU) << 5);
380 assert((*TargetPtr >> 21 & 0x3) == 0 &&
"invalid shift for relocation");
383 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
386 ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
389 assert(isInt<33>(Result) &&
"overflow check failed for relocation");
393 *TargetPtr &= 0x9f00001fU;
396 *TargetPtr |= ((Result & 0x3000U) << (29 - 12));
397 *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5));
400 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
402 uint64_t Result = Value + Addend;
406 *TargetPtr &= 0xffc003ffU;
409 *TargetPtr |= ((Result & 0xffc) << (10 - 2));
412 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
414 uint64_t Result = Value + Addend;
418 *TargetPtr &= 0xffc003ffU;
421 *TargetPtr |= ((Result & 0xff8) << (10 - 3));
427 void RuntimeDyldELF::resolveARMRelocation(
const SectionEntry &Section,
428 uint64_t Offset, uint32_t Value,
429 uint32_t Type, int32_t Addend) {
431 uint32_t *TargetPtr = (uint32_t *)(Section.
Address + Offset);
432 uint32_t FinalAddress = ((Section.
LoadAddress + Offset) & 0xFFFFFFFF);
435 DEBUG(
dbgs() <<
"resolveARMRelocation, LocalAddress: "
437 <<
" FinalAddress: " <<
format(
"%p", FinalAddress) <<
" Value: "
438 <<
format(
"%x", Value) <<
" Type: " <<
format(
"%x", Type)
439 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
445 case ELF::R_ARM_NONE:
447 case ELF::R_ARM_PREL31:
448 case ELF::R_ARM_TARGET1:
449 case ELF::R_ARM_ABS32:
454 case ELF::R_ARM_MOVW_ABS_NC:
455 case ELF::R_ARM_MOVT_ABS:
456 if (Type == ELF::R_ARM_MOVW_ABS_NC)
457 Value = Value & 0xFFFF;
458 else if (Type == ELF::R_ARM_MOVT_ABS)
459 Value = (Value >> 16) & 0xFFFF;
460 *TargetPtr &= ~0x000F0FFF;
461 *TargetPtr |= Value & 0xFFF;
462 *TargetPtr |= ((Value >> 12) & 0xF) << 16;
465 case ELF::R_ARM_PC24:
466 case ELF::R_ARM_CALL:
467 case ELF::R_ARM_JUMP24:
468 int32_t RelValue =
static_cast<int32_t
>(Value - FinalAddress - 8);
469 RelValue = (RelValue & 0x03FFFFFC) >> 2;
470 assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE);
471 *TargetPtr &= 0xFF000000;
472 *TargetPtr |= RelValue;
477 void RuntimeDyldELF::resolveMIPSRelocation(
const SectionEntry &Section,
478 uint64_t Offset, uint32_t Value,
479 uint32_t Type, int32_t Addend) {
480 uint8_t *TargetPtr = Section.
Address + Offset;
483 DEBUG(
dbgs() <<
"resolveMIPSRelocation, LocalAddress: "
484 << Section.
Address + Offset <<
" FinalAddress: "
486 <<
format(
"%x", Value) <<
" Type: " <<
format(
"%x", Type)
487 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
500 Insn |= (Value & 0x0fffffff) >> 2;
503 case ELF::R_MIPS_HI16:
506 Insn |= ((Value + 0x8000) >> 16) & 0xffff;
509 case ELF::R_MIPS_LO16:
511 Insn |= Value & 0xffff;
514 case ELF::R_MIPS_PC32: {
515 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
519 case ELF::R_MIPS_PC16: {
520 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
522 Insn |= ((Value - FinalAddress) >> 2) & 0xffff;
526 case ELF::R_MIPS_PC19_S2: {
527 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
529 Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
533 case ELF::R_MIPS_PC21_S2: {
534 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
536 Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff;
540 case ELF::R_MIPS_PC26_S2: {
541 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
543 Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff;
547 case ELF::R_MIPS_PCHI16: {
548 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
550 Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff;
554 case ELF::R_MIPS_PCLO16: {
555 uint32_t FinalAddress = (Section.
LoadAddress + Offset);
557 Insn |= (Value - FinalAddress) & 0xffff;
564 void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
579 void RuntimeDyldELF::resolveMIPS64Relocation(
const SectionEntry &Section,
580 uint64_t Offset, uint64_t Value,
581 uint32_t Type, int64_t Addend,
584 uint32_t r_type = Type & 0xff;
585 uint32_t r_type2 = (Type >> 8) & 0xff;
586 uint32_t r_type3 = (Type >> 16) & 0xff;
590 uint32_t RelType = r_type;
591 int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,
593 SymOffset, SectionID);
594 if (r_type2 != ELF::R_MIPS_NONE) {
596 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
597 CalculatedValue, SymOffset,
600 if (r_type3 != ELF::R_MIPS_NONE) {
602 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
603 CalculatedValue, SymOffset,
606 applyMIPS64Relocation(Section.
Address + Offset, CalculatedValue, RelType);
610 RuntimeDyldELF::evaluateMIPS64Relocation(
const SectionEntry &Section,
611 uint64_t Offset, uint64_t Value,
612 uint32_t Type, int64_t Addend,
613 uint64_t SymOffset, SID SectionID) {
615 DEBUG(
dbgs() <<
"evaluateMIPS64Relocation, LocalAddress: 0x"
617 <<
" FinalAddress: 0x"
619 <<
" Value: 0x" <<
format(
"%llx", Value) <<
" Type: 0x"
620 <<
format(
"%x", Type) <<
" Addend: 0x" <<
format(
"%llx", Addend)
621 <<
" SymOffset: " <<
format(
"%x", SymOffset)
628 case ELF::R_MIPS_JALR:
629 case ELF::R_MIPS_NONE:
633 return Value + Addend;
635 return ((Value + Addend) >> 2) & 0x3ffffff;
636 case ELF::R_MIPS_GPREL16: {
638 return Value + Addend - (GOTAddr + 0x7ff0);
640 case ELF::R_MIPS_SUB:
641 return Value - Addend;
642 case ELF::R_MIPS_HI16:
644 return ((Value + Addend + 0x8000) >> 16) & 0xffff;
645 case ELF::R_MIPS_LO16:
646 return (Value + Addend) & 0xffff;
647 case ELF::R_MIPS_CALL16:
648 case ELF::R_MIPS_GOT_DISP:
649 case ELF::R_MIPS_GOT_PAGE: {
650 uint8_t *LocalGOTAddr =
655 if (Type == ELF::R_MIPS_GOT_PAGE)
656 Value = (Value + 0x8000) & ~0xffff;
659 assert(GOTEntry == Value &&
660 "GOT entry has two different addresses.");
664 return (SymOffset - 0x7ff0) & 0xffff;
666 case ELF::R_MIPS_GOT_OFST: {
667 int64_t page = (Value + Addend + 0x8000) & ~0xffff;
668 return (Value + Addend - page) & 0xffff;
670 case ELF::R_MIPS_GPREL32: {
672 return Value + Addend - (GOTAddr + 0x7ff0);
674 case ELF::R_MIPS_PC16: {
675 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
676 return ((Value + Addend - FinalAddress) >> 2) & 0xffff;
678 case ELF::R_MIPS_PC32: {
679 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
680 return Value + Addend - FinalAddress;
682 case ELF::R_MIPS_PC18_S3: {
683 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
684 return ((Value + Addend - ((FinalAddress | 7) ^ 7)) >> 3) & 0x3ffff;
686 case ELF::R_MIPS_PC19_S2: {
687 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
688 return ((Value + Addend - FinalAddress) >> 2) & 0x7ffff;
690 case ELF::R_MIPS_PC21_S2: {
691 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
692 return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;
694 case ELF::R_MIPS_PC26_S2: {
695 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
696 return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
698 case ELF::R_MIPS_PCHI16: {
699 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
700 return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
702 case ELF::R_MIPS_PCLO16: {
703 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
704 return (Value + Addend - FinalAddress) & 0xffff;
710 void RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr,
711 int64_t CalculatedValue,
719 case ELF::R_MIPS_GPREL32:
720 case ELF::R_MIPS_PC32:
724 case ELF::R_MIPS_SUB:
728 case ELF::R_MIPS_PC26_S2:
729 Insn = (Insn & 0xfc000000) | CalculatedValue;
732 case ELF::R_MIPS_GPREL16:
733 Insn = (Insn & 0xffff0000) | (CalculatedValue & 0xffff);
736 case ELF::R_MIPS_HI16:
737 case ELF::R_MIPS_LO16:
738 case ELF::R_MIPS_PCHI16:
739 case ELF::R_MIPS_PCLO16:
740 case ELF::R_MIPS_PC16:
741 case ELF::R_MIPS_CALL16:
742 case ELF::R_MIPS_GOT_DISP:
743 case ELF::R_MIPS_GOT_PAGE:
744 case ELF::R_MIPS_GOT_OFST:
745 Insn = (Insn & 0xffff0000) | CalculatedValue;
748 case ELF::R_MIPS_PC18_S3:
749 Insn = (Insn & 0xfffc0000) | CalculatedValue;
752 case ELF::R_MIPS_PC19_S2:
753 Insn = (Insn & 0xfff80000) | CalculatedValue;
756 case ELF::R_MIPS_PC21_S2:
757 Insn = (Insn & 0xffe00000) | CalculatedValue;
765 ObjSectionToIDMap &LocalSections,
777 for (
auto &Section: Obj.
sections()) {
779 check(Section.getName(SectionName));
781 if (SectionName ==
".got"
782 || SectionName ==
".toc"
783 || SectionName ==
".tocbss"
784 || SectionName ==
".plt") {
798 ObjSectionToIDMap &LocalSections,
809 check(RelSecI->getName(RelSectionName));
810 if (RelSectionName !=
".opd")
814 e = si->relocation_end();
818 uint64_t TypeFunc = i->getType();
819 if (TypeFunc != ELF::R_PPC64_ADDR64) {
824 uint64_t TargetSymbolOffset = i->getOffset();
828 int64_t Addend = *AddendOrErr;
835 uint64_t TypeTOC = i->getType();
836 if (TypeTOC != ELF::R_PPC64_TOC)
842 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
847 bool IsCode = tsi->isText();
861 static inline uint16_t
applyPPClo(uint64_t value) {
return value & 0xffff; }
864 return (value >> 16) & 0xffff;
868 return ((value + 0x8000) >> 16) & 0xffff;
872 return (value >> 32) & 0xffff;
876 return ((value + 0x8000) >> 32) & 0xffff;
880 return (value >> 48) & 0xffff;
884 return ((value + 0x8000) >> 48) & 0xffff;
887 void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
888 uint64_t Offset, uint64_t Value,
889 uint32_t Type, int64_t Addend) {
890 uint8_t *LocalAddress = Section.
Address + Offset;
895 case ELF::R_PPC64_ADDR16:
898 case ELF::R_PPC64_ADDR16_DS:
901 case ELF::R_PPC64_ADDR16_LO:
904 case ELF::R_PPC64_ADDR16_LO_DS:
907 case ELF::R_PPC64_ADDR16_HI:
910 case ELF::R_PPC64_ADDR16_HA:
913 case ELF::R_PPC64_ADDR16_HIGHER:
916 case ELF::R_PPC64_ADDR16_HIGHERA:
919 case ELF::R_PPC64_ADDR16_HIGHEST:
922 case ELF::R_PPC64_ADDR16_HIGHESTA:
925 case ELF::R_PPC64_ADDR14: {
926 assert(((Value + Addend) & 3) == 0);
928 uint8_t aalk = *(LocalAddress + 3);
929 writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
931 case ELF::R_PPC64_REL16_LO: {
932 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
933 uint64_t Delta = Value - FinalAddress + Addend;
936 case ELF::R_PPC64_REL16_HI: {
937 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
938 uint64_t Delta = Value - FinalAddress + Addend;
941 case ELF::R_PPC64_REL16_HA: {
942 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
943 uint64_t Delta = Value - FinalAddress + Addend;
946 case ELF::R_PPC64_ADDR32: {
947 int32_t Result =
static_cast<int32_t
>(Value + Addend);
948 if (SignExtend32<32>(Result) != Result)
952 case ELF::R_PPC64_REL24: {
953 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
954 int32_t delta =
static_cast<int32_t
>(Value - FinalAddress + Addend);
955 if (SignExtend32<24>(delta) != delta)
958 writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
960 case ELF::R_PPC64_REL32: {
961 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
962 int32_t delta =
static_cast<int32_t
>(Value - FinalAddress + Addend);
963 if (SignExtend32<32>(delta) != delta)
967 case ELF::R_PPC64_REL64: {
968 uint64_t FinalAddress = (Section.
LoadAddress + Offset);
969 uint64_t Delta = Value - FinalAddress + Addend;
972 case ELF::R_PPC64_ADDR64:
978 void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
979 uint64_t Offset, uint64_t Value,
980 uint32_t Type, int64_t Addend) {
981 uint8_t *LocalAddress = Section.
Address + Offset;
986 case ELF::R_390_PC16DBL:
987 case ELF::R_390_PLT16DBL: {
988 int64_t Delta = (Value + Addend) - (Section.
LoadAddress + Offset);
989 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
993 case ELF::R_390_PC32DBL:
994 case ELF::R_390_PLT32DBL: {
995 int64_t Delta = (Value + Addend) - (Section.
LoadAddress + Offset);
996 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
1000 case ELF::R_390_PC32: {
1001 int64_t Delta = (Value + Addend) - (Section.
LoadAddress + Offset);
1002 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
1039 void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
1040 uint64_t Offset, uint64_t Value,
1041 uint32_t Type, int64_t Addend,
1042 uint64_t SymOffset, SID SectionID) {
1045 resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
1048 resolveX86Relocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
1049 (uint32_t)(Addend & 0xffffffffL));
1053 resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
1059 resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
1060 (uint32_t)(Addend & 0xffffffffL));
1067 resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
1068 Type, (uint32_t)(Addend & 0xffffffffL));
1070 resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
1077 resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
1080 resolveSystemZRelocation(Section, Offset, Value, Type, Addend);
1087 void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID, uint64_t Offset)
const {
1088 return (
void*)(
Sections[SectionID].ObjAddress + Offset);
1091 void RuntimeDyldELF::processSimpleRelocation(
unsigned SectionID, uint64_t Offset,
unsigned RelType,
RelocationValueRef Value) {
1102 const auto &Obj = cast<ELFObjectFileBase>(O);
1103 uint64_t RelType = RelI->getType();
1105 int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
1112 if (std::error_code EC = TargetNameOrErr.
getError())
1114 TargetName = *TargetNameOrErr;
1116 DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
1117 <<
" TargetName: " << TargetName <<
"\n");
1129 const auto &SymInfo = gsi->
second;
1130 Value.
SectionID = SymInfo.getSectionID();
1131 Value.
Offset = SymInfo.getOffset();
1132 Value.
Addend = SymInfo.getOffset() + Addend;
1143 DEBUG(
dbgs() <<
"\t\tThis is section symbol\n");
1144 bool isCode = si->isText();
1168 uint64_t Offset = RelI->getOffset();
1170 DEBUG(
dbgs() <<
"\t\tSectionID: " << SectionID <<
" Offset: " << Offset
1173 (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) {
1175 DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1179 StubMap::const_iterator i = Stubs.find(Value);
1180 if (i != Stubs.end()) {
1181 resolveRelocation(Section, Offset, (uint64_t)Section.
Address + i->second,
1183 DEBUG(
dbgs() <<
" Stub function found\n");
1186 DEBUG(
dbgs() <<
" Create a new stub function\n");
1188 uint8_t *StubTargetAddr =
1192 ELF::R_AARCH64_MOVW_UABS_G3, Value.
Addend);
1194 ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.
Addend);
1196 ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.
Addend);
1198 StubTargetAddr - Section.
Address + 12,
1199 ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.
Addend);
1212 resolveRelocation(Section, Offset,
1218 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1219 RelType == ELF::R_ARM_JUMP24) {
1221 DEBUG(
dbgs() <<
"\t\tThis is an ARM branch relocation.");
1225 StubMap::const_iterator i = Stubs.find(Value);
1226 if (i != Stubs.end()) {
1227 resolveRelocation(Section, Offset, (uint64_t)Section.
Address + i->second,
1229 DEBUG(
dbgs() <<
" Stub function found\n");
1232 DEBUG(
dbgs() <<
" Create a new stub function\n");
1234 uint8_t *StubTargetAddr =
1237 ELF::R_ARM_ABS32, Value.
Addend);
1243 resolveRelocation(Section, Offset,
1249 uint32_t *Placeholder =
1250 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID, Offset));
1251 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1252 RelType == ELF::R_ARM_ABS32) {
1253 Value.
Addend += *Placeholder;
1254 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1256 Value.
Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1258 processSimpleRelocation(SectionID, Offset, RelType, Value);
1261 uint8_t *Placeholder =
reinterpret_cast<uint8_t *
>(
1262 computePlaceholderAddress(SectionID, Offset));
1264 if (RelType == ELF::R_MIPS_26) {
1266 DEBUG(
dbgs() <<
"\t\tThis is a Mips branch relocation.");
1272 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1277 StubMap::const_iterator i = Stubs.find(Value);
1278 if (i != Stubs.end()) {
1281 DEBUG(
dbgs() <<
" Stub function found\n");
1284 DEBUG(
dbgs() <<
" Create a new stub function\n");
1286 uint8_t *StubTargetAddr =
1291 ELF::R_MIPS_HI16, Value.
Addend);
1293 ELF::R_MIPS_LO16, Value.
Addend);
1311 if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16)
1312 Value.
Addend += (Opcode & 0x0000ffff) << 16;
1313 else if (RelType == ELF::R_MIPS_LO16)
1314 Value.
Addend += (Opcode & 0x0000ffff);
1315 else if (RelType == ELF::R_MIPS_32)
1317 else if (RelType == ELF::R_MIPS_PCLO16)
1318 Value.
Addend += SignExtend32<16>((Opcode & 0x0000ffff));
1319 else if (RelType == ELF::R_MIPS_PC16)
1320 Value.
Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1321 else if (RelType == ELF::R_MIPS_PC19_S2)
1322 Value.
Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1323 else if (RelType == ELF::R_MIPS_PC21_S2)
1324 Value.
Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1325 else if (RelType == ELF::R_MIPS_PC26_S2)
1326 Value.
Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
1327 processSimpleRelocation(SectionID, Offset, RelType, Value);
1330 uint32_t r_type = RelType & 0xff;
1332 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1333 || r_type == ELF::R_MIPS_GOT_DISP) {
1335 if (i != GOTSymbolOffsets.
end())
1338 RE.
SymOffset = allocateGOTEntries(SectionID, 1);
1339 GOTSymbolOffsets[TargetName] = RE.
SymOffset;
1347 if (RelType == ELF::R_PPC64_REL24) {
1349 unsigned AbiVariant;
1357 bool RangeOverflow =
false;
1359 if (AbiVariant != 2) {
1363 findOPDEntrySection(Obj, ObjSectionToID, Value);
1367 uint8_t SymOther =
Symbol->getOther();
1370 uint8_t *RelocTarget = Sections[Value.
SectionID].Address + Value.
Addend;
1371 int32_t delta =
static_cast<int32_t
>(Target - RelocTarget);
1373 if (SignExtend32<24>(delta) == delta) {
1376 addRelocationForSymbol(RE, Value.
SymbolName);
1378 addRelocationForSection(RE, Value.
SectionID);
1380 RangeOverflow =
true;
1386 StubMap::const_iterator i = Stubs.find(Value);
1387 if (i != Stubs.end()) {
1389 resolveRelocation(Section, Offset,
1390 (uint64_t)Section.
Address + i->second, RelType, 0);
1391 DEBUG(
dbgs() <<
" Stub function found\n");
1394 DEBUG(
dbgs() <<
" Create a new stub function\n");
1396 uint8_t *StubTargetAddr =
1400 ELF::R_PPC64_ADDR64, Value.
Addend);
1406 uint64_t StubRelocOffset = StubTargetAddr - Section.
Address;
1407 if (!IsTargetLittleEndian)
1408 StubRelocOffset += 2;
1411 ELF::R_PPC64_ADDR16_HIGHEST, Value.
Addend);
1413 ELF::R_PPC64_ADDR16_HIGHER, Value.
Addend);
1415 ELF::R_PPC64_ADDR16_HI, Value.
Addend);
1417 ELF::R_PPC64_ADDR16_LO, Value.
Addend);
1420 addRelocationForSymbol(REhst, Value.
SymbolName);
1421 addRelocationForSymbol(REhr, Value.
SymbolName);
1422 addRelocationForSymbol(REh, Value.
SymbolName);
1423 addRelocationForSymbol(REl, Value.
SymbolName);
1425 addRelocationForSection(REhst, Value.
SectionID);
1426 addRelocationForSection(REhr, Value.
SectionID);
1427 addRelocationForSection(REh, Value.
SectionID);
1428 addRelocationForSection(REl, Value.
SectionID);
1431 resolveRelocation(Section, Offset,
1438 if (AbiVariant == 2)
1439 writeInt32BE(Target + 4, 0xE8410018);
1441 writeInt32BE(Target + 4, 0xE8410028);
1444 }
else if (RelType == ELF::R_PPC64_TOC16 ||
1445 RelType == ELF::R_PPC64_TOC16_DS ||
1446 RelType == ELF::R_PPC64_TOC16_LO ||
1447 RelType == ELF::R_PPC64_TOC16_LO_DS ||
1448 RelType == ELF::R_PPC64_TOC16_HI ||
1449 RelType == ELF::R_PPC64_TOC16_HA) {
1461 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
1462 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
1463 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
1464 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
1465 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
1466 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
1471 findPPC64TOCSection(Obj, ObjSectionToID, TOCValue);
1475 resolveRelocation(Sections[SectionID], Offset, Value.
Addend, RelType, 0);
1481 if (RelType == ELF::R_PPC64_TOC) {
1482 RelType = ELF::R_PPC64_ADDR64;
1483 findPPC64TOCSection(Obj, ObjSectionToID, Value);
1484 }
else if (TargetName ==
".TOC.") {
1485 findPPC64TOCSection(Obj, ObjSectionToID, Value);
1492 addRelocationForSymbol(RE, Value.
SymbolName);
1494 addRelocationForSection(RE, Value.
SectionID);
1497 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
1507 DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
1511 StubMap::const_iterator i = Stubs.find(Value);
1512 uintptr_t StubAddress;
1513 if (i != Stubs.end()) {
1514 StubAddress = uintptr_t(Section.
Address) + i->second;
1515 DEBUG(
dbgs() <<
" Stub function found\n");
1518 DEBUG(
dbgs() <<
" Create a new stub function\n");
1520 uintptr_t BaseAddress = uintptr_t(Section.
Address);
1521 uintptr_t StubAlignment = getStubAlignment();
1522 StubAddress = (BaseAddress + Section.
StubOffset + StubAlignment - 1) &
1524 unsigned StubOffset = StubAddress - BaseAddress;
1526 Stubs[Value] = StubOffset;
1527 createStubFunction((uint8_t *)StubAddress);
1531 addRelocationForSymbol(RE, Value.
SymbolName);
1533 addRelocationForSection(RE, Value.
SectionID);
1534 Section.
StubOffset = StubOffset + getMaxStubSize();
1537 if (RelType == ELF::R_390_GOTENT)
1538 resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL,
1541 resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
1543 if (RelType == ELF::R_X86_64_PLT32) {
1564 StubMap::const_iterator i = Stubs.find(Value);
1565 uintptr_t StubAddress;
1566 if (i != Stubs.end()) {
1567 StubAddress = uintptr_t(Section.
Address) + i->second;
1568 DEBUG(
dbgs() <<
" Stub function found\n");
1571 DEBUG(
dbgs() <<
" Create a new stub function\n");
1573 uintptr_t BaseAddress = uintptr_t(Section.
Address);
1574 uintptr_t StubAlignment = getStubAlignment();
1575 StubAddress = (BaseAddress + Section.
StubOffset + StubAlignment - 1) &
1577 unsigned StubOffset = StubAddress - BaseAddress;
1578 Stubs[Value] = StubOffset;
1579 createStubFunction((uint8_t *)StubAddress);
1582 Section.
StubOffset = StubOffset + getMaxStubSize();
1585 uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
1588 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4);
1591 addRelocationForSymbol(computeGOTOffsetRE(SectionID,GOTOffset,0,ELF::R_X86_64_64),
1596 resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32,
1601 addRelocationForSection(RE, Value.
SectionID);
1603 }
else if (RelType == ELF::R_X86_64_GOTPCREL) {
1604 uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
1605 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend);
1610 addRelocationForSymbol(RE, Value.
SymbolName);
1612 addRelocationForSection(RE, Value.
SectionID);
1613 }
else if (RelType == ELF::R_X86_64_PC32) {
1615 processSimpleRelocation(SectionID, Offset, RelType, Value);
1616 }
else if (RelType == ELF::R_X86_64_PC64) {
1618 processSimpleRelocation(SectionID, Offset, RelType, Value);
1620 processSimpleRelocation(SectionID, Offset, RelType, Value);
1626 processSimpleRelocation(SectionID, Offset, RelType, Value);
1631 size_t RuntimeDyldELF::getGOTEntrySize() {
1642 Result =
sizeof(uint64_t);
1647 Result =
sizeof(uint32_t);
1654 Result =
sizeof(uint32_t);
1656 Result =
sizeof(uint64_t);
1666 uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned SectionID,
unsigned no)
1669 if (GOTSectionID == 0) {
1675 uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
1676 CurrentGOTIndex += no;
1680 void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID, uint64_t Offset, uint64_t GOTOffset)
1683 RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32, GOTOffset);
1687 RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(
unsigned SectionID, uint64_t GOTOffset, uint64_t SymbolOffset,
1697 if (GOTSectionID != 0) {
1699 size_t TotalSize = CurrentGOTIndex * getGOTEntrySize();
1701 GOTSectionID,
".got",
false);
1712 memset(Addr, 0, TotalSize);
1718 if (
SI->relocation_begin() !=
SI->relocation_end()) {
1720 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
1721 assert (i != SectionMap.end());
1722 SectionToGOTMap[i->second] = GOTSectionID;
1725 GOTSymbolOffsets.
clear();
1730 ObjSectionToIDMap::iterator i, e;
1731 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
1735 if (Name ==
".eh_frame") {
1736 UnregisteredEHFrameSections.
push_back(i->second);
1742 CurrentGOTIndex = 0;
bool isInt< 32 >(int64_t x)
RelocationEntry - used to represent relocations internally in the dynamic linker. ...
void push_back(const T &Elt)
std::error_code getError() const
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
Represents either an error or a value T.
DataRefImpl getRawDataRefImpl() const
void writeInt16BE(uint8_t *Addr, uint16_t Value)
std::pair< unsigned, unsigned > loadObjectImpl(const object::ObjectFile &Obj)
RuntimeDyld::MemoryManager & MemMgr
iterator find(StringRef Key)
RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver)
This class is the base class for all object file types.
RuntimeDyldCheckerImpl * Checker
static uint16_t applyPPChigher(uint64_t value)
uint8_t * Address
Address - address in the linker's memory where the section resides.
unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
static uint16_t applyPPChighesta(uint64_t value)
DataRefImpl getRawDataRefImpl() const
static uint16_t applyPPChighera(uint64_t value)
ELFType< support::little, true > ELF64LE
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
ELFType< support::big, false > ELF32BE
static int64_t decodePPC64LocalEntryOffset(unsigned Other)
unsigned SectionID
SectionID - the section this relocation points to.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringRef getData() const
virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr, size_t Size)=0
std::unique_ptr< RuntimeDyld::LoadedObjectInfo > loadObject(const object::ObjectFile &O) override
std::map< RelocationValueRef, uintptr_t > StubMap
uintptr_t StubOffset
StubOffset - used for architectures with stub functions for far relocations (like ARM)...
SymbolRef::Type getType() const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::error_code getName(StringRef &Result) const
static std::error_code check(std::error_code Err)
static uint16_t applyPPChi(uint64_t value)
std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
ELFType< support::little, false > ELF32LE
The instances of the Type class are immutable: once they are created, they are never changed...
void registerEHFrames() override
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
~RuntimeDyldELF() override
uint8_t * getSectionAddress(unsigned SectionID) const
LLVM_ATTRIBUTE_UNUSED_RESULT bool isa(const Y &Val)
ELFType< support::big, true > ELF64BE
static uint16_t applyPPClo(uint64_t value)
virtual std::error_code getPlatformFlags(unsigned &Result) const
Returns platform-specific object flags, if any.
void writeInt32BE(uint8_t *Addr, uint32_t Value)
section_iterator_range sections() const
static const char * getArchTypePrefix(ArchType Kind)
getArchTypePrefix - Get the "prefix" canonical name for the Kind architecture.
bool isCompatibleFile(const object::ObjectFile &Obj) const override
virtual uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly)=0
Allocate a memory block of (at least) the given size suitable for data.
StringRef getFileName() const
basic_symbol_iterator symbol_end() const
static uint16_t applyPPChighest(uint64_t value)
void finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override
void deregisterEHFrames() override
virtual object::OwningBinary< object::ObjectFile > getObjectForDebug(const object::ObjectFile &Obj) const =0
virtual section_iterator section_begin() const =0
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
uint32_t RelType
RelType - relocation type.
ErrorOr< int64_t > getAddend() const
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Target - Wrapper for Target specific information.
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
This is a value type class that represents a single symbol in the list of symbols in the object file...
ErrorOr< StringRef > getName() const
uint64_t Offset
Offset - offset into the section.
relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override
Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...
virtual section_iterator section_end() const =0
std::map< SectionRef, unsigned > ObjSectionToIDMap
std::error_code Check(std::error_code Err)
uint64_t LoadAddress
LoadAddress - the address of the section in the target process's memory.
void writeInt64BE(uint8_t *Addr, uint64_t Value)
bool isLittleEndian() const
SectionEntry - represents a section emitted into memory by the dynamic linker.
LLVM Value Representation.
RTDyldSymbolTable GlobalSymbolTable
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
StringRef - Represent a constant reference to a string, i.e.
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)=0
Register the EH frames with the runtime so that c++ exceptions work.
uint64_t getSectionLoadAddress(unsigned SectionID) const
static uint16_t applyPPCha(uint64_t value)
virtual StringRef getFileFormatName() const =0
std::error_code getSection(section_iterator &Result) const
Get section this symbol is defined in reference to.
This is a value type class that represents a single section in the list of sections in the object fil...