LLVM: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23#include

24

25#include

26

27using namespace llvm;

29

30#define DEBUG_TYPE "dyld"

31

32namespace {

33

34enum RuntimeDyldErrorCode {

35 GenericRTDyldError = 1

36};

37

38

39

40

41class RuntimeDyldErrorCategory : public std::error_category {

42public:

43 const char *name() const noexcept override { return "runtimedyld"; }

44

45 std::string message(int Condition) const override {

46 switch (static_cast<RuntimeDyldErrorCode>(Condition)) {

47 case GenericRTDyldError: return "Generic RuntimeDyld error";

48 }

50 }

51};

52

53}

54

56

58 OS << ErrMsg << "\n";

59}

60

62 static RuntimeDyldErrorCategory RTDyldErrorCategory;

63 return std::error_code(GenericRTDyldError, RTDyldErrorCategory);

64}

65

66

68

69

71

72namespace llvm {

73

75

77 MemMgr.deregisterEHFrames();

78}

79

80#ifndef NDEBUG

82 dbgs() << "----- Contents of section " << S.getName() << " " << State

83 << " -----";

84

86 dbgs() << "\n

\n";

87 return;

88 }

89

90 const unsigned ColsPerRow = 16;

91

94

95 unsigned StartPadding = LoadAddr & (ColsPerRow - 1);

96 unsigned BytesRemaining = S.getSize();

97

98 if (StartPadding) {

99 dbgs() << "\n" << format("0x%016" PRIx64,

100 LoadAddr & ~(uint64_t)(ColsPerRow - 1)) << ":";

101 while (StartPadding--)

102 dbgs() << " ";

103 }

104

105 while (BytesRemaining > 0) {

106 if ((LoadAddr & (ColsPerRow - 1)) == 0)

107 dbgs() << "\n" << format("0x%016" PRIx64, LoadAddr) << ":";

108

109 dbgs() << " " << format("%02x", *DataAddr);

110

111 ++DataAddr;

112 ++LoadAddr;

113 --BytesRemaining;

114 }

115

116 dbgs() << "\n";

117}

118#endif

119

120

122 std::lock_guardsys::Mutex locked(lock);

123

124

128 });

129

130

131 if (auto Err = resolveExternalSymbols()) {

132 HasError = true;

133 ErrorStr = toString(std::move(Err));

134 }

135

136 resolveLocalRelocations();

137

138

142 });

143}

144

146

147 for (const auto &Rel : Relocations) {

148

149

150

151 unsigned Idx = Rel.first;

153 LLVM_DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t"

154 << format("%p", (uintptr_t)Addr) << "\n");

155 resolveRelocationList(Rel.second, Addr);

156 }

157 Relocations.clear();

158}

159

162 std::lock_guardsys::Mutex locked(lock);

163 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {

164 if (Sections[i].getAddress() == LocalAddress) {

165 reassignSectionAddress(i, TargetAddress);

166 return;

167 }

168 }

169 llvm_unreachable("Attempting to remap address of unknown section!");

170}

171

175 if (!AddressOrErr)

177 Result = *AddressOrErr - Sec.getAddress();

179}

180

183 std::lock_guardsys::Mutex locked(lock);

184

185

188 setMipsABI(Obj);

189

190

191

192 if (MemMgr.needsToReserveAllocationSpace()) {

193 uint64_t CodeSize = 0, RODataSize = 0, RWDataSize = 0;

194 Align CodeAlign, RODataAlign, RWDataAlign;

195 if (auto Err = computeTotalAllocSize(Obj, CodeSize, CodeAlign, RODataSize,

196 RODataAlign, RWDataSize, RWDataAlign))

197 return std::move(Err);

198 MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,

199 RWDataSize, RWDataAlign);

200 }

201

202

204

205

207

210

211

212

214 {

218 if (!FlagsOrErr)

219

221 if ((*FlagsOrErr & SymbolRef::SF_Common) ||

222 (*FlagsOrErr & SymbolRef::SF_Weak)) {

223

224 if (auto NameOrErr = Sym.getName())

225 Symbols.insert(*NameOrErr);

226 else

227 return NameOrErr.takeError();

228 }

229 }

230

231 if (auto ResultOrErr = Resolver.getResponsibilitySet(Symbols))

232 ResponsibilitySet = std::move(*ResultOrErr);

233 else

234 return ResultOrErr.takeError();

235 }

236

237

