29#define DEBUG_TYPE "dyld"
34 or32le(L, (Imm & 0xFFF) << 10);
37template <
class T>
static void write(
bool isBE,
void *
P,
T V) {
38 isBE ? write<T, support::big>(
P, V) : write<T, support::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 (
int i = 0, e = UnregisteredEHFrameSections.
size(); i != e; ++i) {
223 SID EHFrameSID = UnregisteredEHFrameSections[i];
224 uint8_t *EHFrameAddr =
Sections[EHFrameSID].getAddress();
226 size_t EHFrameSize =
Sections[EHFrameSID].getSize();
229 UnregisteredEHFrameSections.
clear();
232std::unique_ptr<RuntimeDyldELF>
247std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
250 return std::make_unique<LoadedELFObjectInfo>(*
this, *ObjSectionToIDOrErr);
259void RuntimeDyldELF::resolveX86_64Relocation(
const SectionEntry &Section,
267 case ELF::R_X86_64_NONE:
269 case ELF::R_X86_64_8: {
272 uint8_t TruncatedAddr = (
Value & 0xFF);
273 *Section.getAddressWithOffset(
Offset) = TruncatedAddr;
275 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
278 case ELF::R_X86_64_16: {
285 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
288 case ELF::R_X86_64_64: {
295 case ELF::R_X86_64_32:
296 case ELF::R_X86_64_32S: {
299 (
Type == ELF::R_X86_64_32S &&
300 ((int64_t)
Value <= INT32_MAX && (int64_t)
Value >= INT32_MIN)));
308 case ELF::R_X86_64_PC8: {
310 int64_t RealOffset =
Value + Addend - FinalAddress;
311 assert(isInt<8>(RealOffset));
312 int8_t TruncOffset = (RealOffset & 0xFF);
316 case ELF::R_X86_64_PC32: {
318 int64_t RealOffset =
Value + Addend - FinalAddress;
319 assert(isInt<32>(RealOffset));
320 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
325 case ELF::R_X86_64_PC64: {
327 int64_t RealOffset =
Value + Addend - FinalAddress;
331 <<
format(
"%p\n", FinalAddress));
334 case ELF::R_X86_64_GOTOFF64: {
337 for (
const auto &Section :
Sections) {
338 if (
Section.getName() ==
".got") {
339 GOTBase =
Section.getLoadAddressWithOffset(0);
343 assert(GOTBase != 0 &&
"missing GOT");
344 int64_t GOTOffset =
Value - GOTBase + Addend;
348 case ELF::R_X86_64_DTPMOD64: {
353 case ELF::R_X86_64_DTPOFF64:
354 case ELF::R_X86_64_TPOFF64: {
363 case ELF::R_X86_64_DTPOFF32:
364 case ELF::R_X86_64_TPOFF32: {
367 int64_t RealValue =
Value + Addend;
368 assert(RealValue >= INT32_MIN && RealValue <= INT32_MAX);
369 int32_t TruncValue = RealValue;
377void RuntimeDyldELF::resolveX86Relocation(
const SectionEntry &Section,
381 case ELF::R_386_32: {
388 case ELF::R_386_PLT32:
389 case ELF::R_386_PC32: {
405void RuntimeDyldELF::resolveAArch64Relocation(
const SectionEntry &Section,
416 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
417 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
419 <<
format(
"%llx", Addend) <<
"\n");
425 case ELF::R_AARCH64_NONE:
427 case ELF::R_AARCH64_ABS16: {
430 (Result >> 16) == 0);
431 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
434 case ELF::R_AARCH64_ABS32: {
437 (Result >> 32) == 0);
438 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
441 case ELF::R_AARCH64_ABS64:
444 case ELF::R_AARCH64_PLT32: {
446 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
447 static_cast<int64_t
>(Result) <= INT32_MAX);
451 case ELF::R_AARCH64_PREL16: {
453 assert(
static_cast<int64_t
>(Result) >= INT16_MIN &&
454 static_cast<int64_t
>(Result) <= UINT16_MAX);
455 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
458 case ELF::R_AARCH64_PREL32: {
460 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
461 static_cast<int64_t
>(Result) <= UINT32_MAX);
462 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
465 case ELF::R_AARCH64_PREL64:
466 write(isBE, TargetPtr,
Value + Addend - FinalAddress);
468 case ELF::R_AARCH64_CONDBR19: {
471 assert(isInt<21>(BranchImm));
472 *TargetPtr &= 0xff00001fU;
474 or32le(TargetPtr, (BranchImm & 0x001FFFFC) << 3);
477 case ELF::R_AARCH64_TSTBR14: {
480 assert(isInt<16>(BranchImm));
486 or32le(TargetPtr, (BranchImm & 0x0000FFFC) << 3);
489 case ELF::R_AARCH64_CALL26:
490 case ELF::R_AARCH64_JUMP26: {
496 assert(isInt<28>(BranchImm));
497 or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
500 case ELF::R_AARCH64_MOVW_UABS_G3:
501 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF000000000000) >> 43);
503 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
504 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF00000000) >> 27);
506 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
507 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF0000) >> 11);
509 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
510 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF) << 5);
512 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
515 ((
Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
518 assert(isInt<33>(Result) &&
"overflow check failed for relocation");
525 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
531 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
537 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
543 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
549 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
555 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
561 case ELF::R_AARCH64_LD_PREL_LO19: {
566 assert(isInt<21>(Result));
568 *TargetPtr &= 0xff00001fU;
571 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
574 case ELF::R_AARCH64_ADR_PREL_LO21: {
579 assert(isInt<21>(Result));
581 *TargetPtr &= 0x9f00001fU;
584 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
585 *TargetPtr |= (
Result & 0x3) << 29;
591void RuntimeDyldELF::resolveARMRelocation(
const SectionEntry &Section,
602 <<
" FinalAddress: " <<
format(
"%p", FinalAddress)
605 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
611 case ELF::R_ARM_NONE:
614 case ELF::R_ARM_PREL31:
617 ((
Value - FinalAddress) & ~0x80000000);
619 case ELF::R_ARM_TARGET1:
620 case ELF::R_ARM_ABS32:
625 case ELF::R_ARM_MOVW_ABS_NC:
626 case ELF::R_ARM_MOVT_ABS:
627 if (
Type == ELF::R_ARM_MOVW_ABS_NC)
629 else if (
Type == ELF::R_ARM_MOVT_ABS)
633 (((
Value >> 12) & 0xF) << 16);
636 case ELF::R_ARM_PC24:
637 case ELF::R_ARM_CALL:
638 case ELF::R_ARM_JUMP24:
639 int32_t RelValue =
static_cast<int32_t
>(
Value - FinalAddress - 8);
640 RelValue = (RelValue & 0x03FFFFFC) >> 2;
648void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
656 if (
auto *
E = dyn_cast<ELFObjectFileBase>(&Obj)) {
657 unsigned AbiVariant =
E->getPlatformFlags();
666 ObjSectionToIDMap &LocalSections,
678 for (
auto &Section : Obj.
sections()) {
688 if (
auto SectionIDOrErr =
692 return SectionIDOrErr.takeError();
707 ObjSectionToIDMap &LocalSections,
727 if (RelSectionName !=
".opd")
731 e = si->relocation_end();
736 if (TypeFunc != ELF::R_PPC64_ADDR64) {
741 uint64_t TargetSymbolOffset = i->getOffset();
744 if (
auto AddendOrErr = i->getAddend())
745 Addend = *AddendOrErr;
747 return AddendOrErr.takeError();
755 if (TypeTOC != ELF::R_PPC64_TOC)
761 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
765 if (
auto TSIOrErr = TargetSymbol->
getSection())
768 return TSIOrErr.takeError();
771 bool IsCode = TSI->isText();
776 return SectionIDOrErr.takeError();
777 Rel.
Addend = (intptr_t)Addend;
792 return (
value >> 16) & 0xffff;
796 return ((
value + 0x8000) >> 16) & 0xffff;
800 return (
value >> 32) & 0xffff;
804 return ((
value + 0x8000) >> 32) & 0xffff;
808 return (
value >> 48) & 0xffff;
812 return ((
value + 0x8000) >> 48) & 0xffff;
815void RuntimeDyldELF::resolvePPC32Relocation(
const SectionEntry &Section,
818 uint8_t *LocalAddress = Section.getAddressWithOffset(
Offset);
823 case ELF::R_PPC_ADDR16_LO:
826 case ELF::R_PPC_ADDR16_HI:
829 case ELF::R_PPC_ADDR16_HA:
835void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
838 uint8_t *LocalAddress =
Section.getAddressWithOffset(
Offset);
843 case ELF::R_PPC64_ADDR16:
846 case ELF::R_PPC64_ADDR16_DS:
849 case ELF::R_PPC64_ADDR16_LO:
852 case ELF::R_PPC64_ADDR16_LO_DS:
855 case ELF::R_PPC64_ADDR16_HI:
856 case ELF::R_PPC64_ADDR16_HIGH:
859 case ELF::R_PPC64_ADDR16_HA:
860 case ELF::R_PPC64_ADDR16_HIGHA:
863 case ELF::R_PPC64_ADDR16_HIGHER:
866 case ELF::R_PPC64_ADDR16_HIGHERA:
869 case ELF::R_PPC64_ADDR16_HIGHEST:
872 case ELF::R_PPC64_ADDR16_HIGHESTA:
875 case ELF::R_PPC64_ADDR14: {
878 uint8_t aalk = *(LocalAddress + 3);
881 case ELF::R_PPC64_REL16_LO: {
886 case ELF::R_PPC64_REL16_HI: {
891 case ELF::R_PPC64_REL16_HA: {
896 case ELF::R_PPC64_ADDR32: {
897 int64_t
Result =
static_cast<int64_t
>(
Value + Addend);
898 if (SignExtend64<32>(Result) !=
Result)
902 case ELF::R_PPC64_REL24: {
904 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
905 if (SignExtend64<26>(delta) != delta)
909 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
911 case ELF::R_PPC64_REL32: {
913 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
914 if (SignExtend64<32>(delta) != delta)
918 case ELF::R_PPC64_REL64: {
923 case ELF::R_PPC64_ADDR64:
929void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
932 uint8_t *LocalAddress =
Section.getAddressWithOffset(
Offset);
937 case ELF::R_390_PC16DBL:
938 case ELF::R_390_PLT16DBL: {
940 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
944 case ELF::R_390_PC32DBL:
945 case ELF::R_390_PLT32DBL: {
947 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
951 case ELF::R_390_PC16: {
953 assert(int16_t(Delta) == Delta &&
"R_390_PC16 overflow");
957 case ELF::R_390_PC32: {
959 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
963 case ELF::R_390_PC64: {
969 *LocalAddress = (uint8_t)(
Value + Addend);
983void RuntimeDyldELF::resolveBPFRelocation(
const SectionEntry &Section,
992 case ELF::R_BPF_NONE:
993 case ELF::R_BPF_64_64:
994 case ELF::R_BPF_64_32:
995 case ELF::R_BPF_64_NODYLD32:
997 case ELF::R_BPF_64_ABS64: {
1003 case ELF::R_BPF_64_ABS32: {
1041void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
1044 uint64_t SymOffset, SID SectionID) {
1047 resolveX86_64Relocation(Section,
Offset,
Value,
Type, Addend, SymOffset);
1084void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID,
uint64_t Offset)
const {
1090 if (
Value.SymbolName)
1097 bool IsLocal)
const {
1099 case ELF::R_MICROMIPS_GOT16:
1101 return ELF::R_MICROMIPS_LO16;
1103 case ELF::R_MICROMIPS_HI16:
1104 return ELF::R_MICROMIPS_LO16;
1105 case ELF::R_MIPS_GOT16:
1107 return ELF::R_MIPS_LO16;
1109 case ELF::R_MIPS_HI16:
1110 return ELF::R_MIPS_LO16;
1111 case ELF::R_MIPS_PCHI16:
1112 return ELF::R_MIPS_PCLO16;
1116 return ELF::R_MIPS_NONE;
1128bool RuntimeDyldELF::resolveAArch64ShortBranch(
1132 if (
Value.SymbolName) {
1139 const auto &
SymInfo = Loc->second;
1152 if (!isInt<28>(
Address +
Value.Addend - SourceAddress))
1161void RuntimeDyldELF::resolveAArch64Branch(
unsigned SectionID,
1166 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1170 unsigned RelType = RelI->getType();
1172 StubMap::const_iterator i = Stubs.find(
Value);
1173 if (i != Stubs.end()) {
1174 resolveRelocation(Section,
Offset,
1178 }
else if (!resolveAArch64ShortBranch(SectionID, RelI,
Value)) {
1186 ELF::R_AARCH64_MOVW_UABS_G3,
Value.Addend);
1188 StubTargetAddr -
Section.getAddress() + 4,
1189 ELF::R_AARCH64_MOVW_UABS_G2_NC,
Value.Addend);
1191 StubTargetAddr -
Section.getAddress() + 8,
1192 ELF::R_AARCH64_MOVW_UABS_G1_NC,
Value.Addend);
1194 StubTargetAddr -
Section.getAddress() + 12,
1195 ELF::R_AARCH64_MOVW_UABS_G0_NC,
Value.Addend);
1197 if (
Value.SymbolName) {
1208 resolveRelocation(Section,
Offset,
1212 Section.advanceStubOffset(getMaxStubSize());
1220 const auto &Obj = cast<ELFObjectFileBase>(O);
1221 uint64_t RelType = RelI->getType();
1224 Addend = *AddendOrErr;
1232 if (
auto TargetNameOrErr = Symbol->getName())
1233 TargetName = *TargetNameOrErr;
1235 return TargetNameOrErr.takeError();
1237 LLVM_DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
1238 <<
" TargetName: " << TargetName <<
"\n");
1248 if (!SymTypeOrErr) {
1254 SymType = *SymTypeOrErr;
1257 const auto &
SymInfo = gsi->second;
1267 auto SectionOrErr = Symbol->getSection();
1268 if (!SectionOrErr) {
1278 bool isCode = si->isText();
1281 Value.SectionID = *SectionIDOrErr;
1283 return SectionIDOrErr.takeError();
1284 Value.Addend = Addend;
1292 Value.Addend = Addend;
1298 if (!
Value.SymbolName)
1299 Value.SymbolName =
"";
1313 if ((RelType == ELF::R_AARCH64_CALL26 ||
1314 RelType == ELF::R_AARCH64_JUMP26) &&
1316 resolveAArch64Branch(SectionID,
Value, RelI, Stubs);
1317 }
else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
1320 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1321 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1322 ELF::R_AARCH64_ADR_PREL_PG_HI21);
1324 }
else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
1325 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1326 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1327 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
1329 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1332 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1333 RelType == ELF::R_ARM_JUMP24) {
1339 StubMap::const_iterator i = Stubs.find(
Value);
1340 if (i != Stubs.end()) {
1343 reinterpret_cast<uint64_t>(Section.getAddressWithOffset(i->second)),
1349 Stubs[
Value] = Section.getStubOffset();
1351 Section.getAddressWithOffset(Section.getStubOffset()));
1353 ELF::R_ARM_ABS32,
Value.Addend);
1354 if (
Value.SymbolName)
1360 Section.getAddressWithOffset(
1361 Section.getStubOffset())),
1363 Section.advanceStubOffset(getMaxStubSize());
1367 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID,
Offset));
1368 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1369 RelType == ELF::R_ARM_ABS32) {
1370 Value.Addend += *Placeholder;
1371 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1373 Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1375 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1378 uint8_t *Placeholder =
reinterpret_cast<uint8_t *
>(
1379 computePlaceholderAddress(SectionID,
Offset));
1381 if (RelType == ELF::R_MIPS_26) {
1389 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1391 Value.Addend += Addend;
1394 StubMap::const_iterator i = Stubs.find(
Value);
1395 if (i != Stubs.end()) {
1402 Stubs[
Value] = Section.getStubOffset();
1407 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1410 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1411 ELF::R_MIPS_HI16,
Value.Addend);
1413 StubTargetAddr - Section.getAddress() + 4,
1414 ELF::R_MIPS_LO16,
Value.Addend);
1416 if (
Value.SymbolName) {
1426 Section.advanceStubOffset(getMaxStubSize());
1428 }
else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1429 int64_t Addend = (Opcode & 0x0000ffff) << 16;
1431 PendingRelocs.push_back(std::make_pair(
Value, RE));
1432 }
else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1433 int64_t Addend =
Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
1434 for (
auto I = PendingRelocs.begin();
I != PendingRelocs.end();) {
1437 if (MatchingValue ==
Value &&
1438 RelType == getMatchingLoRelocation(Reloc.
RelType) &&
1441 if (
Value.SymbolName)
1445 I = PendingRelocs.erase(
I);
1450 if (
Value.SymbolName)
1455 if (RelType == ELF::R_MIPS_32)
1456 Value.Addend += Opcode;
1457 else if (RelType == ELF::R_MIPS_PC16)
1458 Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1459 else if (RelType == ELF::R_MIPS_PC19_S2)
1460 Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1461 else if (RelType == ELF::R_MIPS_PC21_S2)
1462 Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1463 else if (RelType == ELF::R_MIPS_PC26_S2)
1464 Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
1465 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1470 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1471 || r_type == ELF::R_MIPS_GOT_DISP) {
1473 if (i != GOTSymbolOffsets.
end())
1477 GOTSymbolOffsets[TargetName] = RE.
SymOffset;
1479 if (
Value.SymbolName)
1483 }
else if (RelType == ELF::R_MIPS_26) {
1489 StubMap::const_iterator i = Stubs.find(
Value);
1490 if (i != Stubs.end()) {
1497 Stubs[
Value] = Section.getStubOffset();
1502 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1506 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1507 ELF::R_MIPS_HI16,
Value.Addend);
1509 StubTargetAddr - Section.getAddress() + 4,
1510 ELF::R_MIPS_LO16,
Value.Addend);
1511 if (
Value.SymbolName) {
1522 StubTargetAddr - Section.getAddress(),
1523 ELF::R_MIPS_HIGHEST,
Value.Addend);
1525 StubTargetAddr - Section.getAddress() + 4,
1526 ELF::R_MIPS_HIGHER,
Value.Addend);
1528 StubTargetAddr - Section.getAddress() + 12,
1529 ELF::R_MIPS_HI16,
Value.Addend);
1531 StubTargetAddr - Section.getAddress() + 20,
1532 ELF::R_MIPS_LO16,
Value.Addend);
1533 if (
Value.SymbolName) {
1547 Section.advanceStubOffset(getMaxStubSize());
1550 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1554 if (RelType == ELF::R_PPC64_REL24) {
1563 uint8_t *
Target = Section.getAddressWithOffset(
Offset);
1564 bool RangeOverflow =
false;
1567 if (AbiVariant != 2) {
1571 if (
auto Err = findOPDEntrySection(Obj, ObjSectionToID,
Value))
1572 return std::move(Err);
1576 if (
Value.SectionID == SectionID){
1577 uint8_t SymOther = Symbol->getOther();
1581 uint8_t *RelocTarget =
1583 int64_t delta =
static_cast<int64_t
>(
Target - RelocTarget);
1585 if (SignExtend64<26>(delta) != delta) {
1586 RangeOverflow =
true;
1587 }
else if ((AbiVariant != 2) ||
1588 (AbiVariant == 2 &&
Value.SectionID == SectionID)) {
1593 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID) ||
1597 StubMap::const_iterator i = Stubs.find(
Value);
1598 if (i != Stubs.end()) {
1600 resolveRelocation(Section,
Offset,
1602 Section.getAddressWithOffset(i->second)),
1608 Stubs[
Value] = Section.getStubOffset();
1610 Section.getAddressWithOffset(Section.getStubOffset()),
1613 ELF::R_PPC64_ADDR64,
Value.Addend);
1619 uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
1621 StubRelocOffset += 2;
1624 ELF::R_PPC64_ADDR16_HIGHEST,
Value.Addend);
1626 ELF::R_PPC64_ADDR16_HIGHER,
Value.Addend);
1628 ELF::R_PPC64_ADDR16_HI,
Value.Addend);
1630 ELF::R_PPC64_ADDR16_LO,
Value.Addend);
1632 if (
Value.SymbolName) {
1645 Section.getAddressWithOffset(
1646 Section.getStubOffset())),
1648 Section.advanceStubOffset(getMaxStubSize());
1650 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID)) {
1652 if (AbiVariant == 2)
1658 }
else if (RelType == ELF::R_PPC64_TOC16 ||
1659 RelType == ELF::R_PPC64_TOC16_DS ||
1660 RelType == ELF::R_PPC64_TOC16_LO ||
1661 RelType == ELF::R_PPC64_TOC16_LO_DS ||
1662 RelType == ELF::R_PPC64_TOC16_HI ||
1663 RelType == ELF::R_PPC64_TOC16_HA) {
1675 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
1676 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
1677 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
1678 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
1679 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
1680 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
1685 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
1686 return std::move(Err);
1696 if (RelType == ELF::R_PPC64_TOC) {
1697 RelType = ELF::R_PPC64_ADDR64;
1698 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
1699 return std::move(Err);
1700 }
else if (TargetName ==
".TOC.") {
1701 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
1702 return std::move(Err);
1703 Value.Addend += Addend;
1708 if (
Value.SymbolName)
1714 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
1724 LLVM_DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
1728 StubMap::const_iterator i = Stubs.find(
Value);
1729 uintptr_t StubAddress;
1730 if (i != Stubs.end()) {
1731 StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
1737 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
1739 alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
1740 unsigned StubOffset = StubAddress - BaseAddress;
1742 Stubs[
Value] = StubOffset;
1746 if (
Value.SymbolName)
1750 Section.advanceStubOffset(getMaxStubSize());
1753 if (RelType == ELF::R_390_GOTENT)
1754 resolveRelocation(Section,
Offset, StubAddress + 8, ELF::R_390_PC32DBL,
1757 resolveRelocation(Section,
Offset, StubAddress, RelType, Addend);
1759 if (RelType == ELF::R_X86_64_PLT32) {
1780 StubMap::const_iterator i = Stubs.find(
Value);
1781 uintptr_t StubAddress;
1782 if (i != Stubs.end()) {
1783 StubAddress = uintptr_t(Section->getAddress()) + i->second;
1789 uintptr_t BaseAddress = uintptr_t(Section->getAddress());
1790 StubAddress =
alignTo(BaseAddress + Section->getStubOffset(),
1791 getStubAlignment());
1792 unsigned StubOffset = StubAddress - BaseAddress;
1793 Stubs[
Value] = StubOffset;
1797 Section->advanceStubOffset(getMaxStubSize());
1800 uint64_t GOTOffset = allocateGOTEntries(1);
1806 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
1807 ELF::R_X86_64_PC32);
1811 computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
1816 resolveRelocation(*Section,
Offset, StubAddress, ELF::R_X86_64_PC32,
1820 computePlaceholderAddress(SectionID,
Offset));
1821 processSimpleRelocation(SectionID,
Offset, ELF::R_X86_64_PC32,
Value);
1823 }
else if (RelType == ELF::R_X86_64_GOTPCREL ||
1824 RelType == ELF::R_X86_64_GOTPCRELX ||
1825 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
1826 uint64_t GOTOffset = allocateGOTEntries(1);
1827 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1828 ELF::R_X86_64_PC32);
1832 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
1833 if (
Value.SymbolName)
1837 }
else if (RelType == ELF::R_X86_64_GOT64) {
1839 uint64_t GOTOffset = allocateGOTEntries(1);
1841 ELF::R_X86_64_64, 0);
1845 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
1846 if (
Value.SymbolName)
1850 }
else if (RelType == ELF::R_X86_64_GOTPC32) {
1854 (void)allocateGOTEntries(0);
1855 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC32);
1856 }
else if (RelType == ELF::R_X86_64_GOTPC64) {
1857 (void)allocateGOTEntries(0);
1858 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC64);
1859 }
else if (RelType == ELF::R_X86_64_GOTOFF64) {
1861 (void)allocateGOTEntries(0);
1862 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1863 }
else if (RelType == ELF::R_X86_64_PC32) {
1865 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1866 }
else if (RelType == ELF::R_X86_64_PC64) {
1868 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1869 }
else if (RelType == ELF::R_X86_64_GOTTPOFF) {
1870 processX86_64GOTTPOFFRelocation(SectionID,
Offset,
Value, Addend);
1871 }
else if (RelType == ELF::R_X86_64_TLSGD ||
1872 RelType == ELF::R_X86_64_TLSLD) {
1875 auto &GetAddrRelocation = *RelI;
1876 processX86_64TLSRelocation(SectionID,
Offset, RelType,
Value, Addend,
1879 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1885 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1890void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(
unsigned SectionID,
1901 struct CodeSequence {
1913 std::array<CodeSequence, 2> CodeSequences;
1917 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
1918 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
1920 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00
1923 CodeSequences[0].ExpectedCodeSequence =
1925 CodeSequences[0].TLSSequenceOffset = 12;
1927 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
1928 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
1929 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
1932 CodeSequences[0].TpoffRelocationOffset = 12;
1937 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
1938 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
1939 0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00
1941 CodeSequences[1].ExpectedCodeSequence =
1943 CodeSequences[1].TLSSequenceOffset = 3;
1945 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
1946 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
1947 0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
1950 CodeSequences[1].TpoffRelocationOffset = 10;
1955 for (
const auto &
C : CodeSequences) {
1956 assert(
C.ExpectedCodeSequence.size() ==
C.NewCodeSequence.size() &&
1957 "Old and new code sequences must have the same size");
1959 if (
Offset <
C.TLSSequenceOffset ||
1960 (
Offset -
C.TLSSequenceOffset +
C.NewCodeSequence.size()) >
1967 auto TLSSequenceStartOffset =
Offset -
C.TLSSequenceOffset;
1968 auto *TLSSequence =
Section.getAddressWithOffset(TLSSequenceStartOffset);
1970 C.ExpectedCodeSequence) {
1974 memcpy(TLSSequence,
C.NewCodeSequence.data(),
C.NewCodeSequence.size());
1981 TLSSequenceStartOffset +
C.TpoffRelocationOffset,
1982 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
1984 if (
Value.SymbolName)
1997 uint64_t GOTOffset = allocateGOTEntries(1);
1998 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1999 ELF::R_X86_64_PC32);
2001 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_TPOFF64);
2002 if (
Value.SymbolName)
2009void RuntimeDyldELF::processX86_64TLSRelocation(
2022 bool IsSmallCodeModel;
2024 bool IsGOTPCRel =
false;
2026 switch (GetAddrRelocation.
getType()) {
2027 case ELF::R_X86_64_GOTPCREL:
2028 case ELF::R_X86_64_REX_GOTPCRELX:
2029 case ELF::R_X86_64_GOTPCRELX:
2032 case ELF::R_X86_64_PLT32:
2033 IsSmallCodeModel =
true;
2035 case ELF::R_X86_64_PLTOFF64:
2036 IsSmallCodeModel =
false;
2040 "invalid TLS relocations for General/Local Dynamic TLS Model: "
2041 "expected PLT or GOT relocation for __tls_get_addr function");
2052 if (RelType == ELF::R_X86_64_TLSGD) {
2057 if (IsSmallCodeModel) {
2059 static const std::initializer_list<uint8_t> CodeSequence = {
2061 0x48, 0x8d, 0x3d, 0x00, 0x00,
2065 0xe8, 0x00, 0x00, 0x00, 0x00
2068 TLSSequenceOffset = 4;
2072 static const std::initializer_list<uint8_t> CodeSequence = {
2074 0x48, 0x8d, 0x3d, 0x00, 0x00,
2078 0xff, 0x15, 0x00, 0x00, 0x00,
2082 TLSSequenceOffset = 4;
2087 static const std::initializer_list<uint8_t> SmallSequence = {
2088 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2090 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2094 TpoffRelocOffset = 12;
2096 static const std::initializer_list<uint8_t> CodeSequence = {
2097 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2099 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2105 TLSSequenceOffset = 3;
2108 static const std::initializer_list<uint8_t> LargeSequence = {
2109 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2111 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
2113 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
2116 TpoffRelocOffset = 12;
2123 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2124 if (
Value.SymbolName)
2128 }
else if (RelType == ELF::R_X86_64_TLSLD) {
2129 if (IsSmallCodeModel) {
2131 static const std::initializer_list<uint8_t> CodeSequence = {
2132 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00,
2133 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00
2136 TLSSequenceOffset = 3;
2139 static const std::initializer_list<uint8_t> SmallSequence = {
2141 0x64, 0x48, 0x8b, 0x04, 0x25,
2142 0x00, 0x00, 0x00, 0x00
2148 static const std::initializer_list<uint8_t> CodeSequence = {
2149 0x48, 0x8d, 0x3d, 0x00,
2151 0xff, 0x15, 0x00, 0x00,
2156 TLSSequenceOffset = 3;
2160 static const std::initializer_list<uint8_t> SmallSequence = {
2161 0x0f, 0x1f, 0x40, 0x00,
2162 0x64, 0x48, 0x8b, 0x04, 0x25,
2163 0x00, 0x00, 0x00, 0x00
2170 static const std::initializer_list<uint8_t> CodeSequence = {
2171 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2173 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2179 TLSSequenceOffset = 3;
2182 static const std::initializer_list<uint8_t> LargeSequence = {
2184 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
2186 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
2195 "Old and new code sequences must have the same size");
2198 if (
Offset < TLSSequenceOffset ||
2199 (
Offset - TLSSequenceOffset + NewCodeSequence.
size()) >
2204 auto *TLSSequence =
Section.getAddressWithOffset(
Offset - TLSSequenceOffset);
2206 ExpectedCodeSequence) {
2208 "invalid TLS sequence for Global/Local Dynamic TLS Model");
2211 memcpy(TLSSequence, NewCodeSequence.
data(), NewCodeSequence.
size());
2249uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned no) {
2250 if (GOTSectionID == 0) {
2257 CurrentGOTIndex += no;
2262 unsigned GOTRelType) {
2263 auto E = GOTOffsetMap.insert({
Value, 0});
2265 uint64_t GOTOffset = allocateGOTEntries(1);
2269 computeGOTOffsetRE(GOTOffset,
Value.Offset, GOTRelType);
2270 if (
Value.SymbolName)
2275 E.first->second = GOTOffset;
2278 return E.first->second;
2281void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID,
2301 if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
2302 if (IFuncStubSectionID == 0) {
2305 IFuncStubSectionID =
Sections.size();
2307 SectionEntry(
".text.__llvm_IFuncStubs",
nullptr, 0, 0, 0));
2309 IFuncStubOffset = 64;
2317 IFuncStubOffset += getMaxIFuncStubSize();
2324 if (!PendingRelocs.empty())
2325 return make_error<RuntimeDyldError>(
"Can't find matching LO16 reloc");
2329 if (IFuncStubSectionID != 0) {
2331 IFuncStubOffset, 1, IFuncStubSectionID,
".text.__llvm_IFuncStubs");
2332 if (!IFuncStubsAddr)
2333 return make_error<RuntimeDyldError>(
2334 "Unable to allocate memory for IFunc stubs!");
2336 SectionEntry(
".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
2337 IFuncStubOffset, 0);
2339 createIFuncResolver(IFuncStubsAddr);
2342 << IFuncStubSectionID <<
" Addr: "
2343 <<
Sections[IFuncStubSectionID].getAddress() <<
'\n');
2344 for (
auto &IFuncStub : IFuncStubs) {
2345 auto &Symbol = IFuncStub.OriginalSymbol;
2347 <<
" Offset: " <<
format(
"%p", Symbol.getOffset())
2348 <<
" IFuncStubOffset: "
2349 <<
format(
"%p\n", IFuncStub.StubOffset));
2350 createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
2351 Symbol.getSectionID(), Symbol.getOffset());
2354 IFuncStubSectionID = 0;
2355 IFuncStubOffset = 0;
2360 if (GOTSectionID != 0) {
2364 GOTSectionID,
".got",
false);
2366 return make_error<RuntimeDyldError>(
"Unable to allocate memory for GOT!");
2373 memset(
Addr, 0, TotalSize);
2379 if (
SI->relocation_begin() !=
SI->relocation_end()) {
2382 return make_error<RuntimeDyldError>(
2386 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
2387 assert(i != SectionMap.end());
2391 GOTSymbolOffsets.
clear();
2396 ObjSectionToIDMap::iterator i, e;
2397 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
2407 if (
Name ==
".eh_frame") {
2408 UnregisteredEHFrameSections.
push_back(i->second);
2413 GOTOffsetMap.clear();
2415 CurrentGOTIndex = 0;
2424void RuntimeDyldELF::createIFuncResolver(uint8_t *
Addr)
const {
2436 const uint8_t StubCode[] = {
2444 0x41, 0xff, 0x53, 0x08,
2456 static_assert(
sizeof(StubCode) <= 64,
2457 "maximum size of the IFunc resolver is 64B");
2458 memcpy(
Addr, StubCode,
sizeof(StubCode));
2461 "IFunc resolver is not supported for target architecture");
2465void RuntimeDyldELF::createIFuncStub(
unsigned IFuncStubSectionID,
2468 unsigned IFuncSectionID,
2470 auto &IFuncStubSection =
Sections[IFuncStubSectionID];
2471 auto *
Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);
2495 uint64_t GOT1 = allocateGOTEntries(2);
2499 IFuncResolverOffset, {});
2501 RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
2504 const uint8_t StubCode[] = {
2505 0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00,
2508 assert(
sizeof(StubCode) <= getMaxIFuncStubSize() &&
2509 "IFunc stub size must not exceed getMaxIFuncStubSize()");
2510 memcpy(
Addr, StubCode,
sizeof(StubCode));
2514 resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
2515 GOT1 - 4, ELF::R_X86_64_PC32);
2521unsigned RuntimeDyldELF::getMaxIFuncStubSize()
const {
2528bool RuntimeDyldELF::relocationNeedsGot(
const RelocationRef &R)
const {
2529 unsigned RelTy =
R.getType();
2531 return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
2532 RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;
2535 return RelTy == ELF::R_X86_64_GOTPCREL ||
2536 RelTy == ELF::R_X86_64_GOTPCRELX ||
2537 RelTy == ELF::R_X86_64_GOT64 ||
2538 RelTy == ELF::R_X86_64_REX_GOTPCRELX;
2542bool RuntimeDyldELF::relocationNeedsStub(
const RelocationRef &R)
const {
2546 switch (
R.getType()) {
2551 case ELF::R_X86_64_GOTPCREL:
2552 case ELF::R_X86_64_GOTPCRELX:
2553 case ELF::R_X86_64_REX_GOTPCRELX:
2554 case ELF::R_X86_64_GOTPC64:
2555 case ELF::R_X86_64_GOT64:
2556 case ELF::R_X86_64_GOTOFF64:
2557 case ELF::R_X86_64_PC32:
2558 case ELF::R_X86_64_PC64:
2559 case ELF::R_X86_64_64:
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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())
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.
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)
StringRef - Represent a constant reference to a string, i.e.
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
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
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)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
@ Resolved
Queried, materialization begun.
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.
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs)
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 uint16_t applyPPChighesta(uint64_t value)
static uint16_t applyPPChighest(uint64_t value)
static uint16_t applyPPCha(uint64_t value)
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.
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.
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.
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)
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...