LLVM: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24using namespace llvm;
27
28#define DEBUG_TYPE "dyld"
29
31
33 or32le(L, (Imm & 0xFFF) << 10);
34}
35
36template static void write(bool isBE, void *P, T V) {
39}
40
42 uint32_t ImmLo = (Imm & 0x3) << 29;
43 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
44 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
46}
47
48
49
52 return (Val >> Start) & Mask;
53}
54
55namespace {
56
57template class DyldELFObject : public ELFObjectFile {
59
60 typedef typename ELFT::uint addr_type;
61
62 DyldELFObject(ELFObjectFile &&Obj);
63
64public:
65 static Expected<std::unique_ptr>
66 create(MemoryBufferRef Wrapper);
67
68 void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
69
70 void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
71
72
73 static bool classof(const Binary *v) {
74 return (isa<ELFObjectFile>(v) &&
75 classof(cast<ELFObjectFile>(v)));
76 }
77 static bool classof(const ELFObjectFile *v) {
78 return v->isDyldType();
79 }
80};
81
82
83
84
85
86
87template
90 this->isDyldELFObject = true;
91}
92
93template
97 if (auto E = Obj.takeError())
98 return std::move(E);
99 std::unique_ptr<DyldELFObject> Ret(
100 new DyldELFObject(std::move(*Obj)));
101 return std::move(Ret);
102}
103
104template
105void DyldELFObject::updateSectionAddress(const SectionRef &Sec,
108 Elf_Shdr *shdr =
109 const_cast<Elf_Shdr *>(reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
110
111
112
113 shdr->sh_addr = static_cast<addr_type>(Addr);
114}
115
116template
117void DyldELFObject::updateSymbolAddress(const SymbolRef &SymRef,
119
120 Elf_Sym *sym = const_cast<Elf_Sym *>(
122
123
124
125 sym->st_value = static_cast<addr_type>(Addr);
126}
127
128class LoadedELFObjectInfo final
130 RuntimeDyld::LoadedObjectInfo> {
131public:
132 LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
133 : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
134
135 OwningBinary
136 getObjectForDebug(const ObjectFile &Obj) const override;
137};
138
139template
142 const LoadedELFObjectInfo &L) {
143 typedef typename ELFT::Shdr Elf_Shdr;
144 typedef typename ELFT::uint addr_type;
145
147 DyldELFObject::create(Buffer);
149 return std::move(E);
150
151 std::unique_ptr<DyldELFObject> Obj = std::move(*ObjOrErr);
152
153
155 for (const auto &Sec : Obj->sections()) {
157 if (!NameOrErr) {
159 continue;
160 }
161
162 if (*NameOrErr != "") {
164 Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
165 reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
166
167 if (uint64_t SecLoadAddr = L.getSectionLoadAddress(*SI)) {
168
169
170 shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
171 }
172 }
173 ++SI;
174 }
175
176 return std::move(Obj);
177}
178
180createELFDebugObject(const ObjectFile &Obj, const LoadedELFObjectInfo &L) {
181 assert(Obj.isELF() && "Not an ELF object file.");
182
183 std::unique_ptr Buffer =
185
188 if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian())
189 DebugObj =
190 createRTDyldELFObject(Buffer->getMemBufferRef(), Obj, L);
191 else if (Obj.getBytesInAddress() == 4 && .isLittleEndian())
192 DebugObj =
193 createRTDyldELFObject(Buffer->getMemBufferRef(), Obj, L);
194 else if (Obj.getBytesInAddress() == 8 && .isLittleEndian())
195 DebugObj =
196 createRTDyldELFObject(Buffer->getMemBufferRef(), Obj, L);
197 else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian())
198 DebugObj =
199 createRTDyldELFObject(Buffer->getMemBufferRef(), Obj, L);
200 else
202
205}
206
208LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
209 return createELFDebugObject(Obj, *this);
210}
211
212}
213
214namespace llvm {
215
220
222 for (SID EHFrameSID : UnregisteredEHFrameSections) {
223 uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();
224 uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress();
225 size_t EHFrameSize = Sections[EHFrameSID].getSize();
226 MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
227 }
228 UnregisteredEHFrameSections.clear();
229}
230
231std::unique_ptr
235 switch (Arch) {
236 default:
237 return std::make_unique(MemMgr, Resolver);
242 return std::make_unique(MemMgr, Resolver);
243 }
244}
245
246std::unique_ptrRuntimeDyld::LoadedObjectInfo
249 return std::make_unique(*this, *ObjSectionToIDOrErr);
250 else {
254 return nullptr;
255 }
256}
257
258void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
262 switch (Type) {
263 default:
265 break;
266 case ELF::R_X86_64_NONE:
267 break;
268 case ELF::R_X86_64_8: {
270 assert((int64_t)Value <= INT8_MAX && (int64_t)Value >= INT8_MIN);
272 *Section.getAddressWithOffset(Offset) = TruncatedAddr;
274 << format("%p\n", Section.getAddressWithOffset(Offset)));
275 break;
276 }
277 case ELF::R_X86_64_16: {
279 assert((int64_t)Value <= INT16_MAX && (int64_t)Value >= INT16_MIN);
281 support::ulittle16_t::ref(Section.getAddressWithOffset(Offset)) =
282 TruncatedAddr;
284 << format("%p\n", Section.getAddressWithOffset(Offset)));
285 break;
286 }
287 case ELF::R_X86_64_64: {
288 support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
292 break;
293 }
294 case ELF::R_X86_64_32:
295 case ELF::R_X86_64_32S: {
297 assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
298 (Type == ELF::R_X86_64_32S &&
299 ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
300 uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
301 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
302 TruncatedAddr;
305 break;
306 }
307 case ELF::R_X86_64_PC8: {
308 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
309 int64_t RealOffset = Value + Addend - FinalAddress;
311 int8_t TruncOffset = (RealOffset & 0xFF);
313 break;
314 }
315 case ELF::R_X86_64_PC32: {
316 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
317 int64_t RealOffset = Value + Addend - FinalAddress;
319 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
320 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
321 TruncOffset;
322 break;
323 }
324 case ELF::R_X86_64_PC64: {
325 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
326 int64_t RealOffset = Value + Addend - FinalAddress;
327 support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
328 RealOffset;
330 << format("%p\n", FinalAddress));
331 break;
332 }
333 case ELF::R_X86_64_GOTOFF64: {
334
335 uint64_t GOTBase = 0;
336 for (const auto &Section : Sections) {
337 if (Section.getName() == ".got") {
338 GOTBase = Section.getLoadAddressWithOffset(0);
339 break;
340 }
341 }
342 assert(GOTBase != 0 && "missing GOT");
343 int64_t GOTOffset = Value - GOTBase + Addend;
344 support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = GOTOffset;
345 break;
346 }
347 case ELF::R_X86_64_DTPMOD64: {
348
349 support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = 1;
350 break;
351 }
352 case ELF::R_X86_64_DTPOFF64:
353 case ELF::R_X86_64_TPOFF64: {
354
355
356
357
358 support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
360 break;
361 }
362 case ELF::R_X86_64_DTPOFF32:
363 case ELF::R_X86_64_TPOFF32: {
364
365
366 int64_t RealValue = Value + Addend;
367 assert(RealValue >= INT32_MIN && RealValue <= INT32_MAX);
368 int32_t TruncValue = RealValue;
369 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
370 TruncValue;
371 break;
372 }
373 }
374}
375
376void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
378 uint32_t Type, int32_t Addend) {
379 switch (Type) {
380 case ELF::R_386_32: {
381 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
383 break;
384 }
385
386
387 case ELF::R_386_PLT32:
388 case ELF::R_386_PC32: {
389 uint32_t FinalAddress =
390 Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
391 uint32_t RealOffset = Value + Addend - FinalAddress;
392 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
393 RealOffset;
394 break;
395 }
396 default:
397
398
400 break;
401 }
402}
403
404void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
406 uint32_t Type, int64_t Addend) {
407 uint32_t *TargetPtr =
408 reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
409 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
410
412
413 LLVM_DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
415 << " FinalAddress: 0x" << format("%llx", FinalAddress)
416 << " Value: 0x" << format("%llx", Value) << " Type: 0x"
417 << format("%x", Type) << " Addend: 0x"
418 << format("%llx", Addend) << "\n");
419
420 switch (Type) {
421 default:
423 break;
424 case ELF::R_AARCH64_NONE:
425 break;
426 case ELF::R_AARCH64_ABS16: {
429 (Result >> 16) == 0);
430 write(isBE, TargetPtr, static_cast<uint16_t>(Result & 0xffffU));
431 break;
432 }
433 case ELF::R_AARCH64_ABS32: {
436 (Result >> 32) == 0);
437 write(isBE, TargetPtr, static_cast<uint32_t>(Result & 0xffffffffU));
438 break;
439 }
440 case ELF::R_AARCH64_ABS64:
441 write(isBE, TargetPtr, Value + Addend);
442 break;
443 case ELF::R_AARCH64_PLT32: {
444 uint64_t Result = Value + Addend - FinalAddress;
445 assert(static_cast<int64_t>(Result) >= INT32_MIN &&
446 static_cast<int64_t>(Result) <= INT32_MAX);
447 write(isBE, TargetPtr, static_cast<uint32_t>(Result));
448 break;
449 }
450 case ELF::R_AARCH64_PREL16: {
451 uint64_t Result = Value + Addend - FinalAddress;
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));
455 break;
456 }
457 case ELF::R_AARCH64_PREL32: {
458 uint64_t Result = Value + Addend - FinalAddress;
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));
462 break;
463 }
464 case ELF::R_AARCH64_PREL64:
465 write(isBE, TargetPtr, Value + Addend - FinalAddress);
466 break;
467 case ELF::R_AARCH64_CONDBR19: {
468 uint64_t BranchImm = Value + Addend - FinalAddress;
469
471 *TargetPtr &= 0xff00001fU;
472
473 or32le(TargetPtr, (BranchImm & 0x001FFFFC) << 3);
474 break;
475 }
476 case ELF::R_AARCH64_TSTBR14: {
477 uint64_t BranchImm = Value + Addend - FinalAddress;
478
480
483
484
485 or32le(TargetPtr, (BranchImm & 0x0000FFFC) << 3);
486 break;
487 }
488 case ELF::R_AARCH64_CALL26:
489 case ELF::R_AARCH64_JUMP26: {
490
491
492 uint64_t BranchImm = Value + Addend - FinalAddress;
493
494
496 or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
497 break;
498 }
499 case ELF::R_AARCH64_MOVW_UABS_G3:
500 or32le(TargetPtr, ((Value + Addend) & 0xFFFF000000000000) >> 43);
501 break;
502 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
503 or32le(TargetPtr, ((Value + Addend) & 0xFFFF00000000) >> 27);
504 break;
505 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
506 or32le(TargetPtr, ((Value + Addend) & 0xFFFF0000) >> 11);
507 break;
508 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
509 or32le(TargetPtr, ((Value + Addend) & 0xFFFF) << 5);
510 break;
511 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
512
514 ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
515
516
517 assert(isInt<33>(Result) && "overflow check failed for relocation");
518
519
520
522 break;
523 }
524 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
525
526
527
529 break;
530 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
531
532
533
535 break;
536 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
537
538
539
541 break;
542 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
543
544
545
547 break;
548 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
549
550
551
553 break;
554 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
555
556
557
559 break;
560 case ELF::R_AARCH64_LD_PREL_LO19: {
561
562 uint64_t Result = Value + Addend - FinalAddress;
563
564
566
567 *TargetPtr &= 0xff00001fU;
568
569
570 *TargetPtr |= ((Result & 0xffc) << (5 - 2));
571 break;
572 }
573 case ELF::R_AARCH64_ADR_PREL_LO21: {
574
575 uint64_t Result = Value + Addend - FinalAddress;
576
577
579
580 *TargetPtr &= 0x9f00001fU;
581
582
583 *TargetPtr |= ((Result & 0xffc) << (5 - 2));
584 *TargetPtr |= (Result & 0x3) << 29;
585 break;
586 }
587 }
588}
589
590void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
592 uint32_t Type, int32_t Addend) {
593
594 uint32_t *TargetPtr =
595 reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
596 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
598
599 LLVM_DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
601 << " FinalAddress: " << format("%p", FinalAddress)
604 << " Addend: " << format("%x", Addend) << "\n");
605
606 switch (Type) {
607 default:
609
610 case ELF::R_ARM_NONE:
611 break;
612
613 case ELF::R_ARM_PREL31:
614 support::ulittle32_t::ref{TargetPtr} =
615 (support::ulittle32_t::ref{TargetPtr} & 0x80000000) |
616 ((Value - FinalAddress) & ~0x80000000);
617 break;
618 case ELF::R_ARM_TARGET1:
619 case ELF::R_ARM_ABS32:
620 support::ulittle32_t::ref{TargetPtr} = Value;
621 break;
622
623
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)
630 support::ulittle32_t::ref{TargetPtr} =
631 (support::ulittle32_t::ref{TargetPtr} & ~0x000F0FFF) | (Value & 0xFFF) |
632 (((Value >> 12) & 0xF) << 16);
633 break;
634
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;
640 assert((support::ulittle32_t::ref{TargetPtr} & 0xFFFFFF) == 0xFFFFFE);
641 support::ulittle32_t::ref{TargetPtr} =
642 (support::ulittle32_t::ref{TargetPtr} & 0xFF000000) | RelValue;
643 break;
644 }
645}
646
647bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
651 if (Value.SymbolName) {
653
655 return false;
656 const auto &SymInfo = Loc->second;
657 Address = Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
658 SymInfo.getOffset());
659 } else {
661 }
663 uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
664 uint64_t Delta = Address + Value.Addend - SourceAddress;
665
666 if (RelI->getType() == ELF::R_LARCH_B26) {
668 return false;
671 return true;
672 }
673
674
675 if (((int64_t)Delta + 0x20000) != llvm::SignExtend64(Delta + 0x20000, 38))
676 return false;
679 return true;
680}
681
682void RuntimeDyldELF::resolveLoongArch64Branch(unsigned SectionID,
685 StubMap &Stubs) {
686 LLVM_DEBUG(dbgs() << "\t\tThis is an LoongArch64 branch relocation.\n");
687
688 if (resolveLoongArch64ShortBranch(SectionID, RelI, Value))
689 return;
690
693 unsigned RelType = RelI->getType();
694
696 if (!Inserted) {
697 resolveRelocation(Section, Offset,
698 (uint64_t)Section.getAddressWithOffset(It->second),
699 RelType, 0);
701 return;
702 }
703
704 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
705 It->second = Section.getStubOffset();
706 uint8_t *StubTargetAddr =
708 RelocationEntry LU12I_W(SectionID, StubTargetAddr - Section.getAddress(),
709 ELF::R_LARCH_ABS_HI20, Value.Addend);
710 RelocationEntry ORI(SectionID, StubTargetAddr - Section.getAddress() + 4,
711 ELF::R_LARCH_ABS_LO12, Value.Addend);
712 RelocationEntry LU32I_D(SectionID, StubTargetAddr - Section.getAddress() + 8,
713 ELF::R_LARCH_ABS64_LO20, Value.Addend);
714 RelocationEntry LU52I_D(SectionID, StubTargetAddr - Section.getAddress() + 12,
715 ELF::R_LARCH_ABS64_HI12, Value.Addend);
716 if (Value.SymbolName) {
721 } else {
725
727 }
728 resolveRelocation(Section, Offset,
729 reinterpret_cast<uint64_t>(
730 Section.getAddressWithOffset(Section.getStubOffset())),
731 RelType, 0);
733}
734
735
737 return Hi == 63 ? Val >> Lo : (Val & (((1ULL << (Hi + 1)) - 1))) >> Lo;
738}
739
740
741
745 switch (type) {
746 case ELF::R_LARCH_PCALA64_LO20:
747 case ELF::R_LARCH_GOT64_PC_LO20:
748 pcalau12i_pc = pc - 8;
749 break;
750 case ELF::R_LARCH_PCALA64_HI12:
751 case ELF::R_LARCH_GOT64_PC_HI12:
752 pcalau12i_pc = pc - 12;
753 break;
754 default:
755 pcalau12i_pc = pc;
756 break;
757 }
758 uint64_t result = (dest & ~0xfffULL) - (pcalau12i_pc & ~0xfffULL);
759 if (dest & 0x800)
760 result += 0x1000 - 0x1'0000'0000;
761 if (result & 0x8000'0000)
762 result += 0x1'0000'0000;
763 return result;
764}
765
766void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section,
769 int64_t Addend) {
770 auto *TargetPtr = Section.getAddressWithOffset(Offset);
771 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
772
773 LLVM_DEBUG(dbgs() << "resolveLoongArch64Relocation, LocalAddress: 0x"
774 << format("%llx", Section.getAddressWithOffset(Offset))
775 << " FinalAddress: 0x" << format("%llx", FinalAddress)
776 << " Value: 0x" << format("%llx", Value) << " Type: 0x"
777 << format("%x", Type) << " Addend: 0x"
778 << format("%llx", Addend) << "\n");
779
780 switch (Type) {
781 default:
783 break;
784 case ELF::R_LARCH_MARK_LA:
785
786 break;
787 case ELF::R_LARCH_32:
788 support::ulittle32_t::ref{TargetPtr} =
789 static_cast<uint32_t>(Value + Addend);
790 break;
791 case ELF::R_LARCH_64:
792 support::ulittle64_t::ref{TargetPtr} = Value + Addend;
793 break;
794 case ELF::R_LARCH_32_PCREL:
795 support::ulittle32_t::ref{TargetPtr} =
796 static_cast<uint32_t>(Value + Addend - FinalAddress);
797 break;
798 case ELF::R_LARCH_B26: {
799 uint64_t B26 = (Value + Addend - FinalAddress) >> 2;
800 auto Instr = support::ulittle32_t::ref(TargetPtr);
801 uint32_t Imm15_0 = extractBits(B26, 15, 0) << 10;
802 uint32_t Imm25_16 = extractBits(B26, 25, 16);
803 Instr = (Instr & 0xfc000000) | Imm15_0 | Imm25_16;
804 break;
805 }
806 case ELF::R_LARCH_CALL36: {
807 uint64_t Call36 = (Value + Addend - FinalAddress) >> 2;
808 auto Pcaddu18i = support::ulittle32_t::ref(TargetPtr);
809 uint32_t Imm35_16 =
810 extractBits((Call36 + (1UL << 15)), 35, 16) << 5;
811 Pcaddu18i = (Pcaddu18i & 0xfe00001f) | Imm35_16;
812 auto Jirl = support::ulittle32_t::ref(TargetPtr + 4);
813 uint32_t Imm15_0 = extractBits(Call36, 15, 0) << 10;
814 Jirl = (Jirl & 0xfc0003ff) | Imm15_0;
815 break;
816 }
817 case ELF::R_LARCH_GOT_PC_HI20:
818 case ELF::R_LARCH_PCALA_HI20: {
821 auto Instr = support::ulittle32_t::ref(TargetPtr);
822 uint32_t Imm31_12 = extractBits(PageDelta, 31, 12) << 5;
823 Instr = (Instr & 0xfe00001f) | Imm31_12;
824 break;
825 }
826 case ELF::R_LARCH_GOT_PC_LO12:
827 case ELF::R_LARCH_PCALA_LO12: {
828 uint64_t TargetOffset = (Value + Addend) & 0xfff;
829 auto Instr = support::ulittle32_t::ref(TargetPtr);
830 uint32_t Imm11_0 = TargetOffset << 10;
831 Instr = (Instr & 0xffc003ff) | Imm11_0;
832 break;
833 }
834 case ELF::R_LARCH_GOT64_PC_LO20:
835 case ELF::R_LARCH_PCALA64_LO20: {
838 auto Instr = support::ulittle32_t::ref(TargetPtr);
839 uint32_t Imm51_32 = extractBits(PageDelta, 51, 32) << 5;
840 Instr = (Instr & 0xfe00001f) | Imm51_32;
841 break;
842 }
843 case ELF::R_LARCH_GOT64_PC_HI12:
844 case ELF::R_LARCH_PCALA64_HI12: {
847 auto Instr = support::ulittle32_t::ref(TargetPtr);
848 uint32_t Imm63_52 = extractBits(PageDelta, 63, 52) << 10;
849 Instr = (Instr & 0xffc003ff) | Imm63_52;
850 break;
851 }
852 case ELF::R_LARCH_ABS_HI20: {
854 auto Instr = support::ulittle32_t::ref(TargetPtr);
855 uint32_t Imm31_12 = extractBits(Target, 31, 12) << 5;
856 Instr = (Instr & 0xfe00001f) | Imm31_12;
857 break;
858 }
859 case ELF::R_LARCH_ABS_LO12: {
861 auto Instr = support::ulittle32_t::ref(TargetPtr);
862 uint32_t Imm11_0 = extractBits(Target, 11, 0) << 10;
863 Instr = (Instr & 0xffc003ff) | Imm11_0;
864 break;
865 }
866 case ELF::R_LARCH_ABS64_LO20: {
868 auto Instr = support::ulittle32_t::ref(TargetPtr);
869 uint32_t Imm51_32 = extractBits(Target, 51, 32) << 5;
870 Instr = (Instr & 0xfe00001f) | Imm51_32;
871 break;
872 }
873 case ELF::R_LARCH_ABS64_HI12: {
875 auto Instr = support::ulittle32_t::ref(TargetPtr);
876 uint32_t Imm63_52 = extractBits(Target, 63, 52) << 10;
877 Instr = (Instr & 0xffc003ff) | Imm63_52;
878 break;
879 }
880 case ELF::R_LARCH_ADD32:
881 support::ulittle32_t::ref{TargetPtr} =
882 (support::ulittle32_t::ref{TargetPtr} +
883 static_cast<uint32_t>(Value + Addend));
884 break;
885 case ELF::R_LARCH_SUB32:
886 support::ulittle32_t::ref{TargetPtr} =
887 (support::ulittle32_t::ref{TargetPtr} -
888 static_cast<uint32_t>(Value + Addend));
889 break;
890 case ELF::R_LARCH_ADD64:
891 support::ulittle64_t::ref{TargetPtr} =
892 (support::ulittle64_t::ref{TargetPtr} + Value + Addend);
893 break;
894 case ELF::R_LARCH_SUB64:
895 support::ulittle64_t::ref{TargetPtr} =
896 (support::ulittle64_t::ref{TargetPtr} - Value - Addend);
897 break;
898 }
899}
900
901void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
907 return;
908 }
910 unsigned AbiVariant = E->getPlatformFlags();
913 }
915}
916
917
918Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,
919 ObjSectionToIDMap &LocalSections,
921
922
923
924
925
928
929
930
931 for (auto &Section : Obj.sections()) {
932 Expected NameOrErr = Section.getName();
933 if (!NameOrErr)
936
937 if (SectionName == ".got"
938 || SectionName == ".toc"
939 || SectionName == ".tocbss"
940 || SectionName == ".plt") {
941 if (auto SectionIDOrErr =
944 else
945 return SectionIDOrErr.takeError();
946 break;
947 }
948 }
949
950
951
953
955}
956
957
958
959Error RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
960 ObjSectionToIDMap &LocalSections,
962
963
965 si != se; ++si) {
966
967 Expected<section_iterator> RelSecOrErr = si->getRelocatedSection();
968 if (!RelSecOrErr)
970
972 if (RelSecI == Obj.section_end())
973 continue;
974
975 Expected NameOrErr = RelSecI->getName();
976 if (!NameOrErr)
978 StringRef RelSectionName = *NameOrErr;
979
980 if (RelSectionName != ".opd")
981 continue;
982
983 for (elf_relocation_iterator i = si->relocation_begin(),
984 e = si->relocation_end();
985 i != e;) {
986
987
988 uint64_t TypeFunc = i->getType();
989 if (TypeFunc != ELF::R_PPC64_ADDR64) {
990 ++i;
991 continue;
992 }
993
994 uint64_t TargetSymbolOffset = i->getOffset();
995 symbol_iterator TargetSymbol = i->getSymbol();
996 int64_t Addend;
997 if (auto AddendOrErr = i->getAddend())
998 Addend = *AddendOrErr;
999 else
1000 return AddendOrErr.takeError();
1001
1002 ++i;
1003 if (i == e)
1004 break;
1005
1006
1007 uint64_t TypeTOC = i->getType();
1008 if (TypeTOC != ELF::R_PPC64_TOC)
1009 continue;
1010
1011
1012
1013
1014 if (Rel.Addend != (int64_t)TargetSymbolOffset)
1015 continue;
1016
1018 if (auto TSIOrErr = TargetSymbol->getSection())
1019 TSI = *TSIOrErr;
1020 else
1021 return TSIOrErr.takeError();
1022 assert(TSI != Obj.section_end() && "TSI should refer to a valid section");
1023
1024 bool IsCode = TSI->isText();
1026 LocalSections))
1027 Rel.SectionID = *SectionIDOrErr;
1028 else
1029 return SectionIDOrErr.takeError();
1030 Rel.Addend = (intptr_t)Addend;
1032 }
1033 }
1034 llvm_unreachable("Attempting to get address of ODP entry!");
1035}
1036
1037
1038
1039
1040
1041
1043
1045 return (value >> 16) & 0xffff;
1046}
1047
1049 return ((value + 0x8000) >> 16) & 0xffff;
1050}
1051
1053 return (value >> 32) & 0xffff;
1054}
1055
1057 return ((value + 0x8000) >> 32) & 0xffff;
1058}
1059
1061 return (value >> 48) & 0xffff;
1062}
1063
1065 return ((value + 0x8000) >> 48) & 0xffff;
1066}
1067
1068void RuntimeDyldELF::resolvePPC32Relocation(const SectionEntry &Section,
1071 uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
1072 switch (Type) {
1073 default:
1075 break;
1076 case ELF::R_PPC_ADDR16_LO:
1078 break;
1079 case ELF::R_PPC_ADDR16_HI:
1081 break;
1082 case ELF::R_PPC_ADDR16_HA:
1084 break;
1085 }
1086}
1087
1088void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
1090 uint32_t Type, int64_t Addend) {
1091 uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
1092 switch (Type) {
1093 default:
1095 break;
1096 case ELF::R_PPC64_ADDR16:
1098 break;
1099 case ELF::R_PPC64_ADDR16_DS:
1101 break;
1102 case ELF::R_PPC64_ADDR16_LO:
1104 break;
1105 case ELF::R_PPC64_ADDR16_LO_DS:
1107 break;
1108 case ELF::R_PPC64_ADDR16_HI:
1109 case ELF::R_PPC64_ADDR16_HIGH:
1111 break;
1112 case ELF::R_PPC64_ADDR16_HA:
1113 case ELF::R_PPC64_ADDR16_HIGHA:
1115 break;
1116 case ELF::R_PPC64_ADDR16_HIGHER:
1118 break;
1119 case ELF::R_PPC64_ADDR16_HIGHERA:
1121 break;
1122 case ELF::R_PPC64_ADDR16_HIGHEST:
1124 break;
1125 case ELF::R_PPC64_ADDR16_HIGHESTA:
1127 break;
1128 case ELF::R_PPC64_ADDR14: {
1130
1131 uint8_t aalk = *(LocalAddress + 3);
1132 writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
1133 } break;
1134 case ELF::R_PPC64_REL16_LO: {
1135 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1136 uint64_t Delta = Value - FinalAddress + Addend;
1138 } break;
1139 case ELF::R_PPC64_REL16_HI: {
1140 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1141 uint64_t Delta = Value - FinalAddress + Addend;
1143 } break;
1144 case ELF::R_PPC64_REL16_HA: {
1145 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1146 uint64_t Delta = Value - FinalAddress + Addend;
1148 } break;
1149 case ELF::R_PPC64_ADDR32: {
1150 int64_t Result = static_cast<int64_t>(Value + Addend);
1154 } break;
1155 case ELF::R_PPC64_REL24: {
1156 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1157 int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
1160
1162 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
1163 } break;
1164 case ELF::R_PPC64_REL32: {
1165 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1166 int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
1170 } break;
1171 case ELF::R_PPC64_REL64: {
1172 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1173 uint64_t Delta = Value - FinalAddress + Addend;
1175 } break;
1176 case ELF::R_PPC64_ADDR64:
1178 break;
1179 }
1180}
1181
1182void RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section,
1184 uint32_t Type, int64_t Addend) {
1185 uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
1186 switch (Type) {
1187 default:
1189 break;
1190 case ELF::R_390_PC16DBL:
1191 case ELF::R_390_PLT16DBL: {
1192 int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1193 assert(int16_t(Delta / 2) * 2 == Delta && "R_390_PC16DBL overflow");
1195 break;
1196 }
1197 case ELF::R_390_PC32DBL:
1198 case ELF::R_390_PLT32DBL: {
1199 int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1200 assert(int32_t(Delta / 2) * 2 == Delta && "R_390_PC32DBL overflow");
1202 break;
1203 }
1204 case ELF::R_390_PC16: {
1205 int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1206 assert(int16_t(Delta) == Delta && "R_390_PC16 overflow");
1208 break;
1209 }
1210 case ELF::R_390_PC32: {
1211 int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1212 assert(int32_t(Delta) == Delta && "R_390_PC32 overflow");
1214 break;
1215 }
1216 case ELF::R_390_PC64: {
1217 int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1219 break;
1220 }
1221 case ELF::R_390_8:
1222 *LocalAddress = (uint8_t)(Value + Addend);
1223 break;
1224 case ELF::R_390_16:
1226 break;
1227 case ELF::R_390_32:
1229 break;
1230 case ELF::R_390_64:
1232 break;
1233 }
1234}
1235
1236void RuntimeDyldELF::resolveBPFRelocation(const SectionEntry &Section,
1238 uint32_t Type, int64_t Addend) {
1240
1241 switch (Type) {
1242 default:
1244 break;
1245 case ELF::R_BPF_NONE:
1246 case ELF::R_BPF_64_64:
1247 case ELF::R_BPF_64_32:
1248 case ELF::R_BPF_64_NODYLD32:
1249 break;
1250 case ELF::R_BPF_64_ABS64: {
1254 break;
1255 }
1256 case ELF::R_BPF_64_ABS32: {
1257 Value += Addend;
1262 break;
1263 }
1264 }
1265}
1266
1268 uint32_t UpperImm = (Imm + 0x800) & 0xfffff000;
1269 auto Instr = support::ulittle32_t::ref(InstrAddr);
1270 Instr = (Instr & 0xfff) | UpperImm;
1271}
1272
1274 uint32_t LowerImm = Imm & 0xfff;
1275 auto Instr = support::ulittle32_t::ref(InstrAddr);
1276 Instr = (Instr & 0xfffff) | (LowerImm << 20);
1277}
1278
1279void RuntimeDyldELF::resolveRISCVRelocation(const SectionEntry &Section,
1282 SID SectionID) {
1283 switch (Type) {
1284 default: {
1285 std::string Err = "Unimplemented reloc type: " + std::to_string(Type);
1287 }
1288
1289
1290
1291 case ELF::R_RISCV_CALL:
1292 case ELF::R_RISCV_CALL_PLT: {
1293 uint64_t P = Section.getLoadAddressWithOffset(Offset);
1294 uint64_t PCOffset = Value + Addend - P;
1297 break;
1298 }
1299
1300 case ELF::R_RISCV_HI20: {
1301 uint64_t PCOffset = Value + Addend;
1303 break;
1304 }
1305
1306 case ELF::R_RISCV_LO12_I: {
1307 uint64_t PCOffset = Value + Addend;
1309 break;
1310 }
1311
1312 case ELF::R_RISCV_GOT_HI20:
1313 case ELF::R_RISCV_PCREL_HI20: {
1314 uint64_t P = Section.getLoadAddressWithOffset(Offset);
1315 uint64_t PCOffset = Value + Addend - P;
1317 break;
1318 }
1319
1320
1321
1322
1323
1324
1325
1326
1327 case ELF::R_RISCV_PCREL_LO12_I: {
1328 for (auto &&PendingReloc : PendingRelocs) {
1329 const RelocationValueRef &MatchingValue = PendingReloc.first;
1330 RelocationEntry &Reloc = PendingReloc.second;
1331 uint64_t HIRelocPC =
1333 if (Value + Addend == HIRelocPC) {
1335 MatchingValue.Addend;
1336 auto PCOffset = Symbol - HIRelocPC;
1338 return;
1339 }
1340 }
1341
1343 "R_RISCV_PCREL_LO12_I without matching R_RISCV_PCREL_HI20");
1344 }
1345 case ELF::R_RISCV_32_PCREL: {
1346 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1347 int64_t RealOffset = Value + Addend - FinalAddress;
1348 int32_t TruncOffset = Lo_32(RealOffset);
1349 support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
1350 TruncOffset;
1351 break;
1352 }
1353 case ELF::R_RISCV_32: {
1354 auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
1356 break;
1357 }
1358 case ELF::R_RISCV_64: {
1359 auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
1361 break;
1362 }
1363 case ELF::R_RISCV_ADD8: {
1364 auto Ref = support::ulittle8_t::ref(Section.getAddressWithOffset(Offset));
1366 break;
1367 }
1368 case ELF::R_RISCV_ADD16: {
1369 auto Ref = support::ulittle16_t::ref(Section.getAddressWithOffset(Offset));
1371 break;
1372 }
1373 case ELF::R_RISCV_ADD32: {
1374 auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
1376 break;
1377 }
1378 case ELF::R_RISCV_ADD64: {
1379 auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
1381 break;
1382 }
1383 case ELF::R_RISCV_SUB8: {
1384 auto Ref = support::ulittle8_t::ref(Section.getAddressWithOffset(Offset));
1386 break;
1387 }
1388 case ELF::R_RISCV_SUB16: {
1389 auto Ref = support::ulittle16_t::ref(Section.getAddressWithOffset(Offset));
1391 break;
1392 }
1393 case ELF::R_RISCV_SUB32: {
1394 auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
1396 break;
1397 }
1398 case ELF::R_RISCV_SUB64: {
1399 auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
1401 break;
1402 }
1403 case ELF::R_RISCV_SET8: {
1404 auto Ref = support::ulittle8_t::ref(Section.getAddressWithOffset(Offset));
1406 break;
1407 }
1408 case ELF::R_RISCV_SET16: {
1409 auto Ref = support::ulittle16_t::ref(Section.getAddressWithOffset(Offset));
1411 break;
1412 }
1413 case ELF::R_RISCV_SET32: {
1414 auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
1416 break;
1417 }
1418 }
1419}
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1447
1448void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
1451 uint64_t SymOffset, SID SectionID) {
1452 switch (Arch) {
1454 resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
1455 break;
1458 (uint32_t)(Addend & 0xffffffffL));
1459 break;
1462 resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
1463 break;
1469 (uint32_t)(Addend & 0xffffffffL));
1470 break;
1472 resolveLoongArch64Relocation(Section, Offset, Value, Type, Addend);
1473 break;
1476 resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
1477 break;
1480 resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
1481 break;
1483 resolveSystemZRelocation(Section, Offset, Value, Type, Addend);
1484 break;
1487 resolveBPFRelocation(Section, Offset, Value, Type, Addend);
1488 break;
1491 resolveRISCVRelocation(Section, Offset, Value, Type, Addend, SectionID);
1492 break;
1493 default:
1495 }
1496}
1497
1498void *RuntimeDyldELF::computePlaceholderAddress(unsigned SectionID,
1499 uint64_t Offset) const {
1500 return (void *)(Sections[SectionID].getObjAddress() + Offset);
1501}
1502
1503void RuntimeDyldELF::processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value) {
1504 RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);
1505 if (Value.SymbolName)
1507 else
1509}
1510
1511uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,
1512 bool IsLocal) const {
1513 switch (RelType) {
1514 case ELF::R_MICROMIPS_GOT16:
1515 if (IsLocal)
1516 return ELF::R_MICROMIPS_LO16;
1517 break;
1518 case ELF::R_MICROMIPS_HI16:
1519 return ELF::R_MICROMIPS_LO16;
1520 case ELF::R_MIPS_GOT16:
1521 if (IsLocal)
1522 return ELF::R_MIPS_LO16;
1523 break;
1524 case ELF::R_MIPS_HI16:
1525 return ELF::R_MIPS_LO16;
1526 case ELF::R_MIPS_PCHI16:
1527 return ELF::R_MIPS_PCLO16;
1528 default:
1529 break;
1530 }
1531 return ELF::R_MIPS_NONE;
1532}
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543bool RuntimeDyldELF::resolveAArch64ShortBranch(
1546 uint64_t TargetOffset;
1547 unsigned TargetSectionID;
1548 if (Value.SymbolName) {
1550
1551
1553 return false;
1554
1555 const auto &SymInfo = Loc->second;
1556
1557 TargetSectionID = SymInfo.getSectionID();
1558 TargetOffset = SymInfo.getOffset();
1559 } else {
1560 TargetSectionID = Value.SectionID;
1561 TargetOffset = 0;
1562 }
1563
1564
1565
1566 if (TargetSectionID != SectionID)
1567 return false;
1568
1569 uint64_t SourceOffset = RelI->getOffset();
1570
1571
1572
1573
1574 if ((TargetOffset + Value.Addend - SourceOffset))
1575 return false;
1576
1577 RelocationEntry RE(SectionID, SourceOffset, RelI->getType(), Value.Addend);
1578 if (Value.SymbolName)
1580 else
1582
1583 return true;
1584}
1585
1586void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
1589 StubMap &Stubs) {
1590
1591 LLVM_DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
1593
1595 unsigned RelType = RelI->getType();
1596
1597 StubMap::const_iterator i = Stubs.find(Value);
1598 if (i != Stubs.end()) {
1599 resolveRelocation(Section, Offset,
1600 Section.getLoadAddressWithOffset(i->second), RelType, 0);
1602 } else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) {
1603
1604 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
1607 Section.getAddressWithOffset(Section.getStubOffset()));
1608
1609 RelocationEntry REmovz_g3(SectionID, StubTargetAddr - Section.getAddress(),
1610 ELF::R_AARCH64_MOVW_UABS_G3, Value.Addend);
1611 RelocationEntry REmovk_g2(SectionID,
1612 StubTargetAddr - Section.getAddress() + 4,
1613 ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.Addend);
1614 RelocationEntry REmovk_g1(SectionID,
1615 StubTargetAddr - Section.getAddress() + 8,
1616 ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.Addend);
1617 RelocationEntry REmovk_g0(SectionID,
1618 StubTargetAddr - Section.getAddress() + 12,
1619 ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.Addend);
1620
1621 if (Value.SymbolName) {
1626 } else {
1631 }
1632 resolveRelocation(Section, Offset,
1633 Section.getLoadAddressWithOffset(Section.getStubOffset()),
1634 RelType, 0);
1636 }
1637}
1638
1645 int64_t Addend = 0;
1647 Addend = *AddendOrErr;
1648 else
1651
1652
1654 if (Symbol != Obj.symbol_end()) {
1655 if (auto TargetNameOrErr = Symbol->getName())
1656 TargetName = *TargetNameOrErr;
1657 else
1658 return TargetNameOrErr.takeError();
1659 }
1660 LLVM_DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
1661 << " TargetName: " << TargetName << "\n");
1663
1665
1666
1668 if (Symbol != Obj.symbol_end()) {
1671 if (!SymTypeOrErr) {
1672 std::string Buf;
1676 }
1677 SymType = *SymTypeOrErr;
1678 }
1680 const auto &SymInfo = gsi->second;
1683 Value.Addend = SymInfo.getOffset() + Addend;
1684 } else {
1685 switch (SymType) {
1687
1688
1689
1690 auto SectionOrErr = Symbol->getSection();
1691 if (!SectionOrErr) {
1692 std::string Buf;
1696 }
1698 if (si == Obj.section_end())
1699 llvm_unreachable("Symbol section not found, bad object file format!");
1700 LLVM_DEBUG(dbgs() << "\t\tThis is section symbol\n");
1701 bool isCode = si->isText();
1703 ObjSectionToID))
1704 Value.SectionID = *SectionIDOrErr;
1705 else
1706 return SectionIDOrErr.takeError();
1707 Value.Addend = Addend;
1708 break;
1709 }
1714 Value.SymbolName = TargetName.data();
1715 Value.Addend = Addend;
1716
1717
1718
1719
1720
1721 if (.SymbolName)
1722 Value.SymbolName = "";
1723 break;
1724 }
1725 default:
1727 break;
1728 }
1729 }
1730
1732
1733 LLVM_DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
1734 << "\n");
1736 if ((RelType == ELF::R_AARCH64_CALL26 ||
1737 RelType == ELF::R_AARCH64_JUMP26) &&
1738 MemMgr.allowStubAllocation()) {
1739 resolveAArch64Branch(SectionID, Value, RelI, Stubs);
1740 } else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
1741
1742
1743 uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_AARCH64_ABS64);
1744 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
1745 ELF::R_AARCH64_ADR_PREL_PG_HI21);
1746
1747 } else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
1748 uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_AARCH64_ABS64);
1749 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
1750 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
1751 } else {
1752 processSimpleRelocation(SectionID, Offset, RelType, Value);
1753 }
1755 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1756 RelType == ELF::R_ARM_JUMP24) {
1757
1758 LLVM_DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
1760
1761
1762 auto [It, Inserted] = Stubs.try_emplace(Value);
1763 if (!Inserted) {
1764 resolveRelocation(Section, Offset,
1765 Section.getLoadAddressWithOffset(It->second), RelType,
1766 0);
1768 } else {
1769
1770 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
1771 It->second = Section.getStubOffset();
1773 Section.getAddressWithOffset(Section.getStubOffset()));
1774 RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
1775 ELF::R_ARM_ABS32, Value.Addend);
1776 if (Value.SymbolName)
1778 else
1780
1781 resolveRelocation(
1783 Section.getLoadAddressWithOffset(Section.getStubOffset()), RelType,
1784 0);
1786 }
1787 } else {
1789 reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
1790 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1791 RelType == ELF::R_ARM_ABS32) {
1792 Value.Addend += *Placeholder;
1793 } else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1794
1795 Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1796 }
1797 processSimpleRelocation(SectionID, Offset, RelType, Value);
1798 }
1800 if ((RelType == ELF::R_LARCH_B26 || RelType == ELF::R_LARCH_CALL36) &&
1801 MemMgr.allowStubAllocation()) {
1802 resolveLoongArch64Branch(SectionID, Value, RelI, Stubs);
1803 } else if (RelType == ELF::R_LARCH_GOT_PC_HI20 ||
1804 RelType == ELF::R_LARCH_GOT_PC_LO12 ||
1805 RelType == ELF::R_LARCH_GOT64_PC_HI12 ||
1806 RelType == ELF::R_LARCH_GOT64_PC_LO20) {
1807 uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_LARCH_64);
1808 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
1809 RelType);
1810 } else {
1811 processSimpleRelocation(SectionID, Offset, RelType, Value);
1812 }
1815 computePlaceholderAddress(SectionID, Offset));
1817 if (RelType == ELF::R_MIPS_26) {
1818
1819 LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
1821
1822
1823
1824
1825 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1826
1827 Value.Addend += Addend;
1828
1829
1830 auto [It, Inserted] = Stubs.try_emplace(Value);
1831 if (!Inserted) {
1835 } else {
1836
1837 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
1838 It->second = Section.getStubOffset();
1839
1840 unsigned AbiVariant = Obj.getPlatformFlags();
1841
1843 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1844
1845
1846 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1847 ELF::R_MIPS_HI16, Value.Addend);
1849 StubTargetAddr - Section.getAddress() + 4,
1850 ELF::R_MIPS_LO16, Value.Addend);
1851
1852 if (Value.SymbolName) {
1855 } else {
1858 }
1859
1863 }
1864 } else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1865 int64_t Addend = (Opcode & 0x0000ffff) << 16;
1867 PendingRelocs.push_back(std::make_pair(Value, RE));
1868 } else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1870 for (auto I = PendingRelocs.begin(); I != PendingRelocs.end();) {
1873 if (MatchingValue == Value &&
1874 RelType == getMatchingLoRelocation(Reloc.RelType) &&
1875 SectionID == Reloc.SectionID) {
1876 Reloc.Addend += Addend;
1877 if (Value.SymbolName)
1879 else
1881 I = PendingRelocs.erase(I);
1882 } else
1883 ++I;
1884 }
1886 if (Value.SymbolName)
1888 else
1890 } else {
1891 if (RelType == ELF::R_MIPS_32)
1892 Value.Addend += Opcode;
1893 else if (RelType == ELF::R_MIPS_PC16)
1895 else if (RelType == ELF::R_MIPS_PC19_S2)
1897 else if (RelType == ELF::R_MIPS_PC21_S2)
1899 else if (RelType == ELF::R_MIPS_PC26_S2)
1901 processSimpleRelocation(SectionID, Offset, RelType, Value);
1902 }
1904 uint32_t r_type = RelType & 0xff;
1906 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1907 || r_type == ELF::R_MIPS_GOT_DISP) {
1908 auto [I, Inserted] = GOTSymbolOffsets.try_emplace(TargetName);
1909 if (Inserted)
1910 I->second = allocateGOTEntries(1);
1912 if (Value.SymbolName)
1914 else
1916 } else if (RelType == ELF::R_MIPS_26) {
1917
1918 LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
1920
1921
1922 StubMap::const_iterator i = Stubs.find(Value);
1923 if (i != Stubs.end()) {
1927 } else {
1928
1929 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
1930 Stubs[Value] = Section.getStubOffset();
1931
1932 unsigned AbiVariant = Obj.getPlatformFlags();
1933
1935 Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
1936
1938
1939 RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1940 ELF::R_MIPS_HI16, Value.Addend);
1942 StubTargetAddr - Section.getAddress() + 4,
1943 ELF::R_MIPS_LO16, Value.Addend);
1944 if (Value.SymbolName) {
1947 } else {
1950 }
1951 } else {
1952
1953
1955 StubTargetAddr - Section.getAddress(),
1956 ELF::R_MIPS_HIGHEST, Value.Addend);
1958 StubTargetAddr - Section.getAddress() + 4,
1959 ELF::R_MIPS_HIGHER, Value.Addend);
1961 StubTargetAddr - Section.getAddress() + 12,
1962 ELF::R_MIPS_HI16, Value.Addend);
1964 StubTargetAddr - Section.getAddress() + 20,
1965 ELF::R_MIPS_LO16, Value.Addend);
1966 if (Value.SymbolName) {
1971 } else {
1976 }
1977 }
1981 }
1982 } else {
1983 processSimpleRelocation(SectionID, Offset, RelType, Value);
1984 }
1985
1987 if (RelType == ELF::R_PPC64_REL24) {
1988
1989 unsigned AbiVariant = Obj.getPlatformFlags();
1991
1992
1993
1994
1997 bool RangeOverflow = false;
1999 if (!IsExtern) {
2000 if (AbiVariant != 2) {
2001
2002
2003
2004 if (auto Err = findOPDEntrySection(Obj, ObjSectionToID, Value))
2005 return std::move(Err);
2006 } else {
2007
2008
2009 if (Value.SectionID == SectionID){
2010 uint8_t SymOther = Symbol->getOther();
2012 }
2013 }
2016 int64_t delta = static_cast<int64_t>(Target - RelocTarget);
2017
2019 RangeOverflow = true;
2020 } else if ((AbiVariant != 2) ||
2021 (AbiVariant == 2 && Value.SectionID == SectionID)) {
2024 }
2025 }
2026 if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID) ||
2027 RangeOverflow) {
2028
2029
2030 auto [It, Inserted] = Stubs.try_emplace(Value);
2031 if (!Inserted) {
2032
2033 resolveRelocation(Section, Offset,
2034 Section.getLoadAddressWithOffset(It->second),
2035 RelType, 0);
2037 } else {
2038
2039 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
2040 It->second = Section.getStubOffset();
2042 Section.getAddressWithOffset(Section.getStubOffset()),
2043 AbiVariant);
2044 RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
2045 ELF::R_PPC64_ADDR64, Value.Addend);
2046
2047
2048
2049
2050
2051 uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
2053 StubRelocOffset += 2;
2054
2056 ELF::R_PPC64_ADDR16_HIGHEST, Value.Addend);
2058 ELF::R_PPC64_ADDR16_HIGHER, Value.Addend);
2060 ELF::R_PPC64_ADDR16_HI, Value.Addend);
2062 ELF::R_PPC64_ADDR16_LO, Value.Addend);
2063
2064 if (Value.SymbolName) {
2069 } else {
2074 }
2075
2076 resolveRelocation(
2078 Section.getLoadAddressWithOffset(Section.getStubOffset()),
2079 RelType, 0);
2081 }
2082 if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID)) {
2083
2084 if (AbiVariant == 2)
2086 else
2088 }
2089 }
2090 } else if (RelType == ELF::R_PPC64_TOC16 ||
2091 RelType == ELF::R_PPC64_TOC16_DS ||
2092 RelType == ELF::R_PPC64_TOC16_LO ||
2093 RelType == ELF::R_PPC64_TOC16_LO_DS ||
2094 RelType == ELF::R_PPC64_TOC16_HI ||
2095 RelType == ELF::R_PPC64_TOC16_HA) {
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106 switch (RelType) {
2107 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16; break;
2108 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS; break;
2109 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO; break;
2110 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS; break;
2111 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI; break;
2112 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA; break;
2114 }
2115
2117 if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
2118 return std::move(Err);
2122 resolveRelocation(Sections[SectionID], Offset, Value.Addend, RelType, 0);
2123 } else {
2124
2125
2126
2127
2128 if (RelType == ELF::R_PPC64_TOC) {
2129 RelType = ELF::R_PPC64_ADDR64;
2130 if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
2131 return std::move(Err);
2132 } else if (TargetName == ".TOC.") {
2133 if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
2134 return std::move(Err);
2135 Value.Addend += Addend;
2136 }
2137
2139
2140 if (Value.SymbolName)
2142 else
2144 }
2146 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 LLVM_DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
2158
2159
2160 StubMap::const_iterator i = Stubs.find(Value);
2161 uintptr_t StubAddress;
2162 if (i != Stubs.end()) {
2163 StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
2165 } else {
2166
2167 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
2168
2169 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
2170 StubAddress =
2171 alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
2172 unsigned StubOffset = StubAddress - BaseAddress;
2173
2174 Stubs[Value] = StubOffset;
2176 RelocationEntry RE(SectionID, StubOffset + 8, ELF::R_390_64,
2178 if (Value.SymbolName)
2180 else
2183 }
2184
2185 if (RelType == ELF::R_390_GOTENT)
2186 resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL,
2187 Addend);
2188 else
2189 resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
2191 if (RelType == ELF::R_X86_64_PLT32) {
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208 if (Value.SymbolName && MemMgr.allowStubAllocation()) {
2209
2210
2212 auto [It, Inserted] = Stubs.try_emplace(Value);
2213 uintptr_t StubAddress;
2214 if (!Inserted) {
2215 StubAddress = uintptr_t(Section->getAddress()) + It->second;
2217 } else {
2218
2219 LLVM_DEBUG(dbgs() << " Create a new stub function\n");
2220
2221 uintptr_t BaseAddress = uintptr_t(Section->getAddress());
2222 StubAddress = alignTo(BaseAddress + Section->getStubOffset(),
2223 getStubAlignment());
2224 unsigned StubOffset = StubAddress - BaseAddress;
2225 It->second = StubOffset;
2227
2228
2230
2231
2232 uint64_t GOTOffset = allocateGOTEntries(1);
2233
2234
2235 Section = &Sections[SectionID];
2236
2237
2238 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
2239 ELF::R_X86_64_PC32);
2240
2241
2243 computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
2244 Value.SymbolName);
2245 }
2246
2247
2248 resolveRelocation(*Section, Offset, StubAddress, ELF::R_X86_64_PC32,
2249 Addend);
2250 } else {
2251 Value.Addend += support::ulittle32_t::ref(
2252 computePlaceholderAddress(SectionID, Offset));
2253 processSimpleRelocation(SectionID, Offset, ELF::R_X86_64_PC32, Value);
2254 }
2255 } else if (RelType == ELF::R_X86_64_GOTPCREL ||
2256 RelType == ELF::R_X86_64_GOTPCRELX ||
2257 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
2258 uint64_t GOTOffset = allocateGOTEntries(1);
2259 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
2260 ELF::R_X86_64_PC32);
2261
2262
2264 computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
2265 if (Value.SymbolName)
2267 else
2269 } else if (RelType == ELF::R_X86_64_GOT64) {
2270
2271 uint64_t GOTOffset = allocateGOTEntries(1);
2272 resolveRelocation(Sections[SectionID], Offset, GOTOffset,
2273 ELF::R_X86_64_64, 0);
2274
2275
2277 computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
2278 if (Value.SymbolName)
2280 else
2282 } else if (RelType == ELF::R_X86_64_GOTPC32) {
2283
2284
2285
2286 (void)allocateGOTEntries(0);
2287 resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC32);
2288 } else if (RelType == ELF::R_X86_64_GOTPC64) {
2289 (void)allocateGOTEntries(0);
2290 resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC64);
2291 } else if (RelType == ELF::R_X86_64_GOTOFF64) {
2292
2293 (void)allocateGOTEntries(0);
2294 processSimpleRelocation(SectionID, Offset, RelType, Value);
2295 } else if (RelType == ELF::R_X86_64_PC32) {
2296 Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
2297 processSimpleRelocation(SectionID, Offset, RelType, Value);
2298 } else if (RelType == ELF::R_X86_64_PC64) {
2299 Value.Addend += support::ulittle64_t::ref(
2300 computePlaceholderAddress(SectionID, Offset));
2301 processSimpleRelocation(SectionID, Offset, RelType, Value);
2302 } else if (RelType == ELF::R_X86_64_GOTTPOFF) {
2303 processX86_64GOTTPOFFRelocation(SectionID, Offset, Value, Addend);
2304 } else if (RelType == ELF::R_X86_64_TLSGD ||
2305 RelType == ELF::R_X86_64_TLSLD) {
2306
2307 ++RelI;
2308 auto &GetAddrRelocation = *RelI;
2309 processX86_64TLSRelocation(SectionID, Offset, RelType, Value, Addend,
2310 GetAddrRelocation);
2311 } else {
2312 processSimpleRelocation(SectionID, Offset, RelType, Value);
2313 }
2315
2316
2317
2318 if (RelType == ELF::R_RISCV_GOT_HI20 ||
2319 RelType == ELF::R_RISCV_PCREL_HI20 ||
2320 RelType == ELF::R_RISCV_TPREL_HI20 ||
2321 RelType == ELF::R_RISCV_TLS_GD_HI20 ||
2322 RelType == ELF::R_RISCV_TLS_GOT_HI20) {
2324 PendingRelocs.push_back({Value, RE});
2325 }
2326 processSimpleRelocation(SectionID, Offset, RelType, Value);
2327 } else {
2329 Value.Addend += support::ulittle32_t::ref(
2330 computePlaceholderAddress(SectionID, Offset));
2331 }
2332 processSimpleRelocation(SectionID, Offset, RelType, Value);
2333 }
2334 return ++RelI;
2335}
2336
2337void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(unsigned SectionID,
2340 int64_t Addend) {
2341
2342
2343
2344
2345
2346
2347
2348 struct CodeSequence {
2349
2351
2352
2354
2356
2357 uint64_t TpoffRelocationOffset;
2358 };
2359
2360 std::array<CodeSequence, 2> CodeSequences;
2361
2362
2363 {
2364 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2365 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2366 0x00,
2367 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00
2368
2369 };
2370 CodeSequences[0].ExpectedCodeSequence =
2371 ArrayRef<uint8_t>(ExpectedCodeSequenceList);
2372 CodeSequences[0].TLSSequenceOffset = 12;
2373
2374 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2375 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2376 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2377 };
2378 CodeSequences[0].NewCodeSequence = ArrayRef<uint8_t>(NewCodeSequenceList);
2379 CodeSequences[0].TpoffRelocationOffset = 12;
2380 }
2381
2382
2383 {
2384 static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
2385 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
2386 0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00
2387 };
2388 CodeSequences[1].ExpectedCodeSequence =
2389 ArrayRef<uint8_t>(ExpectedCodeSequenceList);
2390 CodeSequences[1].TLSSequenceOffset = 3;
2391
2392 static const std::initializer_list<uint8_t> NewCodeSequenceList = {
2393 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
2394 0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
2395 };
2396 CodeSequences[1].NewCodeSequence = ArrayRef<uint8_t>(NewCodeSequenceList);
2397 CodeSequences[1].TpoffRelocationOffset = 10;
2398 }
2399
2402 for (const auto &C : CodeSequences) {
2403 assert(C.ExpectedCodeSequence.size() == C.NewCodeSequence.size() &&
2404 "Old and new code sequences must have the same size");
2405
2406 if (Offset < C.TLSSequenceOffset ||
2407 (Offset - C.TLSSequenceOffset + C.NewCodeSequence.size()) >
2409
2410
2411 continue;
2412 }
2413
2414 auto TLSSequenceStartOffset = Offset - C.TLSSequenceOffset;
2415 auto *TLSSequence = Section.getAddressWithOffset(TLSSequenceStartOffset);
2416 if (ArrayRef<uint8_t>(TLSSequence, C.ExpectedCodeSequence.size()) !=
2417 C.ExpectedCodeSequence) {
2418 continue;
2419 }
2420
2421 memcpy(TLSSequence, C.NewCodeSequence.data(), C.NewCodeSequence.size());
2422
2423
2424
2425
2426
2427 RelocationEntry RE(SectionID,
2428 TLSSequenceStartOffset + C.TpoffRelocationOffset,
2429 ELF::R_X86_64_TPOFF32, Value.Addend - Addend);
2430
2431 if (Value.SymbolName)
2433 else
2435
2437 break;
2438 }
2439
2440 if (!Resolved) {
2441
2442
2443
2444 uint64_t GOTOffset = allocateGOTEntries(1);
2445 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
2446 ELF::R_X86_64_PC32);
2447 RelocationEntry RE =
2448 computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_TPOFF64);
2449 if (Value.SymbolName)
2451 else
2453 }
2454}
2455
2456void RuntimeDyldELF::processX86_64TLSRelocation(
2457 unsigned SectionID, uint64_t Offset, uint64_t RelType,
2459 const RelocationRef &GetAddrRelocation) {
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469 bool IsSmallCodeModel;
2470
2471 bool IsGOTPCRel = false;
2472
2473 switch (GetAddrRelocation.getType()) {
2474 case ELF::R_X86_64_GOTPCREL:
2475 case ELF::R_X86_64_REX_GOTPCRELX:
2476 case ELF::R_X86_64_GOTPCRELX:
2477 IsGOTPCRel = true;
2478 [[fallthrough]];
2479 case ELF::R_X86_64_PLT32:
2480 IsSmallCodeModel = true;
2481 break;
2482 case ELF::R_X86_64_PLTOFF64:
2483 IsSmallCodeModel = false;
2484 break;
2485 default:
2487 "invalid TLS relocations for General/Local Dynamic TLS Model: "
2488 "expected PLT or GOT relocation for __tls_get_addr function");
2489 }
2490
2491
2492
2493 uint64_t TLSSequenceOffset;
2494
2495 ArrayRef<uint8_t> ExpectedCodeSequence;
2496
2497 ArrayRef<uint8_t> NewCodeSequence;
2498
2499 if (RelType == ELF::R_X86_64_TLSGD) {
2500
2501
2502 uint64_t TpoffRelocOffset;
2503
2504 if (IsSmallCodeModel) {
2505 if (!IsGOTPCRel) {
2506 static const std::initializer_list<uint8_t> CodeSequence = {
2507 0x66,
2508 0x48, 0x8d, 0x3d, 0x00, 0x00,
2509 0x00, 0x00,
2510 0x66, 0x66,
2511 0x48,
2512 0xe8, 0x00, 0x00, 0x00, 0x00
2513 };
2514 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2515 TLSSequenceOffset = 4;
2516 } else {
2517
2518
2519 static const std::initializer_list<uint8_t> CodeSequence = {
2520 0x66,
2521 0x48, 0x8d, 0x3d, 0x00, 0x00,
2522 0x00, 0x00,
2523 0x66,
2524 0x48,
2525 0xff, 0x15, 0x00, 0x00, 0x00,
2526 0x00
2527 };
2528 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2529 TLSSequenceOffset = 4;
2530 }
2531
2532
2533
2534 static const std::initializer_list<uint8_t> SmallSequence = {
2535 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2536 0x00,
2537 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00
2538
2539 };
2540 NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
2541 TpoffRelocOffset = 12;
2542 } else {
2543 static const std::initializer_list<uint8_t> CodeSequence = {
2544 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2545
2546 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2547 0x00,
2548 0x48, 0x01, 0xd8,
2549 0xff, 0xd0
2550 };
2551 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2552 TLSSequenceOffset = 3;
2553
2554
2555 static const std::initializer_list<uint8_t> LargeSequence = {
2556 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
2557 0x00,
2558 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00,
2559
2560 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
2561 };
2562 NewCodeSequence = ArrayRef<uint8_t>(LargeSequence);
2563 TpoffRelocOffset = 12;
2564 }
2565
2566
2567
2568
2569 RelocationEntry RE(SectionID, Offset - TLSSequenceOffset + TpoffRelocOffset,
2570 ELF::R_X86_64_TPOFF32, Value.Addend - Addend);
2571 if (Value.SymbolName)
2573 else
2575 } else if (RelType == ELF::R_X86_64_TLSLD) {
2576 if (IsSmallCodeModel) {
2577 if (!IsGOTPCRel) {
2578 static const std::initializer_list<uint8_t> CodeSequence = {
2579 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00,
2580 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00
2581 };
2582 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2583 TLSSequenceOffset = 3;
2584
2585
2586 static const std::initializer_list<uint8_t> SmallSequence = {
2587 0x66, 0x66, 0x66,
2588 0x64, 0x48, 0x8b, 0x04, 0x25,
2589 0x00, 0x00, 0x00, 0x00
2590 };
2591 NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
2592 } else {
2593
2594
2595 static const std::initializer_list<uint8_t> CodeSequence = {
2596 0x48, 0x8d, 0x3d, 0x00,
2597 0x00, 0x00, 0x00,
2598 0xff, 0x15, 0x00, 0x00,
2599 0x00, 0x00
2600
2601 };
2602 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2603 TLSSequenceOffset = 3;
2604
2605
2606
2607 static const std::initializer_list<uint8_t> SmallSequence = {
2608 0x0f, 0x1f, 0x40, 0x00,
2609 0x64, 0x48, 0x8b, 0x04, 0x25,
2610 0x00, 0x00, 0x00, 0x00
2611 };
2612 NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
2613 }
2614 } else {
2615
2616
2617 static const std::initializer_list<uint8_t> CodeSequence = {
2618 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00,
2619
2620 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2621 0x48,
2622 0x01, 0xd8,
2623 0xff, 0xd0
2624 };
2625 ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
2626 TLSSequenceOffset = 3;
2627
2628
2629 static const std::initializer_list<uint8_t> LargeSequence = {
2630 0x66, 0x66, 0x66,
2631 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
2632 0x00,
2633 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
2634 };
2635 NewCodeSequence = ArrayRef<uint8_t>(LargeSequence);
2636 }
2637 } else {
2639 }
2640
2641 assert(ExpectedCodeSequence.size() == NewCodeSequence.size() &&
2642 "Old and new code sequences must have the same size");
2643
2645 if (Offset < TLSSequenceOffset ||
2646 (Offset - TLSSequenceOffset + NewCodeSequence.size()) >
2649 }
2650
2651 auto *TLSSequence = Section.getAddressWithOffset(Offset - TLSSequenceOffset);
2652 if (ArrayRef<uint8_t>(TLSSequence, ExpectedCodeSequence.size()) !=
2653 ExpectedCodeSequence) {
2655 "invalid TLS sequence for Global/Local Dynamic TLS Model");
2656 }
2657
2658 memcpy(TLSSequence, NewCodeSequence.data(), NewCodeSequence.size());
2659}
2660
2662
2663
2664 size_t Result = 0;
2665 switch (Arch) {
2674 break;
2679 break;
2688 else
2690 break;
2691 default:
2693 }
2694 return Result;
2695}
2696
2697uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned no) {
2698 if (GOTSectionID == 0) {
2699 GOTSectionID = Sections.size();
2700
2701
2703 }
2705 CurrentGOTIndex += no;
2706 return StartOffset;
2707}
2708
2710 unsigned GOTRelType) {
2711 auto E = GOTOffsetMap.insert({Value, 0});
2712 if (E.second) {
2713 uint64_t GOTOffset = allocateGOTEntries(1);
2714
2715
2716 RelocationEntry RE =
2717 computeGOTOffsetRE(GOTOffset, Value.Offset, GOTRelType);
2718 if (Value.SymbolName)
2720 else
2722
2723 E.first->second = GOTOffset;
2724 }
2725
2726 return E.first->second;
2727}
2728
2729void RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID,
2731 uint64_t GOTOffset,
2732 uint32_t Type) {
2733
2734 RelocationEntry GOTRE(SectionID, Offset, Type, GOTOffset);
2736}
2737
2738RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(uint64_t GOTOffset,
2739 uint64_t SymbolOffset,
2740 uint32_t Type) {
2741 return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);
2742}
2743
2744void RuntimeDyldELF::processNewSymbol(const SymbolRef &ObjSymbol, SymbolTableEntry& Symbol) {
2745
2746
2748
2749 if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
2750 if (IFuncStubSectionID == 0) {
2751
2752
2753 IFuncStubSectionID = Sections.size();
2755 SectionEntry(".text.__llvm_IFuncStubs", nullptr, 0, 0, 0));
2756
2757 IFuncStubOffset = 64;
2758 }
2759
2760 IFuncStubs.push_back(IFuncStub{IFuncStubOffset, Symbol});
2761
2762
2763 Symbol = SymbolTableEntry(IFuncStubSectionID, IFuncStubOffset,
2765 IFuncStubOffset += getMaxIFuncStubSize();
2766 }
2767}
2768
2772 if (!PendingRelocs.empty())
2774
2775
2776
2777 if (IFuncStubSectionID != 0) {
2778 uint8_t *IFuncStubsAddr = MemMgr.allocateCodeSection(
2779 IFuncStubOffset, 1, IFuncStubSectionID, ".text.__llvm_IFuncStubs");
2780 if (!IFuncStubsAddr)
2782 "Unable to allocate memory for IFunc stubs!");
2783 Sections[IFuncStubSectionID] =
2784 SectionEntry(".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
2785 IFuncStubOffset, 0);
2786
2787 createIFuncResolver(IFuncStubsAddr);
2788
2789 LLVM_DEBUG(dbgs() << "Creating IFunc stubs SectionID: "
2790 << IFuncStubSectionID << " Addr: "
2791 << Sections[IFuncStubSectionID].getAddress() << '\n');
2792 for (auto &IFuncStub : IFuncStubs) {
2793 auto &Symbol = IFuncStub.OriginalSymbol;
2794 LLVM_DEBUG(dbgs() << "\tSectionID: " << Symbol.getSectionID()
2795 << " Offset: " << format("%p", Symbol.getOffset())
2796 << " IFuncStubOffset: "
2797 << format("%p\n", IFuncStub.StubOffset));
2798 createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
2799 Symbol.getSectionID(), Symbol.getOffset());
2800 }
2801
2802 IFuncStubSectionID = 0;
2803 IFuncStubOffset = 0;
2804 IFuncStubs.clear();
2805 }
2806
2807
2808 if (GOTSectionID != 0) {
2809
2812 GOTSectionID, ".got", false);
2813 if (!Addr)
2815
2817 SectionEntry(".got", Addr, TotalSize, TotalSize, 0);
2818
2819
2820
2821 memset(Addr, 0, TotalSize);
2823
2824
2825 for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
2827 if (->relocations().empty()) {
2829 if (!RelSecOrErr)
2832
2834 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
2835 assert(i != SectionMap.end());
2837 }
2838 }
2839 GOTSymbolOffsets.clear();
2840 }
2841 }
2842
2843
2844 ObjSectionToIDMap::iterator i, e;
2845 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
2846 const SectionRef &Section = i->first;
2847
2850 if (NameOrErr)
2851 Name = *NameOrErr;
2852 else
2854
2855 if (Name == ".eh_frame") {
2856 UnregisteredEHFrameSections.push_back(i->second);
2857 break;
2858 }
2859 }
2860
2861 GOTOffsetMap.clear();
2862 GOTSectionID = 0;
2863 CurrentGOTIndex = 0;
2864
2866}
2867
2869 return Obj.isELF();
2870}
2871
2872void RuntimeDyldELF::createIFuncResolver(uint8_t *Addr) const {
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884 const uint8_t StubCode[] = {
2885 0x57,
2886 0x56,
2887 0x52,
2888 0x51,
2889 0x41, 0x50,
2890 0x41, 0x51,
2891 0x41, 0x53,
2892 0x41, 0xff, 0x53, 0x08,
2893 0x41, 0x5b,
2894 0x41, 0x59,
2895 0x41, 0x58,
2896 0x59,
2897 0x5a,
2898 0x5e,
2899 0x5f,
2900 0x49, 0x89, 0x03,
2901 0xff, 0xe0
2902 };
2903
2904 static_assert(sizeof(StubCode) <= 64,
2905 "maximum size of the IFunc resolver is 64B");
2906 memcpy(Addr, StubCode, sizeof(StubCode));
2907 } else {
2909 "IFunc resolver is not supported for target architecture");
2910 }
2911}
2912
2913void RuntimeDyldELF::createIFuncStub(unsigned IFuncStubSectionID,
2914 uint64_t IFuncResolverOffset,
2915 uint64_t IFuncStubOffset,
2916 unsigned IFuncSectionID,
2917 uint64_t IFuncOffset) {
2918 auto &IFuncStubSection = Sections[IFuncStubSectionID];
2919 auto *Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);
2920
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943 uint64_t GOT1 = allocateGOTEntries(2);
2945
2946 RelocationEntry RE1(GOTSectionID, GOT1, ELF::R_X86_64_64,
2947 IFuncResolverOffset, {});
2949 RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
2951
2952 const uint8_t StubCode[] = {
2953 0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00,
2954 0x41, 0xff, 0x23
2955 };
2956 assert(sizeof(StubCode) <= getMaxIFuncStubSize() &&
2957 "IFunc stub size must not exceed getMaxIFuncStubSize()");
2958 memcpy(Addr, StubCode, sizeof(StubCode));
2959
2960
2961
2962 resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
2963 GOT1 - 4, ELF::R_X86_64_PC32);
2964 } else {
2965 report_fatal_error("IFunc stub is not supported for target architecture");
2966 }
2967}
2968
2969unsigned RuntimeDyldELF::getMaxIFuncStubSize() const {
2971 return 10;
2972 }
2973 return 0;
2974}
2975
2976bool RuntimeDyldELF::relocationNeedsGot(const RelocationRef &R) const {
2977 unsigned RelTy = R.getType();
2979 return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
2980 RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;
2981
2983 return RelTy == ELF::R_LARCH_GOT_PC_HI20 ||
2984 RelTy == ELF::R_LARCH_GOT_PC_LO12 ||
2985 RelTy == ELF::R_LARCH_GOT64_PC_HI12 ||
2986 RelTy == ELF::R_LARCH_GOT64_PC_LO20;
2987
2989 return RelTy == ELF::R_X86_64_GOTPCREL ||
2990 RelTy == ELF::R_X86_64_GOTPCRELX ||
2991 RelTy == ELF::R_X86_64_GOT64 ||
2992 RelTy == ELF::R_X86_64_REX_GOTPCRELX;
2993 return false;
2994}
2995
2996bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
2998 return true;
2999
3000 switch (R.getType()) {
3001 default:
3002 return true;
3003
3004
3005 case ELF::R_X86_64_GOTPCREL:
3006 case ELF::R_X86_64_GOTPCRELX:
3007 case ELF::R_X86_64_REX_GOTPCRELX:
3008 case ELF::R_X86_64_GOTPC64:
3009 case ELF::R_X86_64_GOT64:
3010 case ELF::R_X86_64_GOTOFF64:
3011 case ELF::R_X86_64_PC32:
3012 case ELF::R_X86_64_PC64:
3013 case ELF::R_X86_64_64:
3014
3015
3016 return false;
3017 }
3018}
3019
3020}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
static void or32le(void *P, int32_t V)
Definition RuntimeDyldELF.cpp:30
static void or32AArch64Imm(void *L, uint64_t Imm)
Definition RuntimeDyldELF.cpp:32
static uint64_t getBits(uint64_t Val, int Start, int End)
Definition RuntimeDyldELF.cpp:50
static void write32AArch64Addr(void *L, uint64_t Imm)
Definition RuntimeDyldELF.cpp:41
Expected< const Elf_Sym * > getSymbol(DataRefImpl Sym) const
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object, bool InitContent=true)
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.
void registerEHFrames() override
Definition RuntimeDyldELF.cpp:221
size_t getGOTEntrySize() override
Definition RuntimeDyldELF.cpp:2661
~RuntimeDyldELF() override
static std::unique_ptr< RuntimeDyldELF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
Definition RuntimeDyldELF.cpp:232
Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override
Definition RuntimeDyldELF.cpp:2769
DenseMap< SID, SID > SectionToGOTMap
bool isCompatibleFile(const object::ObjectFile &Obj) const override
Definition RuntimeDyldELF.cpp:2868
std::unique_ptr< RuntimeDyld::LoadedObjectInfo > loadObject(const object::ObjectFile &O) override
Definition RuntimeDyldELF.cpp:247
RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
Definition RuntimeDyldELF.cpp:216
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 ...
Definition RuntimeDyldELF.cpp:1640
std::map< SectionRef, unsigned > ObjSectionToIDMap
void writeInt32BE(uint8_t *Addr, uint32_t Value)
RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
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
JITSymbolResolver & Resolver
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
virtual unsigned getMaxStubSize() const =0
RTDyldSymbolTable GlobalSymbolTable
Expected< ObjSectionToIDMap > loadObjectImpl(const object::ObjectFile &Obj)
SectionEntry - represents a section emitted into memory by the dynamic linker.
StringMapIterBase< SymbolTableEntry, true > const_iterator
StringRef - Represent a constant reference to a string, i.e.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Symbol info for RuntimeDyld.
Target - Wrapper for Target specific information.
static LLVM_ABI StringRef getArchTypePrefix(ArchType Kind)
Get the "prefix" canonical name for the Kind architecture.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Expected< uint32_t > getFlags() const
Get symbol flags (bitwise OR of SymbolRef::Flags)
DataRefImpl getRawDataRefImpl() const
Expected< int64_t > getAddend() const
This class is the base class for all object file types.
virtual section_iterator section_begin() const =0
uint64_t getOffset() const
symbol_iterator getSymbol() const
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.
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)
content_iterator< SectionRef > section_iterator
content_iterator< RelocationRef > relocation_iterator
@ Resolved
Queried, materialization begun.
NodeAddr< InstrNode * > Instr
void write32le(void *P, uint32_t V)
uint32_t read32le(const void *P)
detail::packed_endian_specific_integral< int32_t, llvm::endianness::little, unaligned > little32_t
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static uint16_t applyPPChighera(uint64_t value)
Definition RuntimeDyldELF.cpp:1056
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
static uint16_t applyPPChi(uint64_t value)
Definition RuntimeDyldELF.cpp:1044
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)
Definition RuntimeDyldELF.cpp:1273
static uint16_t applyPPChighesta(uint64_t value)
Definition RuntimeDyldELF.cpp:1064
static uint16_t applyPPChighest(uint64_t value)
Definition RuntimeDyldELF.cpp:1060
static uint16_t applyPPCha(uint64_t value)
Definition RuntimeDyldELF.cpp:1048
static void applyUTypeImmRISCV(uint8_t *InstrAddr, uint32_t Imm)
Definition RuntimeDyldELF.cpp:1267
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa - 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)
Definition RuntimeDyldELF.cpp:1042
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
@ 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)
Definition RuntimeDyldELF.cpp:1052
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)
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
static uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo)
Definition RuntimeDyldELF.cpp:736
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, uint32_t type)
Definition RuntimeDyldELF.cpp:742
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 ...