240 ++I) {

242 if (!FlagsOrErr)

243

245

246

247 if (*FlagsOrErr & SymbolRef::SF_Undefined)

248 continue;

249

250

252 if (auto SymTypeOrErr = I->getType())

253 SymType = *SymTypeOrErr;

254 else

255 return SymTypeOrErr.takeError();

256

257

259 if (auto NameOrErr = I->getName())

260 Name = *NameOrErr;

261 else

262 return NameOrErr.takeError();

263

264

265 auto JITSymFlags = getJITSymbolFlags(*I);

266 if (!JITSymFlags)

267 return JITSymFlags.takeError();

268

269

270

271

272

273 if (JITSymFlags->isWeak() || JITSymFlags->isCommon()) {

274

275 if (GlobalSymbolTable.count(Name))

276 continue;

277

278

279 if (!ResponsibilitySet.count(Name))

280 continue;

281

282

283

284 if (JITSymFlags->isWeak())

286 if (JITSymFlags->isCommon()) {

290 if (!CommonAlign)

291 CommonAlign = Align;

293 CommonSymbolsToAllocate.push_back(*I);

294 }

295 }

296

297 if (*FlagsOrErr & SymbolRef::SF_Absolute &&

300 if (auto AddrOrErr = I->getAddress())

301 Addr = *AddrOrErr;

302 else

303 return AddrOrErr.takeError();

304

305 unsigned SectionID = AbsoluteSymbolSection;

306

307 LLVM_DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name

308 << " SID: " << SectionID

309 << " Offset: " << format("%p", (uintptr_t)Addr)

310 << " flags: " << *FlagsOrErr << "\n");

311

312 if (Name.empty()) {

313 auto Result = GlobalSymbolTable.insert_or_assign(

315 processNewSymbol(*I, Result.first->getValue());

316 }

321

323 if (auto SIOrErr = I->getSection())

324 SI = *SIOrErr;

325 else

326 return SIOrErr.takeError();

327

329 continue;

330

331

333 if (auto Err = getOffset(*I, *SI, SectOffset))

334 return std::move(Err);

335

336 bool IsCode = SI->isText();

337 unsigned SectionID;

338 if (auto SectionIDOrErr =

339 findOrEmitSection(Obj, *SI, IsCode, LocalSections))

340 SectionID = *SectionIDOrErr;

341 else

342 return SectionIDOrErr.takeError();

343

345 << " SID: " << SectionID

346 << " Offset: " << format("%p", (uintptr_t)SectOffset)

347 << " flags: " << *FlagsOrErr << "\n");

348

349 if (Name.empty()) {

350 auto Result = GlobalSymbolTable.insert_or_assign(

352 processNewSymbol(*I, Result.first->getValue());

353 }

354 }

355 }

356

357

358 if (auto Err = emitCommonSymbols(Obj, CommonSymbolsToAllocate, CommonSize,

359 CommonAlign))

360 return std::move(Err);

361

362

365 SI != SE; ++SI) {

367

369 if (!RelSecOrErr)

371

373 if (RelocatedSection == SE)

374 continue;

375

378

379 if (I == E && !ProcessAllSections)

380 continue;

381

382 bool IsCode = RelocatedSection->isText();

383 unsigned SectionID = 0;

384 if (auto SectionIDOrErr = findOrEmitSection(Obj, *RelocatedSection, IsCode,

385 LocalSections))

386 SectionID = *SectionIDOrErr;

387 else

388 return SectionIDOrErr.takeError();

389

390 LLVM_DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");

391

392 for (; I != E;)

393 if (auto IOrErr = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs))

394 I = *IOrErr;

395 else

396 return IOrErr.takeError();

397

398

399

400 if (NotifyStubEmitted) {

403 for (auto &KV : Stubs) {

404

405 auto &VR = KV.first;

406 uint64_t StubAddr = KV.second;

407

408

409 if (VR.SymbolName) {

410 NotifyStubEmitted(FileName, SectionName, VR.SymbolName, SectionID,

411 StubAddr);

412 continue;

413 }

414

415

416 for (auto &GSTMapEntry : GlobalSymbolTable) {

417 StringRef SymbolName = GSTMapEntry.first();

418 auto &GSTEntry = GSTMapEntry.second;

419 if (GSTEntry.getSectionID() == VR.SectionID &&

420 GSTEntry.getOffset() == VR.Offset) {

421 NotifyStubEmitted(FileName, SectionName, SymbolName, SectionID,

422 StubAddr);

423 break;

424 }

425 }

426 }

427 }

428 }

429

430

431 if (ProcessAllSections) {

432 LLVM_DEBUG(dbgs() << "Process remaining sections:\n");

434 SI != SE; ++SI) {

435

436

437 if (LocalSections.find(*SI) != LocalSections.end())

438 continue;

439

440 bool IsCode = SI->isText();

441 if (auto SectionIDOrErr =

442 findOrEmitSection(Obj, *SI, IsCode, LocalSections))

443 LLVM_DEBUG(dbgs() << "\tSectionID: " << (*SectionIDOrErr) << "\n");

444 else

445 return SectionIDOrErr.takeError();

446 }

447 }

448

449

450 if (auto Err = finalizeLoad(Obj, LocalSections))

451 return std::move(Err);

452

453

454

455

456 return LocalSections;

457}

458

459

460

461

464 Align Alignment) {

466 for (uint64_t SectionSize : SectionSizes)

467 TotalSize += alignTo(SectionSize, Alignment);

468 return TotalSize;

469}

470

472 const ObjectFile *Obj = Section.getObject();

473 if (isaobject::ELFObjectFileBase(Obj))

475 if (auto *COFFObj = dyn_castobject::COFFObjectFile(Obj)) {

476 const coff_section *CoffSection = COFFObj->getCOFFSection(Section);

477

478

479

480

481

482 bool HasContent =

484 bool IsDiscardable =

487 return HasContent && !IsDiscardable;

488 }

489

490 assert(isa(Obj));

491 return true;

492}

493

495 const ObjectFile *Obj = Section.getObject();

496 if (isaobject::ELFObjectFileBase(Obj))

499 if (auto *COFFObj = dyn_castobject::COFFObjectFile(Obj))

