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;
672void RuntimeDyldELF::resolveLoongArch64Branch(
unsigned SectionID,
676 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an LoongArch64 branch relocation.\n");
678 if (resolveLoongArch64ShortBranch(SectionID, RelI,
Value))
683 unsigned RelType = RelI->getType();
685 StubMap::const_iterator i = Stubs.find(
Value);
686 if (i != Stubs.end()) {
687 resolveRelocation(Section,
Offset,
699 ELF::R_LARCH_ABS_HI20,
Value.Addend);
701 ELF::R_LARCH_ABS_LO12,
Value.Addend);
703 ELF::R_LARCH_ABS64_LO20,
Value.Addend);
705 ELF::R_LARCH_ABS64_HI12,
Value.Addend);
706 if (
Value.SymbolName) {
718 resolveRelocation(Section,
Offset,
722 Section.advanceStubOffset(getMaxStubSize());
727 return Hi == 63 ? Val >>
Lo : (Val & (((1ULL << (
Hi + 1)) - 1))) >>
Lo;
730void RuntimeDyldELF::resolveLoongArch64Relocation(
const SectionEntry &Section,
734 auto *TargetPtr = Section.getAddressWithOffset(
Offset);
737 LLVM_DEBUG(
dbgs() <<
"resolveLoongArch64Relocation, LocalAddress: 0x"
739 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
740 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
742 <<
format(
"%llx", Addend) <<
"\n");
748 case ELF::R_LARCH_32:
752 case ELF::R_LARCH_64:
755 case ELF::R_LARCH_32_PCREL:
759 case ELF::R_LARCH_B26: {
764 Instr = (
Instr & 0xfc000000) | Imm15_0 | Imm25_16;
767 case ELF::R_LARCH_CALL36: {
772 Pcaddu18i = (Pcaddu18i & 0xfe00001f) | Imm35_16;
775 Jirl = (Jirl & 0xfc0003ff) | Imm15_0;
778 case ELF::R_LARCH_GOT_PC_HI20:
779 case ELF::R_LARCH_PCALA_HI20: {
782 (
Target + (
Target & 0x800)) & ~static_cast<uint64_t>(0xfff);
783 uint64_t PCPage = FinalAddress & ~static_cast<uint64_t>(0xfff);
784 int64_t PageDelta = TargetPage - PCPage;
790 case ELF::R_LARCH_GOT_PC_LO12:
791 case ELF::R_LARCH_PCALA_LO12: {
794 uint32_t Imm11_0 = TargetOffset << 10;
798 case ELF::R_LARCH_ABS_HI20: {
805 case ELF::R_LARCH_ABS_LO12: {
812 case ELF::R_LARCH_ABS64_LO20: {
819 case ELF::R_LARCH_ABS64_HI12: {
826 case ELF::R_LARCH_ADD32:
831 case ELF::R_LARCH_SUB32:
836 case ELF::R_LARCH_ADD64:
840 case ELF::R_LARCH_SUB64:
847void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
855 if (
auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
856 unsigned AbiVariant = E->getPlatformFlags();
865 ObjSectionToIDMap &LocalSections,
877 for (
auto &Section : Obj.
sections()) {
887 if (
auto SectionIDOrErr =
891 return SectionIDOrErr.takeError();
906 ObjSectionToIDMap &LocalSections,
926 if (RelSectionName !=
".opd")
930 e = si->relocation_end();
935 if (TypeFunc != ELF::R_PPC64_ADDR64) {
940 uint64_t TargetSymbolOffset = i->getOffset();
943 if (
auto AddendOrErr = i->getAddend())
944 Addend = *AddendOrErr;
946 return AddendOrErr.takeError();
954 if (TypeTOC != ELF::R_PPC64_TOC)
960 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
964 if (
auto TSIOrErr = TargetSymbol->
getSection())
967 return TSIOrErr.takeError();
970 bool IsCode = TSI->
isText();
975 return SectionIDOrErr.takeError();
976 Rel.
Addend = (intptr_t)Addend;
991 return (
value >> 16) & 0xffff;
995 return ((
value + 0x8000) >> 16) & 0xffff;
999 return (
value >> 32) & 0xffff;
1003 return ((
value + 0x8000) >> 32) & 0xffff;
1007 return (
value >> 48) & 0xffff;
1011 return ((
value + 0x8000) >> 48) & 0xffff;
1014void RuntimeDyldELF::resolvePPC32Relocation(
const SectionEntry &Section,
1017 uint8_t *LocalAddress = Section.getAddressWithOffset(
Offset);
1022 case ELF::R_PPC_ADDR16_LO:
1025 case ELF::R_PPC_ADDR16_HI:
1028 case ELF::R_PPC_ADDR16_HA:
1034void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
1042 case ELF::R_PPC64_ADDR16:
1045 case ELF::R_PPC64_ADDR16_DS:
1048 case ELF::R_PPC64_ADDR16_LO:
1051 case ELF::R_PPC64_ADDR16_LO_DS:
1054 case ELF::R_PPC64_ADDR16_HI:
1055 case ELF::R_PPC64_ADDR16_HIGH:
1058 case ELF::R_PPC64_ADDR16_HA:
1059 case ELF::R_PPC64_ADDR16_HIGHA:
1062 case ELF::R_PPC64_ADDR16_HIGHER:
1065 case ELF::R_PPC64_ADDR16_HIGHERA:
1068 case ELF::R_PPC64_ADDR16_HIGHEST:
1071 case ELF::R_PPC64_ADDR16_HIGHESTA:
1074 case ELF::R_PPC64_ADDR14: {
1077 uint8_t aalk = *(LocalAddress + 3);
1080 case ELF::R_PPC64_REL16_LO: {
1085 case ELF::R_PPC64_REL16_HI: {
1090 case ELF::R_PPC64_REL16_HA: {
1095 case ELF::R_PPC64_ADDR32: {
1096 int64_t
Result =
static_cast<int64_t
>(
Value + Addend);
1097 if (SignExtend64<32>(Result) !=
Result)
1101 case ELF::R_PPC64_REL24: {
1103 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
1104 if (SignExtend64<26>(delta) != delta)
1108 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
1110 case ELF::R_PPC64_REL32: {
1112 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
1113 if (SignExtend64<32>(delta) != delta)
1117 case ELF::R_PPC64_REL64: {
1122 case ELF::R_PPC64_ADDR64:
1128void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
1136 case ELF::R_390_PC16DBL:
1137 case ELF::R_390_PLT16DBL: {
1139 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
1143 case ELF::R_390_PC32DBL:
1144 case ELF::R_390_PLT32DBL: {
1146 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
1150 case ELF::R_390_PC16: {
1152 assert(int16_t(Delta) == Delta &&
"R_390_PC16 overflow");
1156 case ELF::R_390_PC32: {
1158 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
1162 case ELF::R_390_PC64: {
1182void RuntimeDyldELF::resolveBPFRelocation(
const SectionEntry &Section,
1191 case ELF::R_BPF_NONE:
1192 case ELF::R_BPF_64_64:
1193 case ELF::R_BPF_64_32:
1194 case ELF::R_BPF_64_NODYLD32:
1196 case ELF::R_BPF_64_ABS64: {
1202 case ELF::R_BPF_64_ABS32: {
1214 uint32_t UpperImm = (Imm + 0x800) & 0xfffff000;
1216 Instr = (Instr & 0xfff) | UpperImm;
1222 Instr = (Instr & 0xfffff) | (LowerImm << 20);
1225void RuntimeDyldELF::resolveRISCVRelocation(
const SectionEntry &Section,
1231 std::string Err =
"Unimplemented reloc type: " + std::to_string(
Type);
1237 case ELF::R_RISCV_CALL:
1238 case ELF::R_RISCV_CALL_PLT: {
1246 case ELF::R_RISCV_HI20: {
1252 case ELF::R_RISCV_LO12_I: {
1258 case ELF::R_RISCV_GOT_HI20:
1259 case ELF::R_RISCV_PCREL_HI20: {
1273 case ELF::R_RISCV_PCREL_LO12_I: {
1274 for (
auto &&PendingReloc : PendingRelocs) {
1279 if (
Value + Addend == HIRelocPC) {
1282 auto PCOffset =
Symbol - HIRelocPC;
1289 "R_RISCV_PCREL_LO12_I without matching R_RISCV_PCREL_HI20");
1291 case ELF::R_RISCV_32_PCREL: {
1293 int64_t RealOffset =
Value + Addend - FinalAddress;
1294 int32_t TruncOffset =
Lo_32(RealOffset);
1299 case ELF::R_RISCV_32: {
1304 case ELF::R_RISCV_64: {
1309 case ELF::R_RISCV_ADD16: {
1314 case ELF::R_RISCV_ADD32: {
1319 case ELF::R_RISCV_ADD64: {
1324 case ELF::R_RISCV_SUB16: {
1329 case ELF::R_RISCV_SUB32: {
1334 case ELF::R_RISCV_SUB64: {
1369void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
1372 uint64_t SymOffset, SID SectionID) {
1375 resolveX86_64Relocation(Section,
Offset,
Value,
Type, Addend, SymOffset);
1412 resolveRISCVRelocation(Section,
Offset,
Value,
Type, Addend, SectionID);
1419void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID,
1426 if (
Value.SymbolName)
1433 bool IsLocal)
const {
1435 case ELF::R_MICROMIPS_GOT16:
1437 return ELF::R_MICROMIPS_LO16;
1439 case ELF::R_MICROMIPS_HI16:
1440 return ELF::R_MICROMIPS_LO16;
1441 case ELF::R_MIPS_GOT16:
1443 return ELF::R_MIPS_LO16;
1445 case ELF::R_MIPS_HI16:
1446 return ELF::R_MIPS_LO16;
1447 case ELF::R_MIPS_PCHI16:
1448 return ELF::R_MIPS_PCLO16;
1452 return ELF::R_MIPS_NONE;
1464bool RuntimeDyldELF::resolveAArch64ShortBranch(
1468 unsigned TargetSectionID;
1469 if (
Value.SymbolName) {
1476 const auto &
SymInfo = Loc->second;
1478 TargetSectionID =
SymInfo.getSectionID();
1479 TargetOffset =
SymInfo.getOffset();
1481 TargetSectionID =
Value.SectionID;
1487 if (TargetSectionID != SectionID)
1490 uint64_t SourceOffset = RelI->getOffset();
1495 if (!isInt<28>(TargetOffset +
Value.Addend - SourceOffset))
1499 if (
Value.SymbolName)
1507void RuntimeDyldELF::resolveAArch64Branch(
unsigned SectionID,
1512 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1516 unsigned RelType = RelI->getType();
1518 StubMap::const_iterator i = Stubs.find(
Value);
1519 if (i != Stubs.end()) {
1520 resolveRelocation(Section,
Offset,
1521 Section.getLoadAddressWithOffset(i->second), RelType, 0);
1523 }
else if (!resolveAArch64ShortBranch(SectionID, RelI,
Value)) {
1531 ELF::R_AARCH64_MOVW_UABS_G3,
Value.Addend);
1533 StubTargetAddr -
Section.getAddress() + 4,
1534 ELF::R_AARCH64_MOVW_UABS_G2_NC,
Value.Addend);
1536 StubTargetAddr -
Section.getAddress() + 8,
1537 ELF::R_AARCH64_MOVW_UABS_G1_NC,
Value.Addend);
1539 StubTargetAddr -
Section.getAddress() + 12,
1540 ELF::R_AARCH64_MOVW_UABS_G0_NC,
Value.Addend);
1542 if (
Value.SymbolName) {
1553 resolveRelocation(Section,
Offset,
1556 Section.advanceStubOffset(getMaxStubSize());
1564 const auto &Obj = cast<ELFObjectFileBase>(O);
1565 uint64_t RelType = RelI->getType();
1568 Addend = *AddendOrErr;
1576 if (
auto TargetNameOrErr = Symbol->getName())
1577 TargetName = *TargetNameOrErr;
1579 return TargetNameOrErr.takeError();
1581 LLVM_DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
1582 <<
" TargetName: " << TargetName <<
"\n");
1592 if (!SymTypeOrErr) {
1598 SymType = *SymTypeOrErr;
1601 const auto &
SymInfo = gsi->second;
1611 auto SectionOrErr = Symbol->getSection();
1612 if (!SectionOrErr) {
1622 bool isCode = si->
isText();
1625 Value.SectionID = *SectionIDOrErr;
1627 return SectionIDOrErr.takeError();
1628 Value.Addend = Addend;
1636 Value.Addend = Addend;
1642 if (!
Value.SymbolName)
1643 Value.SymbolName =
"";
1657 if ((RelType == ELF::R_AARCH64_CALL26 ||
1658 RelType == ELF::R_AARCH64_JUMP26) &&
1660 resolveAArch64Branch(SectionID,
Value, RelI, Stubs);
1661 }
else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
1664 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1665 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1666 ELF::R_AARCH64_ADR_PREL_PG_HI21);
1668 }
else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
1669 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1670 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1671 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
1673 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1676 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1677 RelType == ELF::R_ARM_JUMP24) {
1683 StubMap::const_iterator i = Stubs.find(
Value);
1684 if (i != Stubs.end()) {
1685 resolveRelocation(Section,
Offset,
1686 Section.getLoadAddressWithOffset(i->second), RelType,
1692 Stubs[
Value] = Section.getStubOffset();
1694 Section.getAddressWithOffset(Section.getStubOffset()));
1696 ELF::R_ARM_ABS32,
Value.Addend);
1697 if (
Value.SymbolName)
1704 Section.getLoadAddressWithOffset(Section.getStubOffset()), RelType,
1706 Section.advanceStubOffset(getMaxStubSize());
1710 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID,
Offset));
1711 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1712 RelType == ELF::R_ARM_ABS32) {
1713 Value.Addend += *Placeholder;
1714 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1716 Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1718 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1722 resolveLoongArch64Branch(SectionID,
Value, RelI, Stubs);
1723 }
else if (RelType == ELF::R_LARCH_GOT_PC_HI20 ||
1724 RelType == ELF::R_LARCH_GOT_PC_LO12) {
1725 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_LARCH_64);
1726 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1729 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1733 computePlaceholderAddress(SectionID,
Offset));
1735 if (RelType == ELF::R_MIPS_26) {
1743 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1745 Value.Addend += Addend;
1748 StubMap::const_iterator i = Stubs.find(
Value);
1749 if (i != Stubs.end()) {
1756 Stubs[
Value] = Section.getStubOffset();
1761 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1764 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1765 ELF::R_MIPS_HI16,
Value.Addend);
1767 StubTargetAddr - Section.getAddress() + 4,
1768 ELF::R_MIPS_LO16,
Value.Addend);
1770 if (
Value.SymbolName) {
1780 Section.advanceStubOffset(getMaxStubSize());
1782 }
else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1783 int64_t Addend = (Opcode & 0x0000ffff) << 16;
1785 PendingRelocs.push_back(std::make_pair(
Value, RE));
1786 }
else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1787 int64_t Addend =
Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
1788 for (
auto I = PendingRelocs.begin();
I != PendingRelocs.end();) {
1791 if (MatchingValue ==
Value &&
1792 RelType == getMatchingLoRelocation(Reloc.
RelType) &&
1795 if (
Value.SymbolName)
1799 I = PendingRelocs.erase(
I);
1804 if (
Value.SymbolName)
1809 if (RelType == ELF::R_MIPS_32)
1810 Value.Addend += Opcode;
1811 else if (RelType == ELF::R_MIPS_PC16)
1812 Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1813 else if (RelType == ELF::R_MIPS_PC19_S2)
1814 Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1815 else if (RelType == ELF::R_MIPS_PC21_S2)
1816 Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1817 else if (RelType == ELF::R_MIPS_PC26_S2)
1818 Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
1819 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1824 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1825 || r_type == ELF::R_MIPS_GOT_DISP) {
1826 auto [
I, Inserted] = GOTSymbolOffsets.
try_emplace(TargetName);
1828 I->second = allocateGOTEntries(1);
1830 if (
Value.SymbolName)
1834 }
else if (RelType == ELF::R_MIPS_26) {
1840 StubMap::const_iterator i = Stubs.find(
Value);
1841 if (i != Stubs.end()) {
1848 Stubs[
Value] = Section.getStubOffset();
1853 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1857 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1858 ELF::R_MIPS_HI16,
Value.Addend);
1860 StubTargetAddr - Section.getAddress() + 4,
1861 ELF::R_MIPS_LO16,
Value.Addend);
1862 if (
Value.SymbolName) {
1873 StubTargetAddr - Section.getAddress(),
1874 ELF::R_MIPS_HIGHEST,
Value.Addend);
1876 StubTargetAddr - Section.getAddress() + 4,
1877 ELF::R_MIPS_HIGHER,
Value.Addend);
1879 StubTargetAddr - Section.getAddress() + 12,
1880 ELF::R_MIPS_HI16,
Value.Addend);
1882 StubTargetAddr - Section.getAddress() + 20,
1883 ELF::R_MIPS_LO16,
Value.Addend);
1884 if (
Value.SymbolName) {
1898 Section.advanceStubOffset(getMaxStubSize());
1901 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1905 if (RelType == ELF::R_PPC64_REL24) {
1915 bool RangeOverflow =
false;
1918 if (AbiVariant != 2) {
1922 if (
auto Err = findOPDEntrySection(Obj, ObjSectionToID,
Value))
1923 return std::move(Err);
1927 if (
Value.SectionID == SectionID){
1928 uint8_t SymOther = Symbol->getOther();
1934 int64_t delta =
static_cast<int64_t
>(
Target - RelocTarget);
1936 if (SignExtend64<26>(delta) != delta) {
1937 RangeOverflow =
true;
1938 }
else if ((AbiVariant != 2) ||
1939 (AbiVariant == 2 &&
Value.SectionID == SectionID)) {
1944 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID) ||
1948 StubMap::const_iterator i = Stubs.find(
Value);
1949 if (i != Stubs.end()) {
1951 resolveRelocation(Section,
Offset,
1952 Section.getLoadAddressWithOffset(i->second),
1958 Stubs[
Value] = Section.getStubOffset();
1960 Section.getAddressWithOffset(Section.getStubOffset()),
1963 ELF::R_PPC64_ADDR64,
Value.Addend);
1969 uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
1971 StubRelocOffset += 2;
1974 ELF::R_PPC64_ADDR16_HIGHEST,
Value.Addend);
1976 ELF::R_PPC64_ADDR16_HIGHER,
Value.Addend);
1978 ELF::R_PPC64_ADDR16_HI,
Value.Addend);
1980 ELF::R_PPC64_ADDR16_LO,
Value.Addend);
1982 if (
Value.SymbolName) {
1996 Section.getLoadAddressWithOffset(Section.getStubOffset()),
1998 Section.advanceStubOffset(getMaxStubSize());
2000 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID)) {
2002 if (AbiVariant == 2)
2008 }
else if (RelType == ELF::R_PPC64_TOC16 ||
2009 RelType == ELF::R_PPC64_TOC16_DS ||
2010 RelType == ELF::R_PPC64_TOC16_LO ||
2011 RelType == ELF::R_PPC64_TOC16_LO_DS ||
2012 RelType == ELF::R_PPC64_TOC16_HI ||
2013 RelType == ELF::R_PPC64_TOC16_HA) {
2025 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
2026 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
2027 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
2028 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
2029 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
2030 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
2035 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
2036 return std::move(Err);
2046 if (RelType == ELF::R_PPC64_TOC) {
2047 RelType = ELF::R_PPC64_ADDR64;
2048 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
2049 return std::move(Err);
2050 }
else if (TargetName ==
".TOC.") {
2051 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
2052 return std::move(Err);
2053 Value.Addend += Addend;
2058 if (
Value.SymbolName)
2064 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
2074 LLVM_DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
2078 StubMap::const_iterator i = Stubs.find(
Value);
2079 uintptr_t StubAddress;
2080 if (i != Stubs.end()) {
2081 StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
2087 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
2089 alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
2090 unsigned StubOffset = StubAddress - BaseAddress;
2092 Stubs[
Value] = StubOffset;
2096 if (
Value.SymbolName)
2100 Section.advanceStubOffset(getMaxStubSize());
2103 if (RelType == ELF::R_390_GOTENT)
2104 resolveRelocation(Section,
Offset, StubAddress + 8, ELF::R_390_PC32DBL,
2107 resolveRelocation(Section,
Offset, StubAddress, RelType, Addend);
2109 if (RelType == ELF::R_X86_64_PLT32) {
2130 StubMap::const_iterator i = Stubs.find(
Value);
2131 uintptr_t StubAddress;
2132 if (i != Stubs.end()) {
2133 StubAddress = uintptr_t(Section->getAddress()) + i->second;
2139 uintptr_t BaseAddress = uintptr_t(Section->getAddress());
2140 StubAddress =
alignTo(BaseAddress + Section->getStubOffset(),
2141 getStubAlignment());
2142 unsigned StubOffset = StubAddress - BaseAddress;
2143 Stubs[
Value] = StubOffset;
2147 Section->advanceStubOffset(getMaxStubSize());
2150 uint64_t GOTOffset = allocateGOTEntries(1);
2156 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
2157 ELF::R_X86_64_PC32);
2161 computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
2166 resolveRelocation(*Section,
Offset, StubAddress, ELF::R_X86_64_PC32,
2170 computePlaceholderAddress(SectionID,
Offset));
2171 processSimpleRelocation(SectionID,
Offset, ELF::R_X86_64_PC32,
Value);
2173 }
else if (RelType == ELF::R_X86_64_GOTPCREL ||
2174 RelType == ELF::R_X86_64_GOTPCRELX ||
2175 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
2176 uint64_t GOTOffset = allocateGOTEntries(1);
2177 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
2178 ELF::R_X86_64_PC32);
2182 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
2183 if (
Value.SymbolName)
2187 }
else if (RelType == ELF::R_X86_64_GOT64) {
2189 uint64_t GOTOffset = allocateGOTEntries(1);
2191 ELF::R_X86_64_64, 0);
2195 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
2196 if (
Value.SymbolName)
2200 }
else if (RelType == ELF::R_X86_64_GOTPC32) {
2204 (void)allocateGOTEntries(0);
2205 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC32);
2206 }
else if (RelType == ELF::R_X86_64_GOTPC64) {
2207 (void)allocateGOTEntries(0);
2208 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC64);
2209 }
else if (RelType == ELF::R_X86_64_GOTOFF64) {
2211 (void)allocateGOTEntries(0);
2212 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2213 }
else if (RelType == ELF::R_X86_64_PC32) {
2215 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2216 }
else if (RelType == ELF::R_X86_64_PC64) {
2218 computePlaceholderAddress(SectionID,
Offset));
2219 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2220 }
else if (RelType == ELF::R_X86_64_GOTTPOFF) {
2221 processX86_64GOTTPOFFRelocation(SectionID,
Offset,
Value, Addend);
2222 }
else if (RelType == ELF::R_X86_64_TLSGD ||
2223 RelType == ELF::R_X86_64_TLSLD) {
2226 auto &GetAddrRelocation = *RelI;
2227 processX86_64TLSRelocation(SectionID,
Offset, RelType,
Value, Addend,
2230 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2236 if (RelType == ELF::R_RISCV_GOT_HI20 ||
2237 RelType == ELF::R_RISCV_PCREL_HI20 ||
2238 RelType == ELF::R_RISCV_TPREL_HI20 ||
2239 RelType == ELF::R_RISCV_TLS_GD_HI20 ||
2240 RelType == ELF::R_RISCV_TLS_GOT_HI20) {
2242 PendingRelocs.push_back({
Value, RE});
2244 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2248 computePlaceholderAddress(SectionID,
Offset));
2250 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
2255void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(
unsigned SectionID,
2266 struct CodeSequence {
2278 std::array<CodeSequence, 2> CodeSequences;
2282 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2283 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2285 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00
2288 CodeSequences[0].ExpectedCodeSequence =
2290 CodeSequences[0].TLSSequenceOffset = 12;
2292 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2293 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2294 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2297 CodeSequences[0].TpoffRelocationOffset = 12;
2302 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2303 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
2304 0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00
2306 CodeSequences[1].ExpectedCodeSequence =
2308 CodeSequences[1].TLSSequenceOffset = 3;
2310 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2311 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
2312 0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2315 CodeSequences[1].TpoffRelocationOffset = 10;
2320 for (
const auto &
C : CodeSequences) {
2321 assert(
C.ExpectedCodeSequence.size() ==
C.NewCodeSequence.size() &&
2322 "Old and new code sequences must have the same size");
2324 if (
Offset <
C.TLSSequenceOffset ||
2325 (
Offset -
C.TLSSequenceOffset +
C.NewCodeSequence.size()) >
2332 auto TLSSequenceStartOffset =
Offset -
C.TLSSequenceOffset;
2333 auto *TLSSequence =
Section.getAddressWithOffset(TLSSequenceStartOffset);
2335 C.ExpectedCodeSequence) {
2339 memcpy(TLSSequence,
C.NewCodeSequence.data(),
C.NewCodeSequence.size());
2346 TLSSequenceStartOffset +
C.TpoffRelocationOffset,
2347 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2349 if (
Value.SymbolName)
2362 uint64_t GOTOffset = allocateGOTEntries(1);
2363 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
2364 ELF::R_X86_64_PC32);
2366 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_TPOFF64);
2367 if (
Value.SymbolName)
2374void RuntimeDyldELF::processX86_64TLSRelocation(
2387 bool IsSmallCodeModel;
2389 bool IsGOTPCRel =
false;
2391 switch (GetAddrRelocation.
getType()) {
2392 case ELF::R_X86_64_GOTPCREL:
2393 case ELF::R_X86_64_REX_GOTPCRELX:
2394 case ELF::R_X86_64_GOTPCRELX:
2397 case ELF::R_X86_64_PLT32:
2398 IsSmallCodeModel =
true;
2400 case ELF::R_X86_64_PLTOFF64:
2401 IsSmallCodeModel =
false;
2405 "invalid TLS relocations for General/Local Dynamic TLS Model: "
2406 "expected PLT or GOT relocation for __tls_get_addr function");
2417 if (RelType == ELF::R_X86_64_TLSGD) {
2422 if (IsSmallCodeModel) {
2424 static const std::initializer_list<uint8_t> CodeSequence = {
2426 0x48, 0x8d, 0x3d, 0x00, 0x00,
2430 0xe8, 0x00, 0x00, 0x00, 0x00
2433 TLSSequenceOffset = 4;
2437 static const std::initializer_list<uint8_t> CodeSequence = {
2439 0x48, 0x8d, 0x3d, 0x00, 0x00,
2443 0xff, 0x15, 0x00, 0x00, 0x00,
2447 TLSSequenceOffset = 4;
2452 static const std::initializer_list<uint8_t> SmallSequence = {
2453 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2455 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2459 TpoffRelocOffset = 12;
2461 static const std::initializer_list<uint8_t> CodeSequence = {
2462 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2464 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470 TLSSequenceOffset = 3;
2473 static const std::initializer_list<uint8_t> LargeSequence = {
2474 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2476 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
2478 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
2481 TpoffRelocOffset = 12;
2488 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2489 if (
Value.SymbolName)
2493 }
else if (RelType == ELF::R_X86_64_TLSLD) {
2494 if (IsSmallCodeModel) {
2496 static const std::initializer_list<uint8_t> CodeSequence = {
2497 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00,
2498 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00
2501 TLSSequenceOffset = 3;
2504 static const std::initializer_list<uint8_t> SmallSequence = {
2506 0x64, 0x48, 0x8b, 0x04, 0x25,
2507 0x00, 0x00, 0x00, 0x00
2513 static const std::initializer_list<uint8_t> CodeSequence = {
2514 0x48, 0x8d, 0x3d, 0x00,
2516 0xff, 0x15, 0x00, 0x00,
2521 TLSSequenceOffset = 3;
2525 static const std::initializer_list<uint8_t> SmallSequence = {
2526 0x0f, 0x1f, 0x40, 0x00,
2527 0x64, 0x48, 0x8b, 0x04, 0x25,
2528 0x00, 0x00, 0x00, 0x00
2535 static const std::initializer_list<uint8_t> CodeSequence = {
2536 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2538 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2544 TLSSequenceOffset = 3;
2547 static const std::initializer_list<uint8_t> LargeSequence = {
2549 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
2551 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
2560 "Old and new code sequences must have the same size");
2563 if (
Offset < TLSSequenceOffset ||
2564 (
Offset - TLSSequenceOffset + NewCodeSequence.
size()) >
2569 auto *TLSSequence =
Section.getAddressWithOffset(
Offset - TLSSequenceOffset);
2571 ExpectedCodeSequence) {
2573 "invalid TLS sequence for Global/Local Dynamic TLS Model");
2576 memcpy(TLSSequence, NewCodeSequence.
data(), NewCodeSequence.
size());
2615uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned no) {
2616 if (GOTSectionID == 0) {
2623 CurrentGOTIndex += no;
2628 unsigned GOTRelType) {
2629 auto E = GOTOffsetMap.insert({
Value, 0});
2631 uint64_t GOTOffset = allocateGOTEntries(1);
2635 computeGOTOffsetRE(GOTOffset,
Value.Offset, GOTRelType);
2636 if (
Value.SymbolName)
2641 E.first->second = GOTOffset;
2644 return E.first->second;
2647void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID,
2667 if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
2668 if (IFuncStubSectionID == 0) {
2671 IFuncStubSectionID =
Sections.size();
2673 SectionEntry(
".text.__llvm_IFuncStubs",
nullptr, 0, 0, 0));
2675 IFuncStubOffset = 64;
2683 IFuncStubOffset += getMaxIFuncStubSize();
2690 if (!PendingRelocs.empty())
2691 return make_error<RuntimeDyldError>(
"Can't find matching LO16 reloc");
2695 if (IFuncStubSectionID != 0) {
2697 IFuncStubOffset, 1, IFuncStubSectionID,
".text.__llvm_IFuncStubs");
2698 if (!IFuncStubsAddr)
2699 return make_error<RuntimeDyldError>(
2700 "Unable to allocate memory for IFunc stubs!");
2702 SectionEntry(
".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
2703 IFuncStubOffset, 0);
2705 createIFuncResolver(IFuncStubsAddr);
2708 << IFuncStubSectionID <<
" Addr: "
2710 for (
auto &IFuncStub : IFuncStubs) {
2711 auto &Symbol = IFuncStub.OriginalSymbol;
2713 <<
" Offset: " <<
format(
"%p", Symbol.getOffset())
2714 <<
" IFuncStubOffset: "
2715 <<
format(
"%p\n", IFuncStub.StubOffset));
2716 createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
2717 Symbol.getSectionID(), Symbol.getOffset());
2720 IFuncStubSectionID = 0;
2721 IFuncStubOffset = 0;
2726 if (GOTSectionID != 0) {
2730 GOTSectionID,
".got",
false);
2732 return make_error<RuntimeDyldError>(
"Unable to allocate memory for GOT!");
2739 memset(
Addr, 0, TotalSize);
2745 if (SI->relocation_begin() != SI->relocation_end()) {
2748 return make_error<RuntimeDyldError>(
2752 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
2753 assert(i != SectionMap.end());
2757 GOTSymbolOffsets.
clear();
2762 ObjSectionToIDMap::iterator i, e;
2763 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
2773 if (
Name ==
".eh_frame") {
2774 UnregisteredEHFrameSections.
push_back(i->second);
2779 GOTOffsetMap.clear();
2781 CurrentGOTIndex = 0;
2790void RuntimeDyldELF::createIFuncResolver(
uint8_t *
Addr)
const {
2810 0x41, 0xff, 0x53, 0x08,
2822 static_assert(
sizeof(StubCode) <= 64,
2823 "maximum size of the IFunc resolver is 64B");
2824 memcpy(
Addr, StubCode,
sizeof(StubCode));
2827 "IFunc resolver is not supported for target architecture");
2831void RuntimeDyldELF::createIFuncStub(
unsigned IFuncStubSectionID,
2834 unsigned IFuncSectionID,
2836 auto &IFuncStubSection =
Sections[IFuncStubSectionID];
2837 auto *
Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);
2861 uint64_t GOT1 = allocateGOTEntries(2);
2865 IFuncResolverOffset, {});
2867 RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
2871 0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00,
2874 assert(
sizeof(StubCode) <= getMaxIFuncStubSize() &&
2875 "IFunc stub size must not exceed getMaxIFuncStubSize()");
2876 memcpy(
Addr, StubCode,
sizeof(StubCode));
2880 resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
2881 GOT1 - 4, ELF::R_X86_64_PC32);
2887unsigned RuntimeDyldELF::getMaxIFuncStubSize()
const {
2894bool RuntimeDyldELF::relocationNeedsGot(
const RelocationRef &R)
const {
2895 unsigned RelTy =
R.getType();
2897 return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
2898 RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;
2901 return RelTy == ELF::R_LARCH_GOT_PC_HI20 ||
2902 RelTy == ELF::R_LARCH_GOT_PC_LO12;
2905 return RelTy == ELF::R_X86_64_GOTPCREL ||
2906 RelTy == ELF::R_X86_64_GOTPCRELX ||
2907 RelTy == ELF::R_X86_64_GOT64 ||
2908 RelTy == ELF::R_X86_64_REX_GOTPCRELX;
2912bool RuntimeDyldELF::relocationNeedsStub(
const RelocationRef &R)
const {
2916 switch (
R.getType()) {
2921 case ELF::R_X86_64_GOTPCREL:
2922 case ELF::R_X86_64_GOTPCRELX:
2923 case ELF::R_X86_64_REX_GOTPCRELX:
2924 case ELF::R_X86_64_GOTPC64:
2925 case ELF::R_X86_64_GOT64:
2926 case ELF::R_X86_64_GOTOFF64:
2927 case ELF::R_X86_64_PC32:
2928 case ELF::R_X86_64_PC64:
2929 case ELF::R_X86_64_64:
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Value * getAddress(const DbgVariableIntrinsic *DVI)
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 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.
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)
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.
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 ...