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, llvm::endianness::big>(
P, V)
39 : write<T, llvm::endianness::little>(
P, V);
44 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
45 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
53 return (Val >> Start) & Mask;
58template <
class ELFT>
class DyldELFObject :
public ELFObjectFile<ELFT> {
61 typedef typename ELFT::uint addr_type;
79 return v->isDyldType();
91 this->isDyldELFObject =
true;
98 if (
auto E = Obj.takeError())
100 std::unique_ptr<DyldELFObject<ELFT>>
Ret(
101 new DyldELFObject<ELFT>(std::move(*Obj)));
102 return std::move(Ret);
106void DyldELFObject<ELFT>::updateSectionAddress(
const SectionRef &Sec,
110 const_cast<Elf_Shdr *
>(
reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
114 shdr->sh_addr =
static_cast<addr_type
>(
Addr);
118void DyldELFObject<ELFT>::updateSymbolAddress(
const SymbolRef &SymRef,
121 Elf_Sym *sym =
const_cast<Elf_Sym *
>(
126 sym->st_value =
static_cast<addr_type
>(
Addr);
129class LoadedELFObjectInfo final
131 RuntimeDyld::LoadedObjectInfo> {
133 LoadedELFObjectInfo(
RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
137 getObjectForDebug(
const ObjectFile &Obj)
const override;
140template <
typename ELFT>
143 const LoadedELFObjectInfo &L) {
144 typedef typename ELFT::Shdr Elf_Shdr;
145 typedef typename ELFT::uint addr_type;
148 DyldELFObject<ELFT>::create(Buffer);
152 std::unique_ptr<DyldELFObject<ELFT>> Obj = std::move(*ObjOrErr);
156 for (
const auto &Sec : Obj->sections()) {
163 if (*NameOrErr !=
"") {
165 Elf_Shdr *shdr =
const_cast<Elf_Shdr *
>(
166 reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
168 if (
uint64_t SecLoadAddr =
L.getSectionLoadAddress(*SI)) {
171 shdr->sh_addr =
static_cast<addr_type
>(SecLoadAddr);
177 return std::move(Obj);
181createELFDebugObject(
const ObjectFile &Obj,
const LoadedELFObjectInfo &L) {
184 std::unique_ptr<MemoryBuffer> Buffer =
191 createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj, L);
194 createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj, L);
197 createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj, L);
200 createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj, L);
209LoadedELFObjectInfo::getObjectForDebug(
const ObjectFile &Obj)
const {
210 return createELFDebugObject(Obj, *
this);
223 for (
int i = 0, e = UnregisteredEHFrameSections.
size(); i != e; ++i) {
224 SID EHFrameSID = UnregisteredEHFrameSections[i];
225 uint8_t *EHFrameAddr =
Sections[EHFrameSID].getAddress();
227 size_t EHFrameSize =
Sections[EHFrameSID].getSize();
230 UnregisteredEHFrameSections.
clear();
233std::unique_ptr<RuntimeDyldELF>
248std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
251 return std::make_unique<LoadedELFObjectInfo>(*
this, *ObjSectionToIDOrErr);
260void RuntimeDyldELF::resolveX86_64Relocation(
const SectionEntry &Section,
268 case ELF::R_X86_64_NONE:
270 case ELF::R_X86_64_8: {
273 uint8_t TruncatedAddr = (
Value & 0xFF);
274 *Section.getAddressWithOffset(
Offset) = TruncatedAddr;
276 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
279 case ELF::R_X86_64_16: {
286 <<
format(
"%p\n", Section.getAddressWithOffset(
Offset)));
289 case ELF::R_X86_64_64: {
296 case ELF::R_X86_64_32:
297 case ELF::R_X86_64_32S: {
300 (
Type == ELF::R_X86_64_32S &&
301 ((int64_t)
Value <= INT32_MAX && (int64_t)
Value >= INT32_MIN)));
309 case ELF::R_X86_64_PC8: {
311 int64_t RealOffset =
Value + Addend - FinalAddress;
312 assert(isInt<8>(RealOffset));
313 int8_t TruncOffset = (RealOffset & 0xFF);
317 case ELF::R_X86_64_PC32: {
319 int64_t RealOffset =
Value + Addend - FinalAddress;
320 assert(isInt<32>(RealOffset));
321 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
326 case ELF::R_X86_64_PC64: {
328 int64_t RealOffset =
Value + Addend - FinalAddress;
332 <<
format(
"%p\n", FinalAddress));
335 case ELF::R_X86_64_GOTOFF64: {
338 for (
const auto &Section :
Sections) {
339 if (
Section.getName() ==
".got") {
340 GOTBase =
Section.getLoadAddressWithOffset(0);
344 assert(GOTBase != 0 &&
"missing GOT");
345 int64_t GOTOffset =
Value - GOTBase + Addend;
349 case ELF::R_X86_64_DTPMOD64: {
354 case ELF::R_X86_64_DTPOFF64:
355 case ELF::R_X86_64_TPOFF64: {
364 case ELF::R_X86_64_DTPOFF32:
365 case ELF::R_X86_64_TPOFF32: {
368 int64_t RealValue =
Value + Addend;
369 assert(RealValue >= INT32_MIN && RealValue <= INT32_MAX);
370 int32_t TruncValue = RealValue;
378void RuntimeDyldELF::resolveX86Relocation(
const SectionEntry &Section,
382 case ELF::R_386_32: {
389 case ELF::R_386_PLT32:
390 case ELF::R_386_PC32: {
406void RuntimeDyldELF::resolveAArch64Relocation(
const SectionEntry &Section,
417 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
418 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
420 <<
format(
"%llx", Addend) <<
"\n");
426 case ELF::R_AARCH64_NONE:
428 case ELF::R_AARCH64_ABS16: {
431 (Result >> 16) == 0);
432 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
435 case ELF::R_AARCH64_ABS32: {
438 (Result >> 32) == 0);
439 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
442 case ELF::R_AARCH64_ABS64:
445 case ELF::R_AARCH64_PLT32: {
447 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
448 static_cast<int64_t
>(Result) <= INT32_MAX);
452 case ELF::R_AARCH64_PREL16: {
454 assert(
static_cast<int64_t
>(Result) >= INT16_MIN &&
455 static_cast<int64_t
>(Result) <= UINT16_MAX);
456 write(isBE, TargetPtr,
static_cast<uint16_t>(Result & 0xffffU));
459 case ELF::R_AARCH64_PREL32: {
461 assert(
static_cast<int64_t
>(Result) >= INT32_MIN &&
462 static_cast<int64_t
>(Result) <= UINT32_MAX);
463 write(isBE, TargetPtr,
static_cast<uint32_t>(Result & 0xffffffffU));
466 case ELF::R_AARCH64_PREL64:
467 write(isBE, TargetPtr,
Value + Addend - FinalAddress);
469 case ELF::R_AARCH64_CONDBR19: {
472 assert(isInt<21>(BranchImm));
473 *TargetPtr &= 0xff00001fU;
475 or32le(TargetPtr, (BranchImm & 0x001FFFFC) << 3);
478 case ELF::R_AARCH64_TSTBR14: {
481 assert(isInt<16>(BranchImm));
487 or32le(TargetPtr, (BranchImm & 0x0000FFFC) << 3);
490 case ELF::R_AARCH64_CALL26:
491 case ELF::R_AARCH64_JUMP26: {
497 assert(isInt<28>(BranchImm));
498 or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
501 case ELF::R_AARCH64_MOVW_UABS_G3:
502 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF000000000000) >> 43);
504 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
505 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF00000000) >> 27);
507 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
508 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF0000) >> 11);
510 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
511 or32le(TargetPtr, ((
Value + Addend) & 0xFFFF) << 5);
513 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
516 ((
Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
519 assert(isInt<33>(Result) &&
"overflow check failed for relocation");
526 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
532 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
538 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
544 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
550 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
556 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
562 case ELF::R_AARCH64_LD_PREL_LO19: {
567 assert(isInt<21>(Result));
569 *TargetPtr &= 0xff00001fU;
572 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
575 case ELF::R_AARCH64_ADR_PREL_LO21: {
580 assert(isInt<21>(Result));
582 *TargetPtr &= 0x9f00001fU;
585 *TargetPtr |= ((
Result & 0xffc) << (5 - 2));
586 *TargetPtr |= (
Result & 0x3) << 29;
592void RuntimeDyldELF::resolveARMRelocation(
const SectionEntry &Section,
603 <<
" FinalAddress: " <<
format(
"%p", FinalAddress)
606 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
612 case ELF::R_ARM_NONE:
615 case ELF::R_ARM_PREL31:
618 ((
Value - FinalAddress) & ~0x80000000);
620 case ELF::R_ARM_TARGET1:
621 case ELF::R_ARM_ABS32:
626 case ELF::R_ARM_MOVW_ABS_NC:
627 case ELF::R_ARM_MOVT_ABS:
628 if (
Type == ELF::R_ARM_MOVW_ABS_NC)
630 else if (
Type == ELF::R_ARM_MOVT_ABS)
634 (((
Value >> 12) & 0xF) << 16);
637 case ELF::R_ARM_PC24:
638 case ELF::R_ARM_CALL:
639 case ELF::R_ARM_JUMP24:
640 int32_t RelValue =
static_cast<int32_t
>(
Value - FinalAddress - 8);
641 RelValue = (RelValue & 0x03FFFFFC) >> 2;
649void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
657 if (
auto *
E = dyn_cast<ELFObjectFileBase>(&Obj)) {
658 unsigned AbiVariant =
E->getPlatformFlags();
667 ObjSectionToIDMap &LocalSections,
679 for (
auto &Section : Obj.
sections()) {
689 if (
auto SectionIDOrErr =
693 return SectionIDOrErr.takeError();
708 ObjSectionToIDMap &LocalSections,
728 if (RelSectionName !=
".opd")
732 e = si->relocation_end();
737 if (TypeFunc != ELF::R_PPC64_ADDR64) {
742 uint64_t TargetSymbolOffset = i->getOffset();
745 if (
auto AddendOrErr = i->getAddend())
746 Addend = *AddendOrErr;
748 return AddendOrErr.takeError();
756 if (TypeTOC != ELF::R_PPC64_TOC)
762 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
766 if (
auto TSIOrErr = TargetSymbol->
getSection())
769 return TSIOrErr.takeError();
772 bool IsCode = TSI->
isText();
777 return SectionIDOrErr.takeError();
778 Rel.
Addend = (intptr_t)Addend;
793 return (
value >> 16) & 0xffff;
797 return ((
value + 0x8000) >> 16) & 0xffff;
801 return (
value >> 32) & 0xffff;
805 return ((
value + 0x8000) >> 32) & 0xffff;
809 return (
value >> 48) & 0xffff;
813 return ((
value + 0x8000) >> 48) & 0xffff;
816void RuntimeDyldELF::resolvePPC32Relocation(
const SectionEntry &Section,
819 uint8_t *LocalAddress = Section.getAddressWithOffset(
Offset);
824 case ELF::R_PPC_ADDR16_LO:
827 case ELF::R_PPC_ADDR16_HI:
830 case ELF::R_PPC_ADDR16_HA:
836void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
839 uint8_t *LocalAddress =
Section.getAddressWithOffset(
Offset);
844 case ELF::R_PPC64_ADDR16:
847 case ELF::R_PPC64_ADDR16_DS:
850 case ELF::R_PPC64_ADDR16_LO:
853 case ELF::R_PPC64_ADDR16_LO_DS:
856 case ELF::R_PPC64_ADDR16_HI:
857 case ELF::R_PPC64_ADDR16_HIGH:
860 case ELF::R_PPC64_ADDR16_HA:
861 case ELF::R_PPC64_ADDR16_HIGHA:
864 case ELF::R_PPC64_ADDR16_HIGHER:
867 case ELF::R_PPC64_ADDR16_HIGHERA:
870 case ELF::R_PPC64_ADDR16_HIGHEST:
873 case ELF::R_PPC64_ADDR16_HIGHESTA:
876 case ELF::R_PPC64_ADDR14: {
879 uint8_t aalk = *(LocalAddress + 3);
882 case ELF::R_PPC64_REL16_LO: {
887 case ELF::R_PPC64_REL16_HI: {
892 case ELF::R_PPC64_REL16_HA: {
897 case ELF::R_PPC64_ADDR32: {
898 int64_t
Result =
static_cast<int64_t
>(
Value + Addend);
899 if (SignExtend64<32>(Result) !=
Result)
903 case ELF::R_PPC64_REL24: {
905 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
906 if (SignExtend64<26>(delta) != delta)
910 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
912 case ELF::R_PPC64_REL32: {
914 int64_t delta =
static_cast<int64_t
>(
Value - FinalAddress + Addend);
915 if (SignExtend64<32>(delta) != delta)
919 case ELF::R_PPC64_REL64: {
924 case ELF::R_PPC64_ADDR64:
930void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
933 uint8_t *LocalAddress =
Section.getAddressWithOffset(
Offset);
938 case ELF::R_390_PC16DBL:
939 case ELF::R_390_PLT16DBL: {
941 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
945 case ELF::R_390_PC32DBL:
946 case ELF::R_390_PLT32DBL: {
948 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
952 case ELF::R_390_PC16: {
954 assert(int16_t(Delta) == Delta &&
"R_390_PC16 overflow");
958 case ELF::R_390_PC32: {
960 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
964 case ELF::R_390_PC64: {
970 *LocalAddress = (uint8_t)(
Value + Addend);
984void RuntimeDyldELF::resolveBPFRelocation(
const SectionEntry &Section,
993 case ELF::R_BPF_NONE:
994 case ELF::R_BPF_64_64:
995 case ELF::R_BPF_64_32:
996 case ELF::R_BPF_64_NODYLD32:
998 case ELF::R_BPF_64_ABS64: {
1004 case ELF::R_BPF_64_ABS32: {
1042void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
1045 uint64_t SymOffset, SID SectionID) {
1048 resolveX86_64Relocation(Section,
Offset,
Value,
Type, Addend, SymOffset);
1085void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID,
uint64_t Offset)
const {
1091 if (
Value.SymbolName)
1098 bool IsLocal)
const {
1100 case ELF::R_MICROMIPS_GOT16:
1102 return ELF::R_MICROMIPS_LO16;
1104 case ELF::R_MICROMIPS_HI16:
1105 return ELF::R_MICROMIPS_LO16;
1106 case ELF::R_MIPS_GOT16:
1108 return ELF::R_MIPS_LO16;
1110 case ELF::R_MIPS_HI16:
1111 return ELF::R_MIPS_LO16;
1112 case ELF::R_MIPS_PCHI16:
1113 return ELF::R_MIPS_PCLO16;
1117 return ELF::R_MIPS_NONE;
1129bool RuntimeDyldELF::resolveAArch64ShortBranch(
1133 if (
Value.SymbolName) {
1140 const auto &
SymInfo = Loc->second;
1153 if (!isInt<28>(
Address +
Value.Addend - SourceAddress))
1162void RuntimeDyldELF::resolveAArch64Branch(
unsigned SectionID,
1167 LLVM_DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1171 unsigned RelType = RelI->getType();
1173 StubMap::const_iterator i = Stubs.find(
Value);
1174 if (i != Stubs.end()) {
1175 resolveRelocation(Section,
Offset,
1179 }
else if (!resolveAArch64ShortBranch(SectionID, RelI,
Value)) {
1187 ELF::R_AARCH64_MOVW_UABS_G3,
Value.Addend);
1189 StubTargetAddr -
Section.getAddress() + 4,
1190 ELF::R_AARCH64_MOVW_UABS_G2_NC,
Value.Addend);
1192 StubTargetAddr -
Section.getAddress() + 8,
1193 ELF::R_AARCH64_MOVW_UABS_G1_NC,
Value.Addend);
1195 StubTargetAddr -
Section.getAddress() + 12,
1196 ELF::R_AARCH64_MOVW_UABS_G0_NC,
Value.Addend);
1198 if (
Value.SymbolName) {
1209 resolveRelocation(Section,
Offset,
1213 Section.advanceStubOffset(getMaxStubSize());
1221 const auto &Obj = cast<ELFObjectFileBase>(O);
1222 uint64_t RelType = RelI->getType();
1225 Addend = *AddendOrErr;
1233 if (
auto TargetNameOrErr = Symbol->getName())
1234 TargetName = *TargetNameOrErr;
1236 return TargetNameOrErr.takeError();
1238 LLVM_DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
1239 <<
" TargetName: " << TargetName <<
"\n");
1249 if (!SymTypeOrErr) {
1255 SymType = *SymTypeOrErr;
1258 const auto &
SymInfo = gsi->second;
1268 auto SectionOrErr = Symbol->getSection();
1269 if (!SectionOrErr) {
1279 bool isCode = si->
isText();
1282 Value.SectionID = *SectionIDOrErr;
1284 return SectionIDOrErr.takeError();
1285 Value.Addend = Addend;
1293 Value.Addend = Addend;
1299 if (!
Value.SymbolName)
1300 Value.SymbolName =
"";
1314 if ((RelType == ELF::R_AARCH64_CALL26 ||
1315 RelType == ELF::R_AARCH64_JUMP26) &&
1317 resolveAArch64Branch(SectionID,
Value, RelI, Stubs);
1318 }
else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
1321 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1322 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1323 ELF::R_AARCH64_ADR_PREL_PG_HI21);
1325 }
else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
1326 uint64_t GOTOffset = findOrAllocGOTEntry(
Value, ELF::R_AARCH64_ABS64);
1327 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1328 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
1330 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1333 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1334 RelType == ELF::R_ARM_JUMP24) {
1340 StubMap::const_iterator i = Stubs.find(
Value);
1341 if (i != Stubs.end()) {
1344 reinterpret_cast<uint64_t>(Section.getAddressWithOffset(i->second)),
1350 Stubs[
Value] = Section.getStubOffset();
1352 Section.getAddressWithOffset(Section.getStubOffset()));
1354 ELF::R_ARM_ABS32,
Value.Addend);
1355 if (
Value.SymbolName)
1361 Section.getAddressWithOffset(
1362 Section.getStubOffset())),
1364 Section.advanceStubOffset(getMaxStubSize());
1368 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID,
Offset));
1369 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1370 RelType == ELF::R_ARM_ABS32) {
1371 Value.Addend += *Placeholder;
1372 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1374 Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1376 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1379 uint8_t *Placeholder =
reinterpret_cast<uint8_t *
>(
1380 computePlaceholderAddress(SectionID,
Offset));
1382 if (RelType == ELF::R_MIPS_26) {
1392 Value.Addend += Addend;
1395 StubMap::const_iterator i = Stubs.find(
Value);
1396 if (i != Stubs.end()) {
1403 Stubs[
Value] = Section.getStubOffset();
1408 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1411 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1412 ELF::R_MIPS_HI16,
Value.Addend);
1414 StubTargetAddr - Section.getAddress() + 4,
1415 ELF::R_MIPS_LO16,
Value.Addend);
1417 if (
Value.SymbolName) {
1427 Section.advanceStubOffset(getMaxStubSize());
1429 }
else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1430 int64_t Addend = (
Opcode & 0x0000ffff) << 16;
1432 PendingRelocs.push_back(std::make_pair(
Value, RE));
1433 }
else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1434 int64_t Addend =
Value.Addend + SignExtend32<16>(
Opcode & 0x0000ffff);
1435 for (
auto I = PendingRelocs.begin();
I != PendingRelocs.end();) {
1438 if (MatchingValue ==
Value &&
1439 RelType == getMatchingLoRelocation(Reloc.
RelType) &&
1442 if (
Value.SymbolName)
1446 I = PendingRelocs.erase(
I);
1451 if (
Value.SymbolName)
1456 if (RelType == ELF::R_MIPS_32)
1458 else if (RelType == ELF::R_MIPS_PC16)
1459 Value.Addend += SignExtend32<18>((
Opcode & 0x0000ffff) << 2);
1460 else if (RelType == ELF::R_MIPS_PC19_S2)
1461 Value.Addend += SignExtend32<21>((
Opcode & 0x0007ffff) << 2);
1462 else if (RelType == ELF::R_MIPS_PC21_S2)
1463 Value.Addend += SignExtend32<23>((
Opcode & 0x001fffff) << 2);
1464 else if (RelType == ELF::R_MIPS_PC26_S2)
1465 Value.Addend += SignExtend32<28>((
Opcode & 0x03ffffff) << 2);
1466 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1471 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1472 || r_type == ELF::R_MIPS_GOT_DISP) {
1474 if (i != GOTSymbolOffsets.
end())
1478 GOTSymbolOffsets[TargetName] = RE.
SymOffset;
1480 if (
Value.SymbolName)
1484 }
else if (RelType == ELF::R_MIPS_26) {
1490 StubMap::const_iterator i = Stubs.find(
Value);
1491 if (i != Stubs.end()) {
1498 Stubs[
Value] = Section.getStubOffset();
1503 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1507 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1508 ELF::R_MIPS_HI16,
Value.Addend);
1510 StubTargetAddr - Section.getAddress() + 4,
1511 ELF::R_MIPS_LO16,
Value.Addend);
1512 if (
Value.SymbolName) {
1523 StubTargetAddr - Section.getAddress(),
1524 ELF::R_MIPS_HIGHEST,
Value.Addend);
1526 StubTargetAddr - Section.getAddress() + 4,
1527 ELF::R_MIPS_HIGHER,
Value.Addend);
1529 StubTargetAddr - Section.getAddress() + 12,
1530 ELF::R_MIPS_HI16,
Value.Addend);
1532 StubTargetAddr - Section.getAddress() + 20,
1533 ELF::R_MIPS_LO16,
Value.Addend);
1534 if (
Value.SymbolName) {
1548 Section.advanceStubOffset(getMaxStubSize());
1551 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1555 if (RelType == ELF::R_PPC64_REL24) {
1564 uint8_t *
Target = Section.getAddressWithOffset(
Offset);
1565 bool RangeOverflow =
false;
1568 if (AbiVariant != 2) {
1572 if (
auto Err = findOPDEntrySection(Obj, ObjSectionToID,
Value))
1573 return std::move(Err);
1577 if (
Value.SectionID == SectionID){
1578 uint8_t SymOther = Symbol->getOther();
1582 uint8_t *RelocTarget =
1584 int64_t delta =
static_cast<int64_t
>(
Target - RelocTarget);
1586 if (SignExtend64<26>(delta) != delta) {
1587 RangeOverflow =
true;
1588 }
else if ((AbiVariant != 2) ||
1589 (AbiVariant == 2 &&
Value.SectionID == SectionID)) {
1594 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID) ||
1598 StubMap::const_iterator i = Stubs.find(
Value);
1599 if (i != Stubs.end()) {
1601 resolveRelocation(Section,
Offset,
1603 Section.getAddressWithOffset(i->second)),
1609 Stubs[
Value] = Section.getStubOffset();
1611 Section.getAddressWithOffset(Section.getStubOffset()),
1614 ELF::R_PPC64_ADDR64,
Value.Addend);
1620 uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
1622 StubRelocOffset += 2;
1625 ELF::R_PPC64_ADDR16_HIGHEST,
Value.Addend);
1627 ELF::R_PPC64_ADDR16_HIGHER,
Value.Addend);
1629 ELF::R_PPC64_ADDR16_HI,
Value.Addend);
1631 ELF::R_PPC64_ADDR16_LO,
Value.Addend);
1633 if (
Value.SymbolName) {
1646 Section.getAddressWithOffset(
1647 Section.getStubOffset())),
1649 Section.advanceStubOffset(getMaxStubSize());
1651 if (IsExtern || (AbiVariant == 2 &&
Value.SectionID != SectionID)) {
1653 if (AbiVariant == 2)
1659 }
else if (RelType == ELF::R_PPC64_TOC16 ||
1660 RelType == ELF::R_PPC64_TOC16_DS ||
1661 RelType == ELF::R_PPC64_TOC16_LO ||
1662 RelType == ELF::R_PPC64_TOC16_LO_DS ||
1663 RelType == ELF::R_PPC64_TOC16_HI ||
1664 RelType == ELF::R_PPC64_TOC16_HA) {
1676 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
1677 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
1678 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
1679 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
1680 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
1681 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
1686 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
1687 return std::move(Err);
1697 if (RelType == ELF::R_PPC64_TOC) {
1698 RelType = ELF::R_PPC64_ADDR64;
1699 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
1700 return std::move(Err);
1701 }
else if (TargetName ==
".TOC.") {
1702 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID,
Value))
1703 return std::move(Err);
1704 Value.Addend += Addend;
1709 if (
Value.SymbolName)
1715 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
1725 LLVM_DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
1729 StubMap::const_iterator i = Stubs.find(
Value);
1730 uintptr_t StubAddress;
1731 if (i != Stubs.end()) {
1732 StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
1738 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
1740 alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
1741 unsigned StubOffset = StubAddress - BaseAddress;
1743 Stubs[
Value] = StubOffset;
1747 if (
Value.SymbolName)
1751 Section.advanceStubOffset(getMaxStubSize());
1754 if (RelType == ELF::R_390_GOTENT)
1755 resolveRelocation(Section,
Offset, StubAddress + 8, ELF::R_390_PC32DBL,
1758 resolveRelocation(Section,
Offset, StubAddress, RelType, Addend);
1760 if (RelType == ELF::R_X86_64_PLT32) {
1781 StubMap::const_iterator i = Stubs.find(
Value);
1782 uintptr_t StubAddress;
1783 if (i != Stubs.end()) {
1784 StubAddress = uintptr_t(Section->getAddress()) + i->second;
1790 uintptr_t BaseAddress = uintptr_t(Section->getAddress());
1791 StubAddress =
alignTo(BaseAddress + Section->getStubOffset(),
1792 getStubAlignment());
1793 unsigned StubOffset = StubAddress - BaseAddress;
1794 Stubs[
Value] = StubOffset;
1798 Section->advanceStubOffset(getMaxStubSize());
1801 uint64_t GOTOffset = allocateGOTEntries(1);
1807 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
1808 ELF::R_X86_64_PC32);
1812 computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
1817 resolveRelocation(*Section,
Offset, StubAddress, ELF::R_X86_64_PC32,
1821 computePlaceholderAddress(SectionID,
Offset));
1822 processSimpleRelocation(SectionID,
Offset, ELF::R_X86_64_PC32,
Value);
1824 }
else if (RelType == ELF::R_X86_64_GOTPCREL ||
1825 RelType == ELF::R_X86_64_GOTPCRELX ||
1826 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
1827 uint64_t GOTOffset = allocateGOTEntries(1);
1828 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
1829 ELF::R_X86_64_PC32);
1833 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
1834 if (
Value.SymbolName)
1838 }
else if (RelType == ELF::R_X86_64_GOT64) {
1840 uint64_t GOTOffset = allocateGOTEntries(1);
1842 ELF::R_X86_64_64, 0);
1846 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_64);
1847 if (
Value.SymbolName)
1851 }
else if (RelType == ELF::R_X86_64_GOTPC32) {
1855 (void)allocateGOTEntries(0);
1856 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC32);
1857 }
else if (RelType == ELF::R_X86_64_GOTPC64) {
1858 (void)allocateGOTEntries(0);
1859 resolveGOTOffsetRelocation(SectionID,
Offset, Addend, ELF::R_X86_64_PC64);
1860 }
else if (RelType == ELF::R_X86_64_GOTOFF64) {
1862 (void)allocateGOTEntries(0);
1863 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1864 }
else if (RelType == ELF::R_X86_64_PC32) {
1866 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1867 }
else if (RelType == ELF::R_X86_64_PC64) {
1869 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1870 }
else if (RelType == ELF::R_X86_64_GOTTPOFF) {
1871 processX86_64GOTTPOFFRelocation(SectionID,
Offset,
Value, Addend);
1872 }
else if (RelType == ELF::R_X86_64_TLSGD ||
1873 RelType == ELF::R_X86_64_TLSLD) {
1876 auto &GetAddrRelocation = *RelI;
1877 processX86_64TLSRelocation(SectionID,
Offset, RelType,
Value, Addend,
1880 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1886 processSimpleRelocation(SectionID,
Offset, RelType,
Value);
1891void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(
unsigned SectionID,
1902 struct CodeSequence {
1914 std::array<CodeSequence, 2> CodeSequences;
1918 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
1919 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
1921 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00
1924 CodeSequences[0].ExpectedCodeSequence =
1926 CodeSequences[0].TLSSequenceOffset = 12;
1928 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
1929 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
1930 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
1933 CodeSequences[0].TpoffRelocationOffset = 12;
1938 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
1939 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
1940 0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00
1942 CodeSequences[1].ExpectedCodeSequence =
1944 CodeSequences[1].TLSSequenceOffset = 3;
1946 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
1947 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
1948 0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
1951 CodeSequences[1].TpoffRelocationOffset = 10;
1956 for (
const auto &
C : CodeSequences) {
1957 assert(
C.ExpectedCodeSequence.size() ==
C.NewCodeSequence.size() &&
1958 "Old and new code sequences must have the same size");
1960 if (
Offset <
C.TLSSequenceOffset ||
1961 (
Offset -
C.TLSSequenceOffset +
C.NewCodeSequence.size()) >
1968 auto TLSSequenceStartOffset =
Offset -
C.TLSSequenceOffset;
1969 auto *TLSSequence =
Section.getAddressWithOffset(TLSSequenceStartOffset);
1971 C.ExpectedCodeSequence) {
1975 memcpy(TLSSequence,
C.NewCodeSequence.data(),
C.NewCodeSequence.size());
1982 TLSSequenceStartOffset +
C.TpoffRelocationOffset,
1983 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
1985 if (
Value.SymbolName)
1998 uint64_t GOTOffset = allocateGOTEntries(1);
1999 resolveGOTOffsetRelocation(SectionID,
Offset, GOTOffset + Addend,
2000 ELF::R_X86_64_PC32);
2002 computeGOTOffsetRE(GOTOffset,
Value.Offset, ELF::R_X86_64_TPOFF64);
2003 if (
Value.SymbolName)
2010void RuntimeDyldELF::processX86_64TLSRelocation(
2023 bool IsSmallCodeModel;
2025 bool IsGOTPCRel =
false;
2027 switch (GetAddrRelocation.
getType()) {
2028 case ELF::R_X86_64_GOTPCREL:
2029 case ELF::R_X86_64_REX_GOTPCRELX:
2030 case ELF::R_X86_64_GOTPCRELX:
2033 case ELF::R_X86_64_PLT32:
2034 IsSmallCodeModel =
true;
2036 case ELF::R_X86_64_PLTOFF64:
2037 IsSmallCodeModel =
false;
2041 "invalid TLS relocations for General/Local Dynamic TLS Model: "
2042 "expected PLT or GOT relocation for __tls_get_addr function");
2053 if (RelType == ELF::R_X86_64_TLSGD) {
2058 if (IsSmallCodeModel) {
2060 static const std::initializer_list<uint8_t> CodeSequence = {
2062 0x48, 0x8d, 0x3d, 0x00, 0x00,
2066 0xe8, 0x00, 0x00, 0x00, 0x00
2069 TLSSequenceOffset = 4;
2073 static const std::initializer_list<uint8_t> CodeSequence = {
2075 0x48, 0x8d, 0x3d, 0x00, 0x00,
2079 0xff, 0x15, 0x00, 0x00, 0x00,
2083 TLSSequenceOffset = 4;
2088 static const std::initializer_list<uint8_t> SmallSequence = {
2089 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2091 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2095 TpoffRelocOffset = 12;
2097 static const std::initializer_list<uint8_t> CodeSequence = {
2098 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2100 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2106 TLSSequenceOffset = 3;
2109 static const std::initializer_list<uint8_t> LargeSequence = {
2110 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2112 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
2114 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
2117 TpoffRelocOffset = 12;
2124 ELF::R_X86_64_TPOFF32,
Value.Addend - Addend);
2125 if (
Value.SymbolName)
2129 }
else if (RelType == ELF::R_X86_64_TLSLD) {
2130 if (IsSmallCodeModel) {
2132 static const std::initializer_list<uint8_t> CodeSequence = {
2133 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00,
2134 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00
2137 TLSSequenceOffset = 3;
2140 static const std::initializer_list<uint8_t> SmallSequence = {
2142 0x64, 0x48, 0x8b, 0x04, 0x25,
2143 0x00, 0x00, 0x00, 0x00
2149 static const std::initializer_list<uint8_t> CodeSequence = {
2150 0x48, 0x8d, 0x3d, 0x00,
2152 0xff, 0x15, 0x00, 0x00,
2157 TLSSequenceOffset = 3;
2161 static const std::initializer_list<uint8_t> SmallSequence = {
2162 0x0f, 0x1f, 0x40, 0x00,
2163 0x64, 0x48, 0x8b, 0x04, 0x25,
2164 0x00, 0x00, 0x00, 0x00
2171 static const std::initializer_list<uint8_t> CodeSequence = {
2172 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2174 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180 TLSSequenceOffset = 3;
2183 static const std::initializer_list<uint8_t> LargeSequence = {
2185 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
2187 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
2196 "Old and new code sequences must have the same size");
2199 if (
Offset < TLSSequenceOffset ||
2200 (
Offset - TLSSequenceOffset + NewCodeSequence.
size()) >
2205 auto *TLSSequence =
Section.getAddressWithOffset(
Offset - TLSSequenceOffset);
2207 ExpectedCodeSequence) {
2209 "invalid TLS sequence for Global/Local Dynamic TLS Model");
2212 memcpy(TLSSequence, NewCodeSequence.
data(), NewCodeSequence.
size());
2250uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned no) {
2251 if (GOTSectionID == 0) {
2258 CurrentGOTIndex += no;
2263 unsigned GOTRelType) {
2264 auto E = GOTOffsetMap.insert({
Value, 0});
2266 uint64_t GOTOffset = allocateGOTEntries(1);
2270 computeGOTOffsetRE(GOTOffset,
Value.Offset, GOTRelType);
2271 if (
Value.SymbolName)
2276 E.first->second = GOTOffset;
2279 return E.first->second;
2282void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID,
2302 if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
2303 if (IFuncStubSectionID == 0) {
2306 IFuncStubSectionID =
Sections.size();
2308 SectionEntry(
".text.__llvm_IFuncStubs",
nullptr, 0, 0, 0));
2310 IFuncStubOffset = 64;
2318 IFuncStubOffset += getMaxIFuncStubSize();
2325 if (!PendingRelocs.empty())
2326 return make_error<RuntimeDyldError>(
"Can't find matching LO16 reloc");
2330 if (IFuncStubSectionID != 0) {
2332 IFuncStubOffset, 1, IFuncStubSectionID,
".text.__llvm_IFuncStubs");
2333 if (!IFuncStubsAddr)
2334 return make_error<RuntimeDyldError>(
2335 "Unable to allocate memory for IFunc stubs!");
2337 SectionEntry(
".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
2338 IFuncStubOffset, 0);
2340 createIFuncResolver(IFuncStubsAddr);
2343 << IFuncStubSectionID <<
" Addr: "
2344 <<
Sections[IFuncStubSectionID].getAddress() <<
'\n');
2345 for (
auto &IFuncStub : IFuncStubs) {
2346 auto &Symbol = IFuncStub.OriginalSymbol;
2348 <<
" Offset: " <<
format(
"%p", Symbol.getOffset())
2349 <<
" IFuncStubOffset: "
2350 <<
format(
"%p\n", IFuncStub.StubOffset));
2351 createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
2352 Symbol.getSectionID(), Symbol.getOffset());
2355 IFuncStubSectionID = 0;
2356 IFuncStubOffset = 0;
2361 if (GOTSectionID != 0) {
2365 GOTSectionID,
".got",
false);
2367 return make_error<RuntimeDyldError>(
"Unable to allocate memory for GOT!");
2374 memset(
Addr, 0, TotalSize);
2380 if (SI->relocation_begin() != SI->relocation_end()) {
2383 return make_error<RuntimeDyldError>(
2387 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
2388 assert(i != SectionMap.end());
2392 GOTSymbolOffsets.
clear();
2397 ObjSectionToIDMap::iterator i, e;
2398 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
2408 if (
Name ==
".eh_frame") {
2409 UnregisteredEHFrameSections.
push_back(i->second);
2414 GOTOffsetMap.clear();
2416 CurrentGOTIndex = 0;
2425void RuntimeDyldELF::createIFuncResolver(uint8_t *
Addr)
const {
2437 const uint8_t StubCode[] = {
2445 0x41, 0xff, 0x53, 0x08,
2457 static_assert(
sizeof(StubCode) <= 64,
2458 "maximum size of the IFunc resolver is 64B");
2459 memcpy(
Addr, StubCode,
sizeof(StubCode));
2462 "IFunc resolver is not supported for target architecture");
2466void RuntimeDyldELF::createIFuncStub(
unsigned IFuncStubSectionID,
2469 unsigned IFuncSectionID,
2471 auto &IFuncStubSection =
Sections[IFuncStubSectionID];
2472 auto *
Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);
2496 uint64_t GOT1 = allocateGOTEntries(2);
2500 IFuncResolverOffset, {});
2502 RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
2505 const uint8_t StubCode[] = {
2506 0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00,
2509 assert(
sizeof(StubCode) <= getMaxIFuncStubSize() &&
2510 "IFunc stub size must not exceed getMaxIFuncStubSize()");
2511 memcpy(
Addr, StubCode,
sizeof(StubCode));
2515 resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
2516 GOT1 - 4, ELF::R_X86_64_PC32);
2522unsigned RuntimeDyldELF::getMaxIFuncStubSize()
const {
2529bool RuntimeDyldELF::relocationNeedsGot(
const RelocationRef &R)
const {
2530 unsigned RelTy =
R.getType();
2532 return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
2533 RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;
2536 return RelTy == ELF::R_X86_64_GOTPCREL ||
2537 RelTy == ELF::R_X86_64_GOTPCRELX ||
2538 RelTy == ELF::R_X86_64_GOT64 ||
2539 RelTy == ELF::R_X86_64_REX_GOTPCRELX;
2543bool RuntimeDyldELF::relocationNeedsStub(
const RelocationRef &R)
const {
2547 switch (
R.getType()) {
2552 case ELF::R_X86_64_GOTPCREL:
2553 case ELF::R_X86_64_GOTPCRELX:
2554 case ELF::R_X86_64_REX_GOTPCRELX:
2555 case ELF::R_X86_64_GOTPC64:
2556 case ELF::R_X86_64_GOT64:
2557 case ELF::R_X86_64_GOTOFF64:
2558 case ELF::R_X86_64_PC32:
2559 case ELF::R_X86_64_PC64:
2560 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())
static constexpr uint32_t Opcode
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
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)
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.
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...
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, bool ContinueOnCuIndexOverflow)
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)
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 ...