500 return ((COFFObj->getCOFFSection(Section)->Characteristics &

504 ==

507

508 assert(isa(Obj));

509 return false;

510}

511

513 const ObjectFile *Obj = Section.getObject();

514 if (isaobject::ELFObjectFileBase(Obj))

516 if (auto *COFFObj = dyn_castobject::COFFObjectFile(Obj))

517 return COFFObj->getCOFFSection(Section)->Characteristics &

519

520 auto *MachO = cast(Obj);

521 unsigned SectionType = MachO->getSectionType(Section);

524}

525

527 const ObjectFile *Obj = Section.getObject();

528 if (isaobject::ELFObjectFileBase(Obj))

530 return false;

531}

532

533

534

538 Align &RWDataAlign) {

539

540 std::vector<uint64_t> CodeSectionSizes;

541 std::vector<uint64_t> ROSectionSizes;

542 std::vector<uint64_t> RWSectionSizes;

543

544

545

547 SI != SE; ++SI) {

549

551

552

553 if (IsRequired) {

554 uint64_t DataSize = Section.getSize();

555 Align Alignment = Section.getAlignment();

556 bool IsCode = Section.isText();

558 bool IsTLS = isTLS(Section);

559

561 if (!NameOrErr)

564

565 uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);

566

568 if (Name == ".eh_frame")

569 PaddingSize += 4;

570 if (StubBufSize != 0)

571 PaddingSize += getStubAlignment().value() - 1;

572

573 uint64_t SectionSize = DataSize + PaddingSize + StubBufSize;

574

575

576

577

578

579

580 if (Name == ".eh_frame")

581 SectionSize += 4;

582

583 if (!SectionSize)

584 SectionSize = 1;

585

586 if (IsCode) {

587 CodeAlign = std::max(CodeAlign, Alignment);

588 CodeSectionSizes.push_back(SectionSize);

589 } else if (IsReadOnly) {

590 RODataAlign = std::max(RODataAlign, Alignment);

591 ROSectionSizes.push_back(SectionSize);

592 } else if (!IsTLS) {

593 RWDataAlign = std::max(RWDataAlign, Alignment);

594 RWSectionSizes.push_back(SectionSize);

595 }

596 }

597 }

598

599

600

601

602 if (unsigned GotSize = computeGOTSize(Obj)) {

603 RWSectionSizes.push_back(GotSize);

604 RWDataAlign = std::max(RWDataAlign, Align(getGOTEntrySize()));

605 }

606

607

609 Align CommonAlign;

611 ++I) {

613 if (!FlagsOrErr)

614

616 if (*FlagsOrErr & SymbolRef::SF_Common) {

617

619 Align Alignment = Align(I->getAlignment());

620

621

622 if (CommonSize == 0)

623 CommonAlign = Alignment;

624 CommonSize = alignTo(CommonSize, Alignment) + Size;

625 }

626 }

627 if (CommonSize != 0) {

628 RWSectionSizes.push_back(CommonSize);

629 RWDataAlign = std::max(RWDataAlign, CommonAlign);

630 }

631

632 if (!CodeSectionSizes.empty()) {

633

634 CodeSectionSizes.push_back(64);

635 }

636

637

638

639

640

641

645

647}

648

649

651 size_t GotEntrySize = getGOTEntrySize();

652 if (!GotEntrySize)

653 return 0;

654

655 size_t GotSize = 0;

657 SI != SE; ++SI) {

658

659 for (const RelocationRef &Reloc : SI->relocations())

660 if (relocationNeedsGot(Reloc))

661 GotSize += GotEntrySize;

662 }

663

664 return GotSize;

665}

666

667

670 if (!MemMgr.allowStubAllocation()) {

671 return 0;

672 }

673

674 unsigned StubSize = getMaxStubSize();

675 if (StubSize == 0) {

676 return 0;

677 }

678

679

680

681 unsigned StubBufSize = 0;

683 SI != SE; ++SI) {

684

686 if (!RelSecOrErr)

688

690 if (!(RelSecI == Section))

691 continue;

692

693 for (const RelocationRef &Reloc : SI->relocations()) {

694 if (relocationNeedsStub(Reloc))

695 StubBufSize += StubSize;

696 if (relocationNeedsDLLImportStub(Reloc))

697 StubBufSize = sizeAfterAddingDLLImportStub(StubBufSize);

698 }

699 }

700

701

702 uint64_t DataSize = Section.getSize();

703 Align Alignment = Section.getAlignment();

704

705

706 Align StubAlignment = getStubAlignment();

708 if (StubAlignment > EndAlignment)

709 StubBufSize += StubAlignment.value() - EndAlignment.value();

710 return StubBufSize;

711}

712

714 unsigned Size) const {

716 if (IsTargetLittleEndian) {

717 Src += Size - 1;

718 while (Size--)

719 Result = (Result << 8) | *Src--;

720 } else

721 while (Size--)

722 Result = (Result << 8) | *Src++;

723

724 return Result;

725}

726

728 unsigned Size) const {

729 if (IsTargetLittleEndian) {

730 while (Size--) {

731 *Dst++ = Value & 0xFF;

733 }

734 } else {

735 Dst += Size - 1;

736 while (Size--) {

737 *Dst-- = Value & 0xFF;

739 }

740 }

741}

