28#define DEBUG_TYPE "dyld"
33 or32le(L, (Imm & 0xFFF) << 10);
36template <
class T>
static void write(
bool isBE,
void *
P,
T V) {
37 isBE ? write<T, llvm::endianness::big>(
P, V)
38 : write<T, llvm::endianness::little>(
P, V);
43 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
44 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
52 return (Val >> Start) & Mask;
57template <
class ELFT>
class DyldELFObject :
public ELFObjectFile<ELFT> {
60 typedef typename ELFT::uint addr_type;
78 return v->isDyldType();
90 this->isDyldELFObject =
true;
97 if (
auto E = Obj.takeError())
99 std::unique_ptr<DyldELFObject<ELFT>>
Ret(
100 new DyldELFObject<ELFT>(std::move(*Obj)));
101 return std::move(Ret);
105void DyldELFObject<ELFT>::updateSectionAddress(
const SectionRef &Sec,
109 const_cast<Elf_Shdr *
>(
reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
113 shdr->sh_addr =
static_cast<addr_type
>(
Addr);
117void DyldELFObject<ELFT>::updateSymbolAddress(
const SymbolRef &SymRef,
120 Elf_Sym *sym =
const_cast<Elf_Sym *
>(
125 sym->st_value =
static_cast<addr_type
>(
Addr);
128class LoadedELFObjectInfo final
130 RuntimeDyld::LoadedObjectInfo> {
132 LoadedELFObjectInfo(
RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
136 getObjectForDebug(
const ObjectFile &Obj)
const override;
139template <
typename ELFT>
142 const LoadedELFObjectInfo &L) {
143 typedef typename ELFT::Shdr Elf_Shdr;
144 typedef typename ELFT::uint addr_type;
147 DyldELFObject<ELFT>::create(Buffer);
151 std::unique_ptr<DyldELFObject<ELFT>> Obj = std::move(*ObjOrErr);
155 for (
const auto &Sec : Obj->sections()) {
162 if (*NameOrErr !=
"") {
164 Elf_Shdr *shdr =
const_cast<Elf_Shdr *
>(
165 reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
167 if (
uint64_t SecLoadAddr =
L.getSectionLoadAddress(*SI)) {
170 shdr->sh_addr =
static_cast<addr_type
>(SecLoadAddr);
176 return std::move(Obj);
180createELFDebugObject(
const ObjectFile &Obj,
const LoadedELFObjectInfo &L) {
183 std::unique_ptr<MemoryBuffer> Buffer =
190 createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj, L);
193 createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj, L);
196 createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj, L);
199 createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj, L);
208LoadedELFObjectInfo::getObjectForDebug(
const ObjectFile &Obj)
const {
209 return createELFDebugObject(Obj, *
this);
222 for (
SID EHFrameSID : UnregisteredEHFrameSections) {
225 size_t EHFrameSize =
Sections[EHFrameSID].getSize();
228 UnregisteredEHFrameSections.clear();
231std::unique_ptr<RuntimeDyldELF>
246std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
249 return std::make_unique<LoadedELFObjectInfo>(*
this, *ObjSectionToIDOrErr);
258void RuntimeDyldELF::resolveX86_64Relocation(
const SectionEntry &Section,
266 case ELF::R_X86_64_NONE:
268 case ELF::R_X86_64_8: {
272 *Section.getAddressWithOffset(
Offset) = TruncatedAddr;
274 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
277 case ELF::R_X86_64_16: {
284 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
287 case ELF::R_X86_64_64: {
294 case ELF::R_X86_64_32:
295 case ELF::R_X86_64_32S: {
298 (
Type == ELF::R_X86_64_32S &&
299 ((int64_t)
Value <= INT32_MAX && (int64_t)
Value >= INT32_MIN)));
307 case ELF::R_X86_64_PC8: {
309 int64_t RealOffset =
Value + Addend - FinalAddress;
310 assert(isInt<8>(RealOffset));
311 int8_t TruncOffset = (RealOffset & 0xFF);
315 case ELF::R_X86_64_PC32: {
317 int64_t RealOffset =
Value + Addend - FinalAddress;
318 assert(isInt<32>(RealOffset));
319 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
324 case ELF::R_X86_64_PC64: {
326 int64_t RealOffset =
Value + Addend - FinalAddress;
330 <<
format(
"%p\n", FinalAddress));
333 case ELF::R_X86_64_GOTOFF64: {
336 for (
const auto &Section :
Sections) {
337 if (
Section.getName() ==
".got") {
338 GOTBase =
Section.getLoadAddressWithOffset(0);
342 assert(GOTBase != 0 &&
"missing GOT");
343 int64_t GOTOffset =
Value - GOTBase + Addend;
347 case ELF::R_X86_64_DTPMOD64: {
352 case ELF::R_X86_64_DTPOFF64:
353 case ELF::R_X86_64_TPOFF64: {
362 case ELF::R_X86_64_DTPOFF32:
363 case ELF::R_X86_64_TPOFF32: {
366 int64_t RealValue =
Value + Addend;
367 assert(RealValue >= INT32_MIN && RealValue <= INT32_MAX);
368 int32_t TruncValue = RealValue;
376void RuntimeDyldELF::resolveX86Relocation(
const SectionEntry &Section,
380 case ELF::R_386_32: {
387 case ELF::R_386_PLT32:
388 case ELF::R_386_PC32: {
404void RuntimeDyldELF::resolveAArch64Relocation(
const SectionEntry &Section,
415 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
416 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
418 <<
format(
"%llx", Addend) <<
"\n");
424 case ELF::R_AARCH64_NONE:
426 case ELF::R_AARCH64_ABS16: {
429 (Result >> 16) == 0);
430 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
433 case ELF::R_AARCH64_ABS32: {
436 (Result >> 32) == 0);
437 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
440 case ELF::R_AARCH64_ABS64:
443 case ELF::R_AARCH64_PLT32: {
445 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
446 static_cast<int64_t
>(Result) <= INT32_MAX);
450 case ELF::R_AARCH64_PREL16: {
452 assert(
static_cast<int64_t
>(Result) >= INT16_MIN &&
453 static_cast<int64_t
>(Result) <= UINT16_MAX);
454 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
457 case ELF::R_AARCH64_PREL32: {
459 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
460 static_cast<int64_t
>(Result) <= UINT32_MAX);
461 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
464 case ELF::R_AARCH64_PREL64:
465 write(isBE, TargetPtr,
Value + Addend - FinalAddress);
467 case ELF::R_AARCH64_CONDBR19: {
470 assert(isInt<21>(BranchImm));
471 *TargetPtr &= 0xff00001fU;
473 or32le(TargetPtr, (BranchImm & 0x001FFFFC) << 3);
476 case ELF::R_AARCH64_TSTBR14: {
479 assert(isInt<16>(BranchImm));
485 or32le(TargetPtr, (BranchImm & 0x0000FFFC) << 3);
488 case ELF::R_AARCH64_CALL26:
489 case ELF::R_AARCH64_JUMP26: {
495 assert(isInt<28>(BranchImm));
496 or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
499 case ELF::R_AARCH64_MOVW_UABS_G3:
500 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF000000000000) >> 43);
502 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
503 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF00000000) >> 27);
505 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
506 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF0000) >> 11);
508 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
509 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF) << 5);
511 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
514 ((
Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
517 assert(isInt<33>(Result) &&
"overflow check failed for relocation");
524 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
530 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
536 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
542 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
548 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
554 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
560 case ELF::R_AARCH64_LD_PREL_LO19: {
565 assert(isInt<21>(Result));
567 *TargetPtr &= 0xff00001fU;
570 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
573 case ELF::R_AARCH64_ADR_PREL_LO21: {
578 assert(isInt<21>(Result));
580 *TargetPtr &= 0x9f00001fU;
583 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
584 *TargetPtr |= (
Result & 0x3) << 29;
590void RuntimeDyldELF::resolveARMRelocation(
const SectionEntry &Section,
601 <<
" FinalAddress: " <<
format(
"%p", FinalAddress)
604 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
610 case ELF::R_ARM_NONE:
613 case ELF::R_ARM_PREL31:
616 ((
Value - FinalAddress) & ~0x80000000);
618 case ELF::R_ARM_TARGET1:
619 case ELF::R_ARM_ABS32:
624 case ELF::R_ARM_MOVW_ABS_NC:
625 case ELF::R_ARM_MOVT_ABS:
626 if (
Type == ELF::R_ARM_MOVW_ABS_NC)
628 else if (
Type == ELF::R_ARM_MOVT_ABS)
632 (((
Value >> 12) & 0xF) << 16);
635 case ELF::R_ARM_PC24:
636 case ELF::R_ARM_CALL:
637 case ELF::R_ARM_JUMP24:
638 int32_t RelValue =
static_cast<int32_t
>(
Value - FinalAddress - 8);
639 RelValue = (RelValue & 0x03FFFFFC) >> 2;
647bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
651 if (
Value.SymbolName) {
656 const auto &
SymInfo = Loc->second;
666 if (RelI->getType() == ELF::R_LARCH_B26) {
667 if (!isInt<28>(Delta))
682void RuntimeDyldELF::resolveLoongArch64Branch(
unsigned SectionID,
686 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an LoongArch64 branch relocation.\n");
688 if (resolveLoongArch64ShortBranch(SectionID, RelI,
Value))
693 unsigned RelType = RelI->getType();
697 resolveRelocation(Section,
Offset,
705 It->second =
Section.getStubOffset();
709 ELF::R_LARCH_ABS_HI20,
Value.Addend);
711 ELF::R_LARCH_ABS_LO12,
Value.Addend);
713 ELF::R_LARCH_ABS64_LO20,
Value.Addend);
715 ELF::R_LARCH_ABS64_HI12,
Value.Addend);
716 if (
Value.SymbolName) {
728 resolveRelocation(Section,
Offset,
732 Section.advanceStubOffset(getMaxStubSize());
737 return Hi == 63 ? Val >>
Lo : (Val & (((1ULL << (
Hi + 1)) - 1))) >>
Lo;
746 case ELF::R_LARCH_PCALA64_LO20:
747 case ELF::R_LARCH_GOT64_PC_LO20:
748 pcalau12i_pc = pc - 8;
750 case ELF::R_LARCH_PCALA64_HI12:
751 case ELF::R_LARCH_GOT64_PC_HI12:
752 pcalau12i_pc = pc - 12;
758 uint64_t result = (dest & ~0xfffULL) - (pcalau12i_pc & ~0xfffULL);
760 result += 0x1000 - 0x1'0000'0000;
761 if (result & 0x8000'0000)
762 result += 0x1'0000'0000;
766void RuntimeDyldELF::resolveLoongArch64Relocation(
const SectionEntry &Section,
770 auto *TargetPtr = Section.getAddressWithOffset(
Offset);
773 LLVM_DEBUG(
dbgs() <<
"resolveLoongArch64Relocation, LocalAddress: 0x"
775 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
776 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
778 <<
format(
"%llx", Addend) <<
"\n");
784 case ELF::R_LARCH_32:
788 case ELF::R_LARCH_64:
791 case ELF::R_LARCH_32_PCREL:
795 case ELF::R_LARCH_B26: {
800 Instr = (
Instr & 0xfc000000) | Imm15_0 | Imm25_16;
803 case ELF::R_LARCH_CALL36: {
808 Pcaddu18i = (Pcaddu18i & 0xfe00001f) | Imm35_16;
811 Jirl = (Jirl & 0xfc0003ff) | Imm15_0;
814 case ELF::R_LARCH_GOT_PC_HI20:
815 case ELF::R_LARCH_PCALA_HI20: {
823 case ELF::R_LARCH_GOT_PC_LO12:
824 case ELF::R_LARCH_PCALA_LO12: {
827 uint32_t Imm11_0 = TargetOffset << 10;
831 case ELF::R_LARCH_GOT64_PC_LO20:
832 case ELF::R_LARCH_PCALA64_LO20: {
840 case ELF::R_LARCH_GOT64_PC_HI12:
841 case ELF::R_LARCH_PCALA64_HI12: {
849 case ELF::R_LARCH_ABS_HI20: {
856 case ELF::R_LARCH_ABS_LO12: {
863 case ELF::R_LARCH_ABS64_LO20: {
870 case ELF::R_LARCH_ABS64_HI12: {
877 case ELF::R_LARCH_ADD32:
882 case ELF::R_LARCH_SUB32:
887 case ELF::R_LARCH_ADD64:
891 case ELF::R_LARCH_SUB64:
898void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
906 if (
auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
907 unsigned AbiVariant = E->getPlatformFlags();
916 ObjSectionToIDMap &LocalSections,
928 for (
auto &Section : Obj.
sections()) {
938 if (
auto SectionIDOrErr =
942 return SectionIDOrErr.takeError();
957 ObjSectionToIDMap &LocalSections,
977 if (RelSectionName !=
".opd")
981 e = si->relocation_end();
986 if (TypeFunc != ELF::R_PPC64_ADDR64) {
991 uint64_t TargetSymbolOffset = i->getOffset();
994 if (
auto AddendOrErr = i->getAddend())
995 Addend = *AddendOrErr;
997 return AddendOrErr.takeError();
1005 if (TypeTOC != ELF::R_PPC64_TOC)
1011 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
1015 if (
auto TSIOrErr = TargetSymbol->
getSection())
1018 return TSIOrErr.takeError();
1021 bool IsCode = TSI->
isText();
1026 return SectionIDOrErr.takeError();
1027 Rel.
Addend = (intptr_t)Addend;
1042 return (
value >> 16) & 0xffff;
1046 return ((
value + 0x8000) >> 16) & 0xffff;
1050 return (
value >> 32) & 0xffff;
1054 return ((
value + 0x8000) >> 32) & 0xffff;
1058 return (
value >> 48) & 0xffff;
1062 return ((
value + 0x8000) >> 48) & 0xffff;
1065void RuntimeDyldELF::resolvePPC32Relocation(
const SectionEntry &Section,
1068 uint8_t *LocalAddress = Section.getAddressWithOffset(
Offset);
1073 case ELF::R_PPC_ADDR16_LO:
1076 case ELF::R_PPC_ADDR16_HI:
1079 case ELF::R_PPC_ADDR16_HA:
1085void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
1093 case ELF::R_PPC64_ADDR16:
1096 case ELF::R_PPC64_ADDR16_DS:
1099 case ELF::R_PPC64_ADDR16_LO:
1102 case ELF::R_PPC64_ADDR16_LO_DS:
1105 case ELF::R_PPC64_ADDR16_HI:
1106 case ELF::R_PPC64_ADDR16_HIGH:
1109 case ELF::R_PPC64_ADDR16_HA:
1110 case ELF::R_PPC64_ADDR16_HIGHA:
1113 case ELF::R_PPC64_ADDR16_HIGHER:
1116 case ELF::R_PPC64_ADDR16_HIGHERA:
1119 case ELF::R_PPC64_ADDR16_HIGHEST:
1122 case ELF::R_PPC64_ADDR16_HIGHESTA:
1125 case ELF::R_PPC64_ADDR14: {
1128 uint8_t aalk = *(LocalAddress + 3);
1131 case ELF::R_PPC64_REL16_LO: {
1136 case ELF::R_PPC64_REL16_HI: {
1141 case ELF::R_PPC64_REL16_HA: {
1146 case ELF::R_PPC64_ADDR32: {
1147 int64_t
Result =
static_cast<int64_t
>(
Value + Addend);
1148 if (SignExtend64<32>(Result) !=
Result)
1152 case ELF::R_PPC64_REL24: {
1154 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
1155 if (SignExtend64<26>(delta) != delta)
1159 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
1161 case ELF::R_PPC64_REL32: {
1163 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
1164 if (SignExtend64<32>(delta) != delta)
1168 case ELF::R_PPC64_REL64: {
1173 case ELF::R_PPC64_ADDR64:
1179void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
1187 case ELF::R_390_PC16DBL:
1188 case ELF::R_390_PLT16DBL: {
1190 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
1194 case ELF::R_390_PC32DBL:
1195 case ELF::R_390_PLT32DBL: {
1197 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
1201 case ELF::R_390_PC16: {
1203 assert(int16_t(Delta) == Delta &&
"R_390_PC16 overflow");
1207 case ELF::R_390_PC32: {
1209 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
1213 case ELF::R_390_PC64: {
1233void RuntimeDyldELF::resolveBPFRelocation(
const SectionEntry &Section,
1242 case ELF::R_BPF_NONE:
1243 case ELF::R_BPF_64_64:
1244 case ELF::R_BPF_64_32:
1245 case ELF::R_BPF_64_NODYLD32:
1247 case ELF::R_BPF_64_ABS64: {
1253 case ELF::R_BPF_64_ABS32: {
1265 uint32_t UpperImm = (Imm + 0x800) & 0xfffff000;
1267 Instr = (Instr & 0xfff) | UpperImm;
1273 Instr = (Instr & 0xfffff) | (LowerImm << 20);
1276void RuntimeDyldELF::resolveRISCVRelocation(
const SectionEntry &Section,
1282 std::string Err =
"Unimplemented reloc type: " + std::to_string(
Type);
1288 case ELF::R_RISCV_CALL:
1289 case ELF::R_RISCV_CALL_PLT: {
1297 case ELF::R_RISCV_HI20: {
1303 case ELF::R_RISCV_LO12_I: {
1309 case ELF::R_RISCV_GOT_HI20:
1310 case ELF::R_RISCV_PCREL_HI20: {
1324 case ELF::R_RISCV_PCREL_LO12_I: {
1325 for (
auto &&PendingReloc : PendingRelocs) {
1330 if (
Value + Addend == HIRelocPC) {
1333 auto PCOffset =
Symbol - HIRelocPC;
1340 "R_RISCV_PCREL_LO12_I without matching R_RISCV_PCREL_HI20");
1342 case ELF::R_RISCV_32_PCREL: {
1344 int64_t RealOffset =
Value + Addend - FinalAddress;
1345 int32_t TruncOffset =
Lo_32(RealOffset);
1350 case ELF::R_RISCV_32: {
1355 case ELF::R_RISCV_64: {
1360 case ELF::R_RISCV_ADD8: {
1365 case ELF::R_RISCV_ADD16: {
1370 case ELF::R_RISCV_ADD32: {
1375 case ELF::R_RISCV_ADD64: {
1380 case ELF::R_RISCV_SUB8: {
1385 case ELF::R_RISCV_SUB16: {
1390 case ELF::R_RISCV_SUB32: {
1395 case ELF::R_RISCV_SUB64: {
1400 case ELF::R_RISCV_SET8: {
1405 case ELF::R_RISCV_SET16: {
1410 case ELF::R_RISCV_SET32: {
1445void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
1448 uint64_t SymOffset, SID SectionID) {
1451 resolveX86_64Relocation(Section,
Offset,
Value,
Type, Addend, SymOffset);
1488 resolveRISCVRelocation(Section,
Offset,
Value,
Type, Addend, SectionID);
1495void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID,
1502 if (
Value.SymbolName)
1509 bool IsLocal)
const {
1511 case ELF::R_MICROMIPS_GOT16:
1513 return ELF::R_MICROMIPS_LO16;
1515 case ELF::R_MICROMIPS_HI16:
1516 return ELF::R_MICROMIPS_LO16;
1517 case ELF::R_MIPS_GOT16:
1519 return ELF::R_MIPS_LO16;
1521 case ELF::R_MIPS_HI16:
1522 return ELF::R_MIPS_LO16;
1523 case ELF::R_MIPS_PCHI16:
1524 return ELF::R_MIPS_PCLO16;
1528 return ELF::R_MIPS_NONE;
1540bool RuntimeDyldELF::resolveAArch64ShortBranch(
1544 unsigned TargetSectionID;
1545 if (
Value.SymbolName) {
1552 const auto &
SymInfo = Loc->second;
1554 TargetSectionID =
SymInfo.getSectionID();
1555 TargetOffset =
SymInfo.getOffset();
1557 TargetSectionID =
Value.SectionID;
1563 if (TargetSectionID != SectionID)
1566 uint64_t SourceOffset = RelI->getOffset();
1571 if (!isInt<28>(TargetOffset +
Value.Addend - SourceOffset))
1575 if (
Value.SymbolName)
1583void RuntimeDyldELF::resolveAArch64Branch(
unsigned SectionID,
1588 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1592 unsigned RelType = RelI->getType();
1594 StubMap::const_iterator i = Stubs.find(
Value);
1595 if (i != Stubs.end()) {
1596 resolveRelocation(Section,
Offset,
1597 Section.getLoadAddressWithOffset(i->second), RelType, 0);
1599 }
else if (!resolveAArch64ShortBranch(SectionID, RelI,
Value)) {
1607 ELF::R_AARCH64_MOVW_UABS_G3,
Value.Addend);
1609 StubTargetAddr -
Section.getAddress() + 4,
1610 ELF::R_AARCH64_MOVW_UABS_G2_NC,
Value.Addend);
1612 StubTargetAddr -
Section.getAddress() + 8,
1613 ELF::R_AARCH64_MOVW_UABS_G1_NC,
Value.Addend);
1615 StubTargetAddr -
Section.getAddress() + 12,
1616 ELF::R_AARCH64_MOVW_UABS_G0_NC,
Value.Addend);
1618 if (
Value.SymbolName) {
1629 resolveRelocation(Section,
Offset,
1632 Section.advanceStubOffset(getMaxStubSize());
1640 const auto &Obj = cast<ELFObjectFileBase>(O);
1641 uint64_t RelType = RelI->getType();
1644 Addend = *AddendOrErr;
1652 if (
auto TargetNameOrErr = Symbol->getName())
1653 TargetName = *TargetNameOrErr;
1655 return TargetNameOrErr.takeError();
1657 LLVM_DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
1658 <<
" TargetName: " << TargetName <<
"\n");
1668 if (!SymTypeOrErr) {
1674 SymType = *SymTypeOrErr;
1677 const auto &
SymInfo = gsi->second;
1687 auto SectionOrErr = Symbol->getSection();
1688 if (!SectionOrErr) {
1698 bool isCode = si->
isText();
1701 Value.SectionID = *SectionIDOrErr;
1703 return SectionIDOrErr.takeError();
1704 Value.Addend = Addend;
1712 Value.Addend = Addend;
1718 if (!
Value.SymbolName)
1719 Value.SymbolName =
"";
1733 if ((RelType == ELF::R_AARCH64_CALL26 ||
1734 RelType == ELF::R_AARCH64_JUMP26) &&
1736 resolveAArch64Branch(SectionID,
Value, RelI, Stubs);
1737 }
else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
1740 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1741 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1742 ELF::R_AARCH64_ADR_PREL_PG_HI21);
1744 }
else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
1745 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1746 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1747 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
1749 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1752 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1753 RelType == ELF::R_ARM_JUMP24) {
1759 auto [It, Inserted] = Stubs.try_emplace(
Value);
1761 resolveRelocation(Section,
Offset,
1762 Section.getLoadAddressWithOffset(It->second), RelType,
1768 It->second = Section.getStubOffset();
1770 Section.getAddressWithOffset(Section.getStubOffset()));
1772 ELF::R_ARM_ABS32,
Value.Addend);
1773 if (
Value.SymbolName)
1780 Section.getLoadAddressWithOffset(Section.getStubOffset()), RelType,
1782 Section.advanceStubOffset(getMaxStubSize());
1786 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID,
Offset));
1787 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1788 RelType == ELF::R_ARM_ABS32) {
1789 Value.Addend += *Placeholder;
1790 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1792 Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1794 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1797 if ((RelType == ELF::R_LARCH_B26 || RelType == ELF::R_LARCH_CALL36) &&
1799 resolveLoongArch64Branch(SectionID,
Value, RelI, Stubs);
1800 }
else if (RelType == ELF::R_LARCH_GOT_PC_HI20 ||
1801 RelType == ELF::R_LARCH_GOT_PC_LO12 ||
1802 RelType == ELF::R_LARCH_GOT64_PC_HI12 ||
1803 RelType == ELF::R_LARCH_GOT64_PC_LO20) {
1804 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_LARCH_64);
1805 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1808 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1812 computePlaceholderAddress(SectionID,
Offset));
1814 if (RelType == ELF::R_MIPS_26) {
1822 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1824 Value.Addend += Addend;
1827 auto [It, Inserted] = Stubs.try_emplace(
Value);
1835 It->second = Section.getStubOffset();
1840 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1843 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1844 ELF::R_MIPS_HI16,
Value.Addend);
1846 StubTargetAddr - Section.getAddress() + 4,
1847 ELF::R_MIPS_LO16,
Value.Addend);
1849 if (
Value.SymbolName) {
1859 Section.advanceStubOffset(getMaxStubSize());
1861 }
else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1862 int64_t Addend = (Opcode & 0x0000ffff) << 16;
1864 PendingRelocs.push_back(std::make_pair(
Value, RE));
1865 }
else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1866 int64_t Addend =
Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
1867 for (
auto I = PendingRelocs.begin();
I != PendingRelocs.end();) {
1870 if (MatchingValue ==
Value &&
1871 RelType == getMatchingLoRelocation(Reloc.
RelType) &&
1874 if (
Value.SymbolName)
1878 I = PendingRelocs.erase(
I);
1883 if (
Value.SymbolName)
1888 if (RelType == ELF::R_MIPS_32)
1889 Value.Addend += Opcode;
1890 else if (RelType == ELF::R_MIPS_PC16)
1891 Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1892 else if (RelType == ELF::R_MIPS_PC19_S2)
1893 Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1894 else if (RelType == ELF::R_MIPS_PC21_S2)
1895 Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1896 else if (RelType == ELF::R_MIPS_PC26_S2)
1897 Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
1898 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1903 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1904 || r_type == ELF::R_MIPS_GOT_DISP) {
1905 auto [
I, Inserted] = GOTSymbolOffsets.
try_emplace(TargetName);
1907 I->second = allocateGOTEntries(1);
1909 if (
Value.SymbolName)
1913 }
else if (RelType == ELF::R_MIPS_26) {
1919 StubMap::const_iterator i = Stubs.find(
Value);
1920 if (i != Stubs.end()) {
1927 Stubs[
Value] = Section.getStubOffset();
1932 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1936 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1937 ELF::R_MIPS_HI16,
Value.Addend);
1939 StubTargetAddr - Section.getAddress() + 4,
1940 ELF::R_MIPS_LO16,
Value.Addend);
1941 if (
Value.SymbolName) {
1952 StubTargetAddr - Section.getAddress(),
1953 ELF::R_MIPS_HIGHEST,
Value.Addend);
1955 StubTargetAddr - Section.getAddress() + 4,
1956 ELF::R_MIPS_HIGHER,
Value.Addend);
1958 StubTargetAddr - Section.getAddress() + 12,
1959 ELF::R_MIPS_HI16,
Value.Addend);
1961 StubTargetAddr - Section.getAddress() + 20,
1962 ELF::R_MIPS_LO16,
Value.Addend);
1963 if (
Value.SymbolName) {
1977 Section.advanceStubOffset(getMaxStubSize());
1980 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1984 if (RelType == ELF::R_PPC64_REL24) {
1994 bool RangeOverflow =
false;
1997 if (AbiVariant != 2) {
2001 if (
auto Err = findOPDEntrySection(Obj, ObjSectionToID,
Value))
2002 return std::move(Err);
2006 if (
Value.SectionID == SectionID){
2007 uint8_t SymOther = Symbol->getOther();
2013 int64_t delta =
static_cast<int64_t
>(
Target - RelocTarget);
2015 if (SignExtend64<26>(delta) != delta) {
2016 RangeOverflow =
true;
2017 }
else if ((AbiVariant != 2) ||
2018 (AbiVariant == 2 &&
Value.SectionID == SectionID)) {
2023 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID) ||
2027 auto [It, Inserted] = Stubs.try_emplace(
Value);
2030 resolveRelocation(Section,
Offset,
2031 Section.getLoadAddressWithOffset(It->second),
2037 It->second = Section.getStubOffset();
2039 Section.getAddressWithOffset(Section.getStubOffset()),
2042 ELF::R_PPC64_ADDR64,
Value.Addend);
2048 uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
2050 StubRelocOffset += 2;
2053 ELF::R_PPC64_ADDR16_HIGHEST,
Value.Addend);
2055 ELF::R_PPC64_ADDR16_HIGHER,
Value.Addend);
2057 ELF::R_PPC64_ADDR16_HI,
Value.Addend);
2059 ELF::R_PPC64_ADDR16_LO,
Value.Addend);
2061 if (
Value.SymbolName) {
2075 Section.getLoadAddressWithOffset(Section.getStubOffset()),
2077 Section.advanceStubOffset(getMaxStubSize());
2079 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID)) {
2081 if (AbiVariant == 2)
2087 }
else if (RelType == ELF::R_PPC64_TOC16 ||
2088 RelType == ELF::R_PPC64_TOC16_DS ||
2089 RelType == ELF::R_PPC64_TOC16_LO ||
2090 RelType == ELF::R_PPC64_TOC16_LO_DS ||
2091 RelType == ELF::R_PPC64_TOC16_HI ||
2092 RelType == ELF::R_PPC64_TOC16_HA) {
2104 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
2105 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
2106 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
2107 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
2108 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
2109 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
2114 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
2115 return std::move(Err);
2125 if (RelType == ELF::R_PPC64_TOC) {
2126 RelType = ELF::R_PPC64_ADDR64;
2127 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
2128 return std::move(Err);
2129 }
else if (TargetName ==
".TOC.") {
2130 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
2131 return std::move(Err);
2132 Value.Addend += Addend;
2137 if (
Value.SymbolName)
2143 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
2153 LLVM_DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
2157 StubMap::const_iterator i = Stubs.find(
Value);
2158 uintptr_t StubAddress;
2159 if (i != Stubs.end()) {
2160 StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
2166 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
2168 alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
2169 unsigned StubOffset = StubAddress - BaseAddress;
2171 Stubs[
Value] = StubOffset;
2175 if (
Value.SymbolName)
2179 Section.advanceStubOffset(getMaxStubSize());
2182 if (RelType == ELF::R_390_GOTENT)
2183 resolveRelocation(Section,
Offset, StubAddress + 8, ELF::R_390_PC32DBL,
2186 resolveRelocation(Section,
Offset, StubAddress, RelType, Addend);
2188 if (RelType == ELF::R_X86_64_PLT32) {
2209 auto [It, Inserted] = Stubs.try_emplace(
Value);
2210 uintptr_t StubAddress;
2212 StubAddress = uintptr_t(Section->getAddress()) + It->second;
2218 uintptr_t BaseAddress = uintptr_t(Section->getAddress());
2219 StubAddress =
alignTo(BaseAddress + Section->getStubOffset(),
2220 getStubAlignment());
2221 unsigned StubOffset = StubAddress - BaseAddress;
2222 It->second = StubOffset;
2226 Section->advanceStubOffset(getMaxStubSize());
2229 uint64_t GOTOffset = allocateGOTEntries(1);
2235 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
2236 ELF::R_X86_64_PC32);
2240 computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
2245 resolveRelocation(*Section,
Offset, StubAddress, ELF::R_X86_64_PC32,
2249 computePlaceholderAddress(SectionID,
Offset));
2250 processSimpleRelocation(SectionID,
Offset, ELF::R_X86_64_PC32,
Value);
2252 }
else if (RelType == ELF::R_X86_64_GOTPCREL ||
2253 RelType == ELF::R_X86_64_GOTPCRELX ||
2254 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
2255 uint64_t GOTOffset = allocateGOTEntries(1);
2256 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
2257 ELF::R_X86_64_PC32);
2261 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
2262 if (
Value.SymbolName)
2266 }
else if (RelType == ELF::R_X86_64_GOT64) {
2268 uint64_t GOTOffset = allocateGOTEntries(1);
2270 ELF::R_X86_64_64, 0);
2274 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
2275 if (
Value.SymbolName)
2279 }
else if (RelType == ELF::R_X86_64_GOTPC32) {
2283 (void)allocateGOTEntries(0);
2284 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC32);
2285 }
else if (RelType == ELF::R_X86_64_GOTPC64) {
2286 (void)allocateGOTEntries(0);
2287 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC64);
2288 }
else if (RelType == ELF::R_X86_64_GOTOFF64) {
2290 (void)allocateGOTEntries(0);
2291 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2292 }
else if (RelType == ELF::R_X86_64_PC32) {
2294 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2295 }
else if (RelType == ELF::R_X86_64_PC64) {
2297 computePlaceholderAddress(SectionID,
Offset));
2298 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2299 }
else if (RelType == ELF::R_X86_64_GOTTPOFF) {
2300 processX86_64GOTTPOFFRelocation(SectionID,
Offset,
Value, Addend);
2301 }
else if (RelType == ELF::R_X86_64_TLSGD ||
2302 RelType == ELF::R_X86_64_TLSLD) {
2305 auto &GetAddrRelocation = *RelI;
2306 processX86_64TLSRelocation(SectionID,
Offset, RelType,
Value, Addend,
2309 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2315 if (RelType == ELF::R_RISCV_GOT_HI20 ||
2316 RelType == ELF::R_RISCV_PCREL_HI20 ||
2317 RelType == ELF::R_RISCV_TPREL_HI20 ||
2318 RelType == ELF::R_RISCV_TLS_GD_HI20 ||
2319 RelType == ELF::R_RISCV_TLS_GOT_HI20) {
2321 PendingRelocs.push_back({
Value, RE});
2323 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2327 computePlaceholderAddress(SectionID,
Offset));
2329 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2334void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(
unsigned SectionID,
2345 struct CodeSequence {
2357 std::array<CodeSequence, 2> CodeSequences;
2361 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2362 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2364 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00
2367 CodeSequences[0].ExpectedCodeSequence =
2369 CodeSequences[0].TLSSequenceOffset = 12;
2371 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2372 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2373 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2376 CodeSequences[0].TpoffRelocationOffset = 12;
2381 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2382 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
2383 0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00
2385 CodeSequences[1].ExpectedCodeSequence =
2387 CodeSequences[1].TLSSequenceOffset = 3;
2389 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2390 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
2391 0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2394 CodeSequences[1].TpoffRelocationOffset = 10;
2399 for (
const auto &
C : CodeSequences) {
2400 assert(
C.ExpectedCodeSequence.size() ==
C.NewCodeSequence.size() &&
2401 "Old and new code sequences must have the same size");
2403 if (
Offset <
C.TLSSequenceOffset ||
2404 (
Offset -
C.TLSSequenceOffset +
C.NewCodeSequence.size()) >
2411 auto TLSSequenceStartOffset =
Offset -
C.TLSSequenceOffset;
2412 auto *TLSSequence =
Section.getAddressWithOffset(TLSSequenceStartOffset);
2414 C.ExpectedCodeSequence) {
2418 memcpy(TLSSequence,
C.NewCodeSequence.data(),
C.NewCodeSequence.size());
2425 TLSSequenceStartOffset +
C.TpoffRelocationOffset,
2426 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2428 if (
Value.SymbolName)
2441 uint64_t GOTOffset = allocateGOTEntries(1);
2442 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
2443 ELF::R_X86_64_PC32);
2445 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_TPOFF64);
2446 if (
Value.SymbolName)
2453void RuntimeDyldELF::processX86_64TLSRelocation(
2466 bool IsSmallCodeModel;
2468 bool IsGOTPCRel =
false;
2470 switch (GetAddrRelocation.
getType()) {
2471 case ELF::R_X86_64_GOTPCREL:
2472 case ELF::R_X86_64_REX_GOTPCRELX:
2473 case ELF::R_X86_64_GOTPCRELX:
2476 case ELF::R_X86_64_PLT32:
2477 IsSmallCodeModel =
true;
2479 case ELF::R_X86_64_PLTOFF64:
2480 IsSmallCodeModel =
false;
2484 "invalid TLS relocations for General/Local Dynamic TLS Model: "
2485 "expected PLT or GOT relocation for __tls_get_addr function");
2496 if (RelType == ELF::R_X86_64_TLSGD) {
2501 if (IsSmallCodeModel) {
2503 static const std::initializer_list<uint8_t> CodeSequence = {
2505 0x48, 0x8d, 0x3d, 0x00, 0x00,
2509 0xe8, 0x00, 0x00, 0x00, 0x00
2512 TLSSequenceOffset = 4;
2516 static const std::initializer_list<uint8_t> CodeSequence = {
2518 0x48, 0x8d, 0x3d, 0x00, 0x00,
2522 0xff, 0x15, 0x00, 0x00, 0x00,
2526 TLSSequenceOffset = 4;
2531 static const std::initializer_list<uint8_t> SmallSequence = {
2532 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2534 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2538 TpoffRelocOffset = 12;
2540 static const std::initializer_list<uint8_t> CodeSequence = {
2541 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2543 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2549 TLSSequenceOffset = 3;
2552 static const std::initializer_list<uint8_t> LargeSequence = {
2553 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2555 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
2557 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
2560 TpoffRelocOffset = 12;
2567 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2568 if (
Value.SymbolName)
2572 }
else if (RelType == ELF::R_X86_64_TLSLD) {
2573 if (IsSmallCodeModel) {
2575 static const std::initializer_list<uint8_t> CodeSequence = {
2576 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00,
2577 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00
2580 TLSSequenceOffset = 3;
2583 static const std::initializer_list<uint8_t> SmallSequence = {
2585 0x64, 0x48, 0x8b, 0x04, 0x25,
2586 0x00, 0x00, 0x00, 0x00
2592 static const std::initializer_list<uint8_t> CodeSequence = {
2593 0x48, 0x8d, 0x3d, 0x00,
2595 0xff, 0x15, 0x00, 0x00,
2600 TLSSequenceOffset = 3;
2604 static const std::initializer_list<uint8_t> SmallSequence = {
2605 0x0f, 0x1f, 0x40, 0x00,
2606 0x64, 0x48, 0x8b, 0x04, 0x25,
2607 0x00, 0x00, 0x00, 0x00
2614 static const std::initializer_list<uint8_t> CodeSequence = {
2615 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2617 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2623 TLSSequenceOffset = 3;
2626 static const std::initializer_list<uint8_t> LargeSequence = {
2628 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
2630 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
2639 "Old and new code sequences must have the same size");
2642 if (
Offset < TLSSequenceOffset ||
2643 (
Offset - TLSSequenceOffset + NewCodeSequence.
size()) >
2648 auto *TLSSequence =
Section.getAddressWithOffset(
Offset - TLSSequenceOffset);
2650 ExpectedCodeSequence) {
2652 "invalid TLS sequence for Global/Local Dynamic TLS Model");
2655 memcpy(TLSSequence, NewCodeSequence.
data(), NewCodeSequence.
size());
2694uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned no) {
2695 if (GOTSectionID == 0) {
2702 CurrentGOTIndex += no;
2707 unsigned GOTRelType) {
2708 auto E = GOTOffsetMap.insert({
Value, 0});
2710 uint64_t GOTOffset = allocateGOTEntries(1);
2714 computeGOTOffsetRE(GOTOffset,
Value.Offset, GOTRelType);
2715 if (
Value.SymbolName)
2720 E.first->second = GOTOffset;
2723 return E.first->second;
2726void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID,
2746 if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
2747 if (IFuncStubSectionID == 0) {
2750 IFuncStubSectionID =
Sections.size();
2752 SectionEntry(
".text.__llvm_IFuncStubs",
nullptr, 0, 0, 0));
2754 IFuncStubOffset = 64;
2762 IFuncStubOffset += getMaxIFuncStubSize();
2769 if (!PendingRelocs.empty())
2770 return make_error<RuntimeDyldError>(
"Can't find matching LO16 reloc");
2774 if (IFuncStubSectionID != 0) {
2776 IFuncStubOffset, 1, IFuncStubSectionID,
".text.__llvm_IFuncStubs");
2777 if (!IFuncStubsAddr)
2778 return make_error<RuntimeDyldError>(
2779 "Unable to allocate memory for IFunc stubs!");
2781 SectionEntry(
".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
2782 IFuncStubOffset, 0);
2784 createIFuncResolver(IFuncStubsAddr);
2787 << IFuncStubSectionID <<
" Addr: "
2788 <<
Sections[IFuncStubSectionID].getAddress() <<
'\n');
2789 for (
auto &IFuncStub : IFuncStubs) {
2790 auto &Symbol = IFuncStub.OriginalSymbol;
2792 <<
" Offset: " <<
format(
"%p", Symbol.getOffset())
2793 <<
" IFuncStubOffset: "
2794 <<
format(
"%p\n", IFuncStub.StubOffset));
2795 createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
2796 Symbol.getSectionID(), Symbol.getOffset());
2799 IFuncStubSectionID = 0;
2800 IFuncStubOffset = 0;
2805 if (GOTSectionID != 0) {
2809 GOTSectionID,
".got",
false);
2811 return make_error<RuntimeDyldError>(
"Unable to allocate memory for GOT!");
2818 memset(
Addr, 0, TotalSize);
2824 if (!SI->relocations().empty()) {
2827 return make_error<RuntimeDyldError>(
2831 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
2832 assert(i != SectionMap.end());
2836 GOTSymbolOffsets.
clear();
2841 ObjSectionToIDMap::iterator i, e;
2842 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
2852 if (
Name ==
".eh_frame") {
2853 UnregisteredEHFrameSections.
push_back(i->second);
2858 GOTOffsetMap.clear();
2860 CurrentGOTIndex = 0;
2869void RuntimeDyldELF::createIFuncResolver(
uint8_t *
Addr)
const {
2889 0x41, 0xff, 0x53, 0x08,
2901 static_assert(
sizeof(StubCode) <= 64,
2902 "maximum size of the IFunc resolver is 64B");
2903 memcpy(
Addr, StubCode,
sizeof(StubCode));
2906 "IFunc resolver is not supported for target architecture");
2910void RuntimeDyldELF::createIFuncStub(
unsigned IFuncStubSectionID,
2913 unsigned IFuncSectionID,
2915 auto &IFuncStubSection =
Sections[IFuncStubSectionID];
2916 auto *
Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);
2940 uint64_t GOT1 = allocateGOTEntries(2);
2944 IFuncResolverOffset, {});
2946 RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
2950 0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00,
2953 assert(
sizeof(StubCode) <= getMaxIFuncStubSize() &&
2954 "IFunc stub size must not exceed getMaxIFuncStubSize()");
2955 memcpy(
Addr, StubCode,
sizeof(StubCode));
2959 resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
2960 GOT1 - 4, ELF::R_X86_64_PC32);
2966unsigned RuntimeDyldELF::getMaxIFuncStubSize()
const {
2973bool RuntimeDyldELF::relocationNeedsGot(
const RelocationRef &R)
const {
2974 unsigned RelTy =
R.getType();
2976 return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
2977 RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;
2980 return RelTy == ELF::R_LARCH_GOT_PC_HI20 ||
2981 RelTy == ELF::R_LARCH_GOT_PC_LO12 ||
2982 RelTy == ELF::R_LARCH_GOT64_PC_HI12 ||
2983 RelTy == ELF::R_LARCH_GOT64_PC_LO20;
2986 return RelTy == ELF::R_X86_64_GOTPCREL ||
2987 RelTy == ELF::R_X86_64_GOTPCRELX ||
2988 RelTy == ELF::R_X86_64_GOT64 ||
2989 RelTy == ELF::R_X86_64_REX_GOTPCRELX;
2993bool RuntimeDyldELF::relocationNeedsStub(
const RelocationRef &R)
const {
2997 switch (
R.getType()) {
3002 case ELF::R_X86_64_GOTPCREL:
3003 case ELF::R_X86_64_GOTPCRELX:
3004 case ELF::R_X86_64_REX_GOTPCRELX:
3005 case ELF::R_X86_64_GOTPC64:
3006 case ELF::R_X86_64_GOT64:
3007 case ELF::R_X86_64_GOTOFF64:
3008 case ELF::R_X86_64_PC32:
3009 case ELF::R_X86_64_PC64:
3010 case ELF::R_X86_64_64:
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
Given that RA is a live value
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
static void or32le(void *P, int32_t V)
static void or32AArch64Imm(void *L, uint64_t Imm)
static void write(bool isBE, void *P, T V)
static uint64_t getBits(uint64_t Val, int Start, int End)
static void write32AArch64Addr(void *L, uint64_t Imm)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
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.
Symbol resolution interface.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
RelocationEntry - used to represent relocations internally in the dynamic linker.
uint32_t RelType
RelType - relocation type.
uint64_t Offset
Offset - offset into the section.
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
unsigned SectionID
SectionID - the section this relocation points to.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
void registerEHFrames() override
size_t getGOTEntrySize() override
~RuntimeDyldELF() override
static std::unique_ptr< RuntimeDyldELF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override
DenseMap< SID, SID > SectionToGOTMap
bool isCompatibleFile(const object::ObjectFile &Obj) const override
std::unique_ptr< RuntimeDyld::LoadedObjectInfo > loadObject(const object::ObjectFile &O) override
RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
Expected< 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 ...
std::map< SectionRef, unsigned > ObjSectionToIDMap
void writeInt32BE(uint8_t *Addr, uint32_t Value)
void writeInt64BE(uint8_t *Addr, uint64_t Value)
std::map< RelocationValueRef, uintptr_t > StubMap
void writeInt16BE(uint8_t *Addr, uint16_t Value)
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
bool IsTargetLittleEndian
RuntimeDyld::MemoryManager & MemMgr
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
uint64_t getSectionLoadAddress(unsigned SectionID) const
RTDyldSymbolTable GlobalSymbolTable
Expected< ObjSectionToIDMap > loadObjectImpl(const object::ObjectFile &Obj)
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.
virtual uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName)=0
Allocate a memory block of (at least) the given size suitable for executable code.
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.
virtual bool allowStubAllocation() const
Override to return false to tell LLVM no stub space will be needed.
SectionEntry - represents a section emitted into memory by the dynamic linker.
void push_back(const T &Elt)
iterator find(StringRef Key)
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Symbol info for RuntimeDyld.
Target - Wrapper for Target specific information.
static LLVM_ABI StringRef getArchTypePrefix(ArchType Kind)
Get the "prefix" canonical name for the Kind architecture.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Expected< uint32_t > getFlags() const
Get symbol flags (bitwise OR of SymbolRef::Flags)
DataRefImpl getRawDataRefImpl() const
StringRef getData() const
bool isLittleEndian() const
StringRef getFileName() const
virtual unsigned getPlatformFlags() const =0
Returns platform-specific object flags, if any.
static bool classof(const Binary *v)
Expected< const Elf_Sym * > getSymbol(DataRefImpl Sym) const
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object, bool InitContent=true)
Expected< int64_t > getAddend() const
This class is the base class for all object file types.
virtual section_iterator section_end() const =0
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
section_iterator_range sections() const
virtual StringRef getFileFormatName() const =0
virtual section_iterator section_begin() const =0
This is a value type class that represents a single relocation in the list of relocations in the obje...
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
bool isText() const
Whether this section contains instructions.
Expected< StringRef > getName() const
This is a value type class that represents a single symbol in the list of symbols in the object file.
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
virtual basic_symbol_iterator symbol_end() const =0
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
static int64_t decodePPC64LocalEntryOffset(unsigned Other)
@ Resolved
Queried, materialization begun.
NodeAddr< InstrNode * > Instr
void write32le(void *P, uint32_t V)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
static uint16_t applyPPChighera(uint64_t value)
static uint16_t applyPPChi(uint64_t value)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
static void applyITypeImmRISCV(uint8_t *InstrAddr, uint32_t Imm)
static uint16_t applyPPChighesta(uint64_t value)
static uint16_t applyPPChighest(uint64_t value)
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
static uint16_t applyPPCha(uint64_t value)
static void applyUTypeImmRISCV(uint8_t *InstrAddr, uint32_t Imm)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
static uint16_t applyPPClo(uint64_t value)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Ref
The access may reference the value stored in memory.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
static uint16_t applyPPChigher(uint64_t value)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
static void or32le(void *P, int32_t V)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
static uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo)
const char * toString(DWARFSectionKind Kind)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, uint32_t type)
void consumeError(Error Err)
Consume a Error without doing anything.
static void write32AArch64Addr(void *T, uint64_t s, uint64_t p, int shift)
Implement std::hash so that hash_code can be used in STL containers.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...