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 && Obj.isLittleEndian())

192 DebugObj =

193 createRTDyldELFObject(Buffer->getMemBufferRef(), Obj, L);

194 else if (Obj.getBytesInAddress() == 8 && Obj.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 (isInt<28>(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 (Value.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();

2826 SI != SE; ++SI) {

2827 if (SI->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 ...