742

746}

747

752 if (SymbolsToAllocate.empty())

754

755

756 unsigned SectionID = Sections.size();

757 uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, CommonAlign, SectionID,

758 "", false);

762 Sections.push_back(

763 SectionEntry("", Addr, CommonSize, CommonSize, 0));

764 memset(Addr, 0, CommonSize);

765

766 LLVM_DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID

767 << " new addr: " << format("%p", Addr)

768 << " DataSize: " << CommonSize << "\n");

769

770

771 for (auto &Sym : SymbolsToAllocate) {

775 if (auto NameOrErr = Sym.getName())

776 Name = *NameOrErr;

777 else

778 return NameOrErr.takeError();

779 if (Alignment) {

780

783 Addr += AlignOffset;

784 Offset += AlignOffset;

785 }

786 auto JITSymFlags = getJITSymbolFlags(Sym);

787

788 if (!JITSymFlags)

789 return JITSymFlags.takeError();

790

791 LLVM_DEBUG(dbgs() << "Allocating common symbol " << Name << " address "

793 if (Name.empty())

794 GlobalSymbolTable[Name] =

798 }

799

801}

802

806 bool IsCode) {

808 Align Alignment = Section.getAlignment();

809

810 unsigned PaddingSize = 0;

811 unsigned StubBufSize = 0;

813 bool IsVirtual = Section.isVirtual();

814 bool IsZeroInit = isZeroInit(Section);

816 bool IsTLS = isTLS(Section);

817 uint64_t DataSize = Section.getSize();

818

820 if (!NameOrErr)

823

824 StubBufSize = computeSectionStubBufSize(Obj, Section);

825

826

827

828

829 if (Name == ".eh_frame")

830 PaddingSize = 4;

831

832 uintptr_t Allocate;

833 unsigned SectionID = Sections.size();

836 const char *pData = nullptr;

837

838

839

840 if (!IsVirtual && !IsZeroInit) {

841

842

845 else

846 return E.takeError();

847 pData = data.data();

848 }

849

850

851

852

853 if (StubBufSize != 0) {

854 Alignment = std::max(Alignment, getStubAlignment());

855 PaddingSize += getStubAlignment().value() - 1;

856 }

857

858

859

860 if (IsRequired || ProcessAllSections) {

861 Allocate = DataSize + PaddingSize + StubBufSize;

862 if (!Allocate)

863 Allocate = 1;

864 if (IsTLS) {

865 auto TLSSection = MemMgr.allocateTLSSection(Allocate, Alignment.value(),

866 SectionID, Name);

867 Addr = TLSSection.InitializationImage;

868 LoadAddress = TLSSection.Offset;

869 } else if (IsCode) {

870 Addr = MemMgr.allocateCodeSection(Allocate, Alignment.value(), SectionID,

872 } else {

873 Addr = MemMgr.allocateDataSection(Allocate, Alignment.value(), SectionID,

874 Name, IsReadOnly);

875 }

878

879

880 if (IsZeroInit || IsVirtual)

881 memset(Addr, 0, DataSize);

882 else

883 memcpy(Addr, pData, DataSize);

884

885

886 if (PaddingSize != 0) {

887 memset(Addr + DataSize, 0, PaddingSize);

888

889 DataSize += PaddingSize;

890

891

892

893 if (StubBufSize > 0)

894 DataSize &= -(uint64_t)getStubAlignment().value();

895 }

896

897 LLVM_DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: "

898 << Name << " obj addr: " << format("%p", pData)

899 << " new addr: " << format("%p", Addr) << " DataSize: "

900 << DataSize << " StubBufSize: " << StubBufSize

901 << " Allocate: " << Allocate << "\n");

902 } else {

903

904

905

906 Allocate = 0;

907 Addr = nullptr;

909 dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name

910 << " obj addr: " << format("%p", data.data()) << " new addr: 0"

911 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize

912 << " Allocate: " << Allocate << "\n");

913 }

914

915 Sections.push_back(

917

918

919

920 if (IsTLS)

921 Sections.back().setLoadAddress(LoadAddress);

922

923 if (!IsRequired)

924 Sections.back().setLoadAddress(0);

925

926 return SectionID;

927}

928

932 bool IsCode,

934

935 unsigned SectionID = 0;

936 ObjSectionToIDMap::iterator i = LocalSections.find(Section);

937 if (i != LocalSections.end())

938 SectionID = i->second;

939 else {

940 if (auto SectionIDOrErr = emitSection(Obj, Section, IsCode))

941 SectionID = *SectionIDOrErr;

942 else

943 return SectionIDOrErr.takeError();

944 LocalSections[Section] = SectionID;

945 }

946 return SectionID;

947}

948

950 unsigned SectionID) {

951 Relocations[SectionID].push_back(RE);

952}

953

956

957

958

960 if (Loc == GlobalSymbolTable.end()) {

961 ExternalSymbolRelocations[SymbolName].push_back(RE);

962 } else {

963 assert(!SymbolName.empty() &&

964 "Empty symbol should not be in GlobalSymbolTable");

965

967 const auto &SymInfo = Loc->second;

969 Relocations[SymInfo.getSectionID()].push_back(RECopy);

970 }

971}

972

974 unsigned AbiVariant) {

977

978

979

980

981 writeBytesUnaligned(0xd2e00010, Addr, 4);

982 writeBytesUnaligned(0xf2c00010, Addr+4, 4);

983 writeBytesUnaligned(0xf2a00010, Addr+8, 4);

984 writeBytesUnaligned(0xf2800010, Addr+12, 4);

985 writeBytesUnaligned(0xd61f0200, Addr+16, 4);

986

989

990

991 writeBytesUnaligned(0xe51ff004, Addr, 4);

992 return Addr + 4;

994

995

996

997

998

999 writeBytesUnaligned(0x1400000c, Addr, 4);

1000 writeBytesUnaligned(0x0380018c, Addr + 4, 4);

1001 writeBytesUnaligned(0x1600000c, Addr + 8, 4);

1002 writeBytesUnaligned(0x0300018c, Addr + 12, 4);

1003 writeBytesUnaligned(0x4c000180, Addr + 16, 4);

1004 return Addr;

1005 } else if (IsMipsO32ABI || IsMipsN32ABI) {

1006

1007

1008

1009

1010 const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;

1011 const unsigned NopInstr = 0x0;

1012 unsigned JrT9Instr = 0x03200008;

1015 JrT9Instr = 0x03200009;

1016

1017 writeBytesUnaligned(LuiT9Instr, Addr, 4);

1018 writeBytesUnaligned(AdduiT9Instr, Addr + 4, 4);

1019 writeBytesUnaligned(JrT9Instr, Addr + 8, 4);

1020 writeBytesUnaligned(NopInstr, Addr + 12, 4);

1021 return Addr;

1022 } else if (IsMipsN64ABI) {

1023

1024

1025

1026

1027

1028

1029

1030

1031 const unsigned LuiT9Instr = 0x3c190000, DaddiuT9Instr = 0x67390000,

1032 DsllT9Instr = 0x19CC38;

1033 const unsigned NopInstr = 0x0;

1034 unsigned JrT9Instr = 0x03200008;

1036 JrT9Instr = 0x03200009;

1037

1038 writeBytesUnaligned(LuiT9Instr, Addr, 4);

1039 writeBytesUnaligned(DaddiuT9Instr, Addr + 4, 4);

1040 writeBytesUnaligned(DsllT9Instr, Addr + 8, 4);

1041 writeBytesUnaligned(DaddiuT9Instr, Addr + 12, 4);

1042 writeBytesUnaligned(DsllT9Instr, Addr + 16, 4);

1043 writeBytesUnaligned(DaddiuT9Instr, Addr + 20, 4);

1044 writeBytesUnaligned(JrT9Instr, Addr + 24, 4);

1045 writeBytesUnaligned(NopInstr, Addr + 28, 4);

1046 return Addr;

1048

1049

1050

1051 writeInt32BE(Addr, 0x3D800000);

1052 writeInt32BE(Addr+4, 0x618C0000);

1053 writeInt32BE(Addr+8, 0x798C07C6);

1054 writeInt32BE(Addr+12, 0x658C0000);

1055 writeInt32BE(Addr+16, 0x618C0000);

1056 if (AbiVariant == 2) {

1057

1058

1059 writeInt32BE(Addr+20, 0xF8410018);

1060 writeInt32BE(Addr+24, 0x7D8903A6);

1061 writeInt32BE(Addr+28, 0x4E800420);

1062 } else {

1063

1064

1065

1066 writeInt32BE(Addr+20, 0xF8410028);

1067 writeInt32BE(Addr+24, 0xE96C0000);

1068 writeInt32BE(Addr+28, 0xE84C0008);

1069 writeInt32BE(Addr+32, 0x7D6903A6);

1070 writeInt32BE(Addr+36, 0xE96C0010);

1071 writeInt32BE(Addr+40, 0x4E800420);

1072 }

1073 return Addr;

1075 writeInt16BE(Addr, 0xC418);

1076 writeInt16BE(Addr+2, 0x0000);

1077 writeInt16BE(Addr+4, 0x0004);

1078 writeInt16BE(Addr+6, 0x07F1);

1079

1080 return Addr;

1082 *Addr = 0xFF;

1083 *(Addr+1) = 0x25;

1084

1086 *Addr = 0xE9;

1087 }

1088 return Addr;

1089}

1090

1091

1092

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1106 dbgs() << "Reassigning address for section " << SectionID << " ("

1107 << Sections[SectionID].getName() << "): "

1108 << format("0x%016" PRIx64, Sections[SectionID].getLoadAddress())

1109 << " -> " << format("0x%016" PRIx64, Addr) << "\n");

1110 Sections[SectionID].setLoadAddress(Addr);

1111}

1112

1116

1117 if (RE.SectionID != AbsoluteSymbolSection &&

1118 Sections[RE.SectionID].getAddress() == nullptr)

1119 continue;

1121 }

1122}

1123

1126 for (auto &RelocKV : ExternalSymbolRelocations) {

1129 if (Name.size() == 0) {

1130

1131 LLVM_DEBUG(dbgs() << "Resolving absolute relocations."

1132 << "\n");

1133 resolveRelocationList(Relocs, 0);

1134 } else {

1138 if (Loc == GlobalSymbolTable.end()) {

1139 auto RRI = ExternalSymbolMap.find(Name);

1140 assert(RRI != ExternalSymbolMap.end() && "No result for symbol");

1141 Addr = RRI->second.getAddress();

1142 Flags = RRI->second.getFlags();

1143 } else {

1144

1145

1146 const auto &SymInfo = Loc->second;

1147 Addr = getSectionLoadAddress(SymInfo.getSectionID()) +

1149 Flags = SymInfo.getFlags();

1150 }

1151

1152

1155 "' which could not be resolved!");

1156

1157

1158

1160

1161

1162

1163

1164 Addr = modifyAddressBasedOnFlags(Addr, Flags);

1165

1168 resolveRelocationList(Relocs, Addr);

1169 }

1170 }

1171 }

1172 ExternalSymbolRelocations.clear();

1173}

1174

1177

1178

1179

1180 {

1182

1183 while (true) {

1185

1186 for (auto &RelocKV : ExternalSymbolRelocations) {

1188 if (Name.empty() && !GlobalSymbolTable.count(Name) &&

1189 !ResolvedSymbols.count(Name))

1190 NewSymbols.insert(Name);

1191 }

1192

1193 if (NewSymbols.empty())

1194 break;

1195

1196#ifdef _MSC_VER

1197 using ExpectedLookupResult =

1199#else

1201#endif

1202

1203 auto NewSymbolsP = std::make_shared<std::promise>();

1204 auto NewSymbolsF = NewSymbolsP->get_future();

1207 NewSymbolsP->set_value(std::move(Result));

1208 });

1209

1210 auto NewResolverResults = NewSymbolsF.get();

1211

1212 if (!NewResolverResults)

1213 return NewResolverResults.takeError();

1214

1215 assert(NewResolverResults->size() == NewSymbols.size() &&

1216 "Should have errored on unresolved symbols");

1217

1218 for (auto &RRKV : *NewResolverResults) {

1219 assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");

1220 ExternalSymbolMap.insert(RRKV);

1221 ResolvedSymbols.insert(RRKV.first);

1222 }

1223 }

1224 }

1225

1226 applyExternalSymbolRelocations(ExternalSymbolMap);

1227

1229}

1230

1232 std::unique_ptr This,

1234 std::unique_ptrRuntimeDyld::LoadedObjectInfo, Error)>

1235 OnEmitted,

1237 std::unique_ptrRuntimeDyld::LoadedObjectInfo Info) {

1238

1239 auto SharedThis = std::shared_ptr(std::move(This));

1240 auto PostResolveContinuation =

1241 [SharedThis, OnEmitted = std::move(OnEmitted), O = std::move(O),

1244 if (!Result) {

1245 OnEmitted(std::move(O), std::move(Info), Result.takeError());

1246 return;

1247 }

1248

1249

1251 for (auto &KV : *Result)

1252 Resolved[KV.first] = KV.second;

1253

1254 SharedThis->applyExternalSymbolRelocations(Resolved);

1255 SharedThis->resolveLocalRelocations();

1256 SharedThis->registerEHFrames();

1257 std::string ErrMsg;

1258 if (SharedThis->MemMgr.finalizeMemory(&ErrMsg))

1259 OnEmitted(std::move(O), std::move(Info),

1260 make_error(std::move(ErrMsg),

1262 else

1264 };

1265

1267

1268 for (auto &RelocKV : SharedThis->ExternalSymbolRelocations) {

1270 if (Name.empty())

1271 continue;

1272 assert(!SharedThis->GlobalSymbolTable.count(Name) &&

1273 "Name already processed. RuntimeDyld instances can not be re-used "

1274 "when finalizing with finalizeAsync.");

1275 Symbols.insert(Name);

1276 }

1277

1278 if (!Symbols.empty()) {

1279 SharedThis->Resolver.lookup(Symbols, std::move(PostResolveContinuation));

1280 } else

1281 PostResolveContinuation(std::map<StringRef, JITEvaluatedSymbol>());

1282}

1283

1284

1285

1286

1289

1290 auto I = ObjSecToIDMap.find(Sec);

1291 if (I != ObjSecToIDMap.end())

1292 return RTDyld.Sections[I->second].getLoadAddress();

1293

1294 return 0;

1295}

1296

1299 unsigned Alignment,

1300 unsigned SectionID,

1303}

1304

1305void RuntimeDyld::MemoryManager::anchor() {}

1306void JITSymbolResolver::anchor() {}

1307void LegacyJITSymbolResolver::anchor() {}

1308

1312

1313

1314

1315

1316

1317

1318 Dyld = nullptr;

1319 ProcessAllSections = false;

1320}

1321

1323

1324static std::unique_ptr

1329 std::unique_ptr Dyld =

1331 Dyld->setProcessAllSections(ProcessAllSections);

1332 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1333 return Dyld;

1334}

1335

1336static std::unique_ptr

1340 std::unique_ptr Dyld =

1342 Dyld->setProcessAllSections(ProcessAllSections);

1343 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1344 return Dyld;

1345}

1346

1347static std::unique_ptr

1351 bool ProcessAllSections,

1353 std::unique_ptr Dyld =

1355 Dyld->setProcessAllSections(ProcessAllSections);

1356 Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));

1357 return Dyld;

1358}

1359

1360std::unique_ptrRuntimeDyld::LoadedObjectInfo

1362 if (!Dyld) {

1363 if (Obj.isELF())

1364 Dyld =

1366 MemMgr, Resolver, ProcessAllSections,

1367 std::move(NotifyStubEmitted));

1371 ProcessAllSections, std::move(NotifyStubEmitted));

1372 else if (Obj.isCOFF())

1375 ProcessAllSections, std::move(NotifyStubEmitted));

1376 else

1378 }

1379

1380 if (!Dyld->isCompatibleFile(Obj))

1382

1383 auto LoadedObjInfo = Dyld->loadObject(Obj);

1385 return LoadedObjInfo;

1386}

1387

1389 if (!Dyld)

1390 return nullptr;

1391 return Dyld->getSymbolLocalAddress(Name);

1392}

1393

1395 assert(Dyld && "No RuntimeDyld instance attached");

1396 return Dyld->getSymbolSectionID(Name);

1397}

1398

1400 if (!Dyld)

1401 return nullptr;

1402 return Dyld->getSymbol(Name);

1403}

1404

1406 if (!Dyld)

1407 return std::map<StringRef, JITEvaluatedSymbol>();

1408 return Dyld->getSymbolTable();

1409}

1410

1412

1414 Dyld->reassignSectionAddress(SectionID, Addr);

1415}

1416

1419 Dyld->mapSectionAddress(LocalAddress, TargetAddress);

1420}

1421

1423

1425

1427 bool MemoryFinalizationLocked = MemMgr.FinalizationLocked;

1428 MemMgr.FinalizationLocked = true;

1431 if (!MemoryFinalizationLocked) {

1433 MemMgr.FinalizationLocked = false;

1434 }

1435}

1436

1438 assert(Dyld && "No Dyld instance attached");

1439 return Dyld->getSectionContent(SectionID);

1440}

1441

1443 assert(Dyld && "No Dyld instance attached");

1444 return Dyld->getSectionLoadAddress(SectionID);

1445}

1446

1448 if (Dyld)

1449 Dyld->registerEHFrames();

1450}

1451

1453 if (Dyld)

1454 Dyld->deregisterEHFrames();

1455}

1456

1457

1458

1462 bool ProcessAllSections,

1465 std::map<StringRef, JITEvaluatedSymbol>)>

1466 OnLoaded,

1468 std::unique_ptrRuntimeDyld::LoadedObjectInfo, Error)>

1469 OnEmitted) {

1470

1473

1475

1477 OnEmitted(std::move(O), std::move(Info),

1480 return;

1481 }

1482

1483 if (auto Err = OnLoaded(*O.getBinary(), *Info, RTDyld.getSymbolTable())) {

1484 OnEmitted(std::move(O), std::move(Info), std::move(Err));

1485 return;

1486 }

1487

1489 std::move(O), std::move(Info));

1490}

1491

1492}

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static StringRef getName(Value *V)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

const Value * getAddress(const DbgVariableIntrinsic *DVI)

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.

Represents a symbol that has been evaluated to an address already.

Flags for symbols in the JIT.

static Expected< JITSymbolFlags > fromObjectSymbol(const object::SymbolRef &Symbol)

Construct a JITSymbolFlags value based on the flags of the given libobject symbol.

Symbol resolution interface.

std::set< StringRef > LookupSet

RelocationEntry - used to represent relocations internally in the dynamic linker.

int64_t Addend

Addend - the relocation addend encoded in the instruction itself.

Interface for looking up the initializer for a variable name, used by Init::resolveReferences.

static std::unique_ptr< RuntimeDyldCOFF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)

static std::unique_ptr< RuntimeDyldELF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)

void log(raw_ostream &OS) const override

Print an error message to an output stream.

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)

void reassignSectionAddress(unsigned SectionID, uint64_t Addr)

std::map< SectionRef, unsigned > ObjSectionToIDMap

void applyExternalSymbolRelocations(const StringMap< JITEvaluatedSymbol > ExternalSymbolMap)

void resolveRelocationList(const RelocationList &Relocs, uint64_t Value)

Resolves relocations from Relocs list with address from Value.

std::map< RelocationValueRef, uintptr_t > StubMap

void deregisterEHFrames()

void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)

virtual void registerEHFrames()

virtual ~RuntimeDyldImpl()

static void finalizeAsync(std::unique_ptr< RuntimeDyldImpl > This, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted, object::OwningBinary< object::ObjectFile > O, std::unique_ptr< RuntimeDyld::LoadedObjectInfo > Info)

Error emitCommonSymbols(const ObjectFile &Obj, CommonSymbolList &CommonSymbols, uint64_t CommonSize, uint32_t CommonAlign)

Given the common symbols discovered in the object file, emit a new section for them and update the sy...

Expected< unsigned > emitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode)

Emits section data from the object file to the MemoryManager.

std::vector< SymbolRef > CommonSymbolList

void resolveLocalRelocations()

void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)

Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)

Find Section in LocalSections.

unsigned computeGOTSize(const ObjectFile &Obj)

void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const

Endian-aware write.

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.

Error computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, Align &CodeAlign, uint64_t &RODataSize, Align &RODataAlign, uint64_t &RWDataSize, Align &RWDataAlign)

unsigned computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section)

void resolveRelocations()

virtual Expected< JITSymbolFlags > getJITSymbolFlags(const SymbolRef &Sym)

Generate JITSymbolFlags from a libObject symbol.

Expected< ObjSectionToIDMap > loadObjectImpl(const object::ObjectFile &Obj)

Error resolveExternalSymbols()

Resolve relocations to external symbols.

static std::unique_ptr< RuntimeDyldMachO > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)

Create a RuntimeDyldMachO instance for the given target architecture.

Information about the loaded object.

uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override

Obtain the Load Address of a section by SectionRef.

virtual void notifyObjectLoaded(RuntimeDyld &RTDyld, const object::ObjectFile &Obj)

This method is called after an object has been loaded into memory but before relocations are applied ...

virtual TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName)

Allocate a memory block of (at least) the given size to be used for thread-local storage (TLS).

virtual bool finalizeMemory(std::string *ErrMsg=nullptr)=0

This method is called when object loading is complete and section page permissions can be applied.

void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)

Map a section to its target address space value.

void setProcessAllSections(bool ProcessAllSections)

By default, only sections that are "required for execution" are passed to the RTDyldMemoryManager,...

void reassignSectionAddress(unsigned SectionID, uint64_t Addr)

uint64_t getSectionLoadAddress(unsigned SectionID) const

If the section was loaded, return the section's load address, otherwise return std::nullopt.

void * getSymbolLocalAddress(StringRef Name) const

Get the address of our local copy of the symbol.

std::map< StringRef, JITEvaluatedSymbol > getSymbolTable() const

Returns a copy of the symbol table.

void resolveRelocations()

Resolve the relocations for all symbols we currently know about.

void finalizeWithMemoryManagerLocking()

Perform all actions needed to make the code owned by this RuntimeDyld instance executable:

void deregisterEHFrames()

void registerEHFrames()

Register any EH frame sections that have been loaded but not previously registered with the memory ma...

StringRef getSectionContent(unsigned SectionID) const

Returns the section's working memory.

JITEvaluatedSymbol getSymbol(StringRef Name) const

Get the target address and flags for the named symbol.

RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver)

Construct a RuntimeDyld instance.

std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)

Add the referenced object file to the list of objects to be loaded and relocated.

StringRef getErrorString()

unsigned getSymbolSectionID(StringRef Name) const

Get the section ID for the section containing the given symbol.

std::function< void(StringRef FileName, StringRef SectionName, StringRef SymbolName, unsigned SectionID, uint32_t StubOffset)> NotifyStubEmittedFunction

SectionEntry - represents a section emitted into memory by the dynamic linker.

StringRef getName() const

uint8_t * getAddress() const

uint64_t getLoadAddress() const

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

iterator find(StringRef Key)

bool insert(MapEntryTy *KeyValue)

insert - Insert the specified key/value pair into the map.

StringRef - Represent a constant reference to a string, i.e.

Symbol info for RuntimeDyld.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

bool isLittleEndian() const

StringRef getFileName() const

uint64_t getFlags() const

This class is the base class for all object file types.

virtual section_iterator section_end() const =0

symbol_iterator_range symbols() const

virtual Triple::ArchType getArch() const =0

virtual section_iterator section_begin() const =0

This is a value type class that represents a single relocation in the list of relocations in the obje...

This is a value type class that represents a single section in the list of sections in the object fil...

uint64_t getAddress() const

bool isText() const

Whether this section contains instructions.

This is a value type class that represents a single symbol in the list of symbols in the object file.

virtual basic_symbol_iterator symbol_begin() const =0

virtual basic_symbol_iterator symbol_end() const =0

This class implements an extremely fast bulk output stream that can only output to a stream.

unique_function is a type-erasing functor similar to std::function.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_SCN_CNT_UNINITIALIZED_DATA

@ IMAGE_SCN_MEM_DISCARDABLE

@ IMAGE_SCN_CNT_INITIALIZED_DATA

@ S_GB_ZEROFILL

S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).

@ S_ZEROFILL

S_ZEROFILL - Zero fill on demand section.

uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, uint64_t S, uint64_t LocData)

This is an optimization pass for GlobalISel generic memory operations.

std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

static std::unique_ptr< RuntimeDyldMachO > createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

static bool isTLS(const SectionRef Section)

static void dumpSectionMemory(const SectionEntry &S, StringRef State)

static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)

static std::unique_ptr< RuntimeDyldCOFF > createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

static bool isReadOnlyData(const SectionRef Section)

void jitLinkForORC(object::OwningBinary< object::ObjectFile > O, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections, unique_function< Error(const object::ObjectFile &Obj, RuntimeDyld::LoadedObjectInfo &, std::map< StringRef, JITEvaluatedSymbol >)> OnLoaded, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted)

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

static std::unique_ptr< RuntimeDyldELF > createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted)

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

static bool isZeroInit(const SectionRef Section)

Align commonAlignment(Align A, uint64_t Offset)

Returns the alignment that satisfies both alignments.

const char * toString(DWARFSectionKind Kind)

static uint64_t computeAllocationSizeForSections(std::vector< uint64_t > &SectionSizes, Align Alignment)

static bool isRequiredForExecution(const SectionRef Section)

SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t value() const

This is a hole in the type system and should not be abused.

An allocated TLS section.

support::ulittle32_t VirtualSize

support::ulittle32_t Characteristics

support::ulittle32_t SizeOfRawData