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

1

2

3

4

5

6

7

8

10

20#include

21

22#define DEBUG_TYPE "orc"

23

24using namespace llvm;

27

28namespace llvm {

29namespace orc {

31

35

36class SPSMachOExecutorSymbolFlags;

37

38template <>

41public:

43 return SPSMachOJITDylibDepInfo::AsArgList::size(DDI.Sealed, DDI.DepHeaders);

44 }

45

48 return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.Sealed,

50 }

51

54 return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.Sealed,

56 }

57};

58

59template <>

62private:

63 using UT = std::underlying_type_tMachOPlatform::MachOExecutorSymbolFlags;

64

65public:

67 return sizeof(UT);

68 }

69

74

77 UT Tmp;

79 return false;

81 return true;

82 }

83};

84

85}

86}

87}

88

89namespace {

90

91using SPSRegisterSymbolsArgs =

94 SPSMachOExecutorSymbolFlags>>>;

95

96std::unique_ptrjitlink::LinkGraph createPlatformGraph(MachOPlatform &MOP,

97 std::string Name) {

99 return std::make_uniquejitlink::LinkGraph(

100 std::move(Name), ES.getSymbolStringPool(), ES.getTargetTriple(),

102}

103

104

105class MachOPlatformCompleteBootstrapMaterializationUnit

107public:

108 using SymbolTableVector =

109 SmallVector<std::tuple<ExecutorAddr, ExecutorAddr,

111

112 MachOPlatformCompleteBootstrapMaterializationUnit(

113 MachOPlatform &MOP, StringRef PlatformJDName,

114 SymbolStringPtr CompleteBootstrapSymbol, SymbolTableVector SymTab,

116 ExecutorAddr PlatformBootstrap, ExecutorAddr PlatformShutdown,

117 ExecutorAddr RegisterJITDylib, ExecutorAddr DeregisterJITDylib,

118 ExecutorAddr RegisterObjectSymbolTable,

119 ExecutorAddr DeregisterObjectSymbolTable)

120 : MaterializationUnit(

122 MOP(MOP), PlatformJDName(PlatformJDName),

123 CompleteBootstrapSymbol(std::move(CompleteBootstrapSymbol)),

124 SymTab(std::move(SymTab)), DeferredAAs(std::move(DeferredAAs)),

125 MachOHeaderAddr(MachOHeaderAddr), PlatformBootstrap(PlatformBootstrap),

126 PlatformShutdown(PlatformShutdown), RegisterJITDylib(RegisterJITDylib),

127 DeregisterJITDylib(DeregisterJITDylib),

128 RegisterObjectSymbolTable(RegisterObjectSymbolTable),

129 DeregisterObjectSymbolTable(DeregisterObjectSymbolTable) {}

130

131 StringRef getName() const override {

132 return "MachOPlatformCompleteBootstrap";

133 }

134

135 void materialize(std::unique_ptr R) override {

136 using namespace jitlink;

137 auto G = createPlatformGraph(MOP, "");

138 auto &PlaceholderSection =

139 G->createSection("__orc_rt_cplt_bs", MemProt::Read);

140 auto &PlaceholderBlock =

141 G->createZeroFillBlock(PlaceholderSection, 1, ExecutorAddr(), 1, 0);

142 G->addDefinedSymbol(PlaceholderBlock, 0, *CompleteBootstrapSymbol, 1,

143 Linkage::Strong, Scope::Hidden, false, true);

144

145

146 G->allocActions().reserve(DeferredAAs.size() + 3);

147

148

149 G->allocActions().push_back(

153

154

155 G->allocActions().push_back(

157 SPSArgList<SPSString, SPSExecutorAddr>>(

158 RegisterJITDylib, PlatformJDName, MachOHeaderAddr)),

160 DeregisterJITDylib, MachOHeaderAddr))});

161

162

163 G->allocActions().push_back(

165 RegisterObjectSymbolTable, MachOHeaderAddr, SymTab)),

167 DeregisterObjectSymbolTable, MachOHeaderAddr, SymTab))});

168

169

170 std::move(DeferredAAs.begin(), DeferredAAs.end(),

171 std::back_inserter(G->allocActions()));

172

173 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));

174 }

175

176 void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}

177

178private:

179 MachOPlatform &MOP;

180 StringRef PlatformJDName;

181 SymbolStringPtr CompleteBootstrapSymbol;

182 SymbolTableVector SymTab;

184 ExecutorAddr MachOHeaderAddr;

185 ExecutorAddr PlatformBootstrap;

186 ExecutorAddr PlatformShutdown;

187 ExecutorAddr RegisterJITDylib;

188 ExecutorAddr DeregisterJITDylib;

189 ExecutorAddr RegisterObjectSymbolTable;

190 ExecutorAddr DeregisterObjectSymbolTable;

191};

192

193static StringRef ObjCRuntimeObjectSectionsData[] = {

200

201static StringRef ObjCRuntimeObjectSectionsText[] = {

207

208static StringRef ObjCRuntimeObjectSectionName =

209 "__llvm_jitlink_ObjCRuntimeRegistrationObject";

210

211static StringRef ObjCImageInfoSymbolName =

212 "__llvm_jitlink_macho_objc_imageinfo";

213

214struct ObjCImageInfoFlags {

215 uint16_t SwiftABIVersion;

216 uint16_t SwiftVersion;

217 bool HasCategoryClassProperties;

218 bool HasSignedObjCClassROs;

219

220 static constexpr uint32_t SIGNED_CLASS_RO = (1 << 4);

221 static constexpr uint32_t HAS_CATEGORY_CLASS_PROPERTIES = (1 << 6);

222

223 explicit ObjCImageInfoFlags(uint32_t RawFlags) {

224 HasSignedObjCClassROs = RawFlags & SIGNED_CLASS_RO;

225 HasCategoryClassProperties = RawFlags & HAS_CATEGORY_CLASS_PROPERTIES;

226 SwiftABIVersion = (RawFlags >> 8) & 0xFF;

227 SwiftVersion = (RawFlags >> 16) & 0xFFFF;

228 }

229

230 uint32_t rawFlags() const {

232 if (HasCategoryClassProperties)

233 Result |= HAS_CATEGORY_CLASS_PROPERTIES;

234 if (HasSignedObjCClassROs)

235 Result |= SIGNED_CLASS_RO;

236 Result |= (SwiftABIVersion << 8);

237 Result |= (SwiftVersion << 16);

239 }

240};

241}

242

243namespace llvm {

244namespace orc {

245

246std::optionalMachOPlatform::HeaderOptions::BuildVersionOpts

250

252 switch (TT.getOS()) {

254 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR

255 : MachO::PLATFORM_IOS;

256 break;

258 Platform = MachO::PLATFORM_MACOS;

259 break;

261 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR

262 : MachO::PLATFORM_TVOS;

263 break;

265 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR

266 : MachO::PLATFORM_WATCHOS;

267 break;

269 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR

270 : MachO::PLATFORM_XROS;

271 break;

272 default:

273 return std::nullopt;

274 }

275

277}

278

281 std::unique_ptr OrcRuntime,

284 std::optional RuntimeAliases) {

285

286 auto &ES = ObjLinkingLayer.getExecutionSession();

287

288

289 if (!supportedTarget(ES.getTargetTriple()))

291 ES.getTargetTriple().str(),

293

294 auto &EPC = ES.getExecutorProcessControl();

295

296

297 if (!RuntimeAliases)

299

300

301 if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))

302 return std::move(Err);

303

304

305 if (auto Err = PlatformJD.define(

307 {EPC.getJITDispatchInfo().JITDispatchFunction,

309 {ES.intern("___orc_rt_jit_dispatch_ctx"),

310 {EPC.getJITDispatchInfo().JITDispatchContext,

312 return std::move(Err);

313

314

316 auto P = std::unique_ptr(new MachOPlatform(

317 ObjLinkingLayer, PlatformJD, std::move(OrcRuntime),

318 std::move(PlatformJDOpts), std::move(BuildMachOHeaderMU), Err));

319 if (Err)

320 return std::move(Err);

321 return std::move(P);

322}

323

326 const char *OrcRuntimePath, HeaderOptions PlatformJDOpts,

328 std::optional RuntimeAliases) {

329

330

331 auto OrcRuntimeArchiveGenerator =

333 if (!OrcRuntimeArchiveGenerator)

334 return OrcRuntimeArchiveGenerator.takeError();

335

336 return Create(ObjLinkingLayer, PlatformJD,

337 std::move(*OrcRuntimeArchiveGenerator),

338 std::move(PlatformJDOpts), std::move(BuildMachOHeaderMU),

339 std::move(RuntimeAliases));

340}

341

345

347 if (auto Err = JD.define(BuildMachOHeaderMU(*this, std::move(Opts))))

348 return Err;

349

350 return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();

351}

352

354 std::lock_guardstd::mutex Lock(PlatformMutex);

355 auto I = JITDylibToHeaderAddr.find(&JD);

356 if (I != JITDylibToHeaderAddr.end()) {

357 assert(HeaderAddrToJITDylib.count(I->second) &&

358 "HeaderAddrToJITDylib missing entry");

359 HeaderAddrToJITDylib.erase(I->second);

360 JITDylibToHeaderAddr.erase(I);

361 }

362 JITDylibToPThreadKey.erase(&JD);

364}

365

370 if (!InitSym)

372

373 RegisteredInitSymbols[&JD].add(InitSym,

376 dbgs() << "MachOPlatform: Registered init symbol " << *InitSym << " for MU "

378 });

380}

381

385

387 ArrayRef<std::pair<const char *, const char *>> AL) {

388 for (auto &KV : AL) {

389 auto AliasName = ES.intern(KV.first);

390 assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");

391 Aliases[std::move(AliasName)] = {ES.intern(KV.second),

393 }

394}

395

403

406 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {

407 {"___cxa_atexit", "___orc_rt_macho_cxa_atexit"}};

408

410}

411

414 static const std::pair<const char *, const char *>

415 StandardRuntimeUtilityAliases[] = {

416 {"___orc_rt_run_program", "___orc_rt_macho_run_program"},

417 {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},

418 {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},

419 {"___orc_rt_jit_dlupdate", "___orc_rt_macho_jit_dlupdate"},

420 {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},

421 {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},

422 {"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};

423

425 StandardRuntimeUtilityAliases);

426}

427

430 static const std::pair<const char *, const char *>

431 StandardLazyCompilationAliases[] = {

432 {"__orc_rt_reenter", "__orc_rt_sysv_reenter"},

433 {"__orc_rt_resolve_tag", "___orc_rt_resolve_tag"}};

434

436 StandardLazyCompilationAliases);

437}

438

439bool MachOPlatform::supportedTarget(const Triple &TT) {

440 switch (TT.getArch()) {

443 return true;

444 default:

445 return false;

446 }

447}

448

449jitlink::Edge::Kind MachOPlatform::getPointerEdgeKind(jitlink::LinkGraph &G) {

450 switch (G.getTargetTriple().getArch()) {

455 default:

457 }

458}

459

461MachOPlatform::flagsForSymbol(jitlink::Symbol &Sym) {

465

468

470}

471

472MachOPlatform::MachOPlatform(

473 ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,

474 std::unique_ptr OrcRuntimeGenerator,

478 ObjLinkingLayer(ObjLinkingLayer),

479 BuildMachOHeaderMU(std::move(BuildMachOHeaderMU)) {

480 ErrorAsOutParameter _(Err);

481 ObjLinkingLayer.addPlugin(std::make_unique(*this));

482 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));

483

484 {

485

486 std::optional ForceEHFrames;

487 if ((Err = ES.getBootstrapMapValue<bool, bool>("darwin-use-ehframes-only",

488 ForceEHFrames)))

489 return;

490 this->ForceEHFrames = ForceEHFrames.value_or(false);

491 }

492

493 BootstrapInfo BI;

494 Bootstrap = &BI;

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551 if ((Err = PlatformJD.define(

552 this->BuildMachOHeaderMU(*this, std::move(PlatformJDOpts)))))

553 return;

554 if ((Err = ES.lookup(&PlatformJD, MachOHeaderStartSymbol).takeError()))

555 return;

556

557

558

560 SymbolLookupSet(

561 {PlatformBootstrap.Name, PlatformShutdown.Name,

562 RegisterJITDylib.Name, DeregisterJITDylib.Name,

563 RegisterObjectSymbolTable.Name,

564 DeregisterObjectSymbolTable.Name,

565 RegisterObjectPlatformSections.Name,

566 DeregisterObjectPlatformSections.Name,

567 CreatePThreadKey.Name}))

568 .takeError()))

569 return;

570

571

572 {

573 std::unique_lockstd::mutex Lock(PlatformMutex);

574 BI.CV.wait(Lock, [&]() { return BI.ActiveGraphs == 0; });

575 Bootstrap = nullptr;

576 }

577

578

579 auto BootstrapCompleteSymbol = ES.intern("__orc_rt_macho_complete_bootstrap");

580 if ((Err = PlatformJD.define(

581 std::make_unique(

582 *this, PlatformJD.getName(), BootstrapCompleteSymbol,

583 std::move(BI.SymTab), std::move(BI.DeferredAAs),

584 BI.MachOHeaderAddr, PlatformBootstrap.Addr,

585 PlatformShutdown.Addr, RegisterJITDylib.Addr,

586 DeregisterJITDylib.Addr, RegisterObjectSymbolTable.Addr,

587 DeregisterObjectSymbolTable.Addr))))

588 return;

591 std::move(BootstrapCompleteSymbol))

592 .takeError()))

593 return;

594

595

596

597

598

599

600

601

602 if ((Err = associateRuntimeSupportFunctions()))

603 return;

604}

605

606Error MachOPlatform::associateRuntimeSupportFunctions() {

608

609 using PushInitializersSPSSig =

610 SPSExpected(SPSExecutorAddr);

611 WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =

612 ES.wrapAsyncWithSPS(

613 this, &MachOPlatform::rt_pushInitializers);

614

615 using PushSymbolsSPSSig =

616 SPSError(SPSExecutorAddr, SPSSequence<SPSTuple<SPSString, bool>>);

617 WFs[ES.intern("___orc_rt_macho_push_symbols_tag")] =

618 ES.wrapAsyncWithSPS(this,

619 &MachOPlatform::rt_pushSymbols);

620

621 return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));

622}

623

624void MachOPlatform::pushInitializersLoop(

625 PushInitializersSendResultFn SendResult, JITDylibSP JD) {

626 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;

627 DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;

629

630 ES.runSessionLocked([&]() {

631 while (!Worklist.empty()) {

632

633

634 auto DepJD = Worklist.back();

635 Worklist.pop_back();

636

637

639 if (!Inserted)

640 continue;

641

642

643 auto &DM = It->second;

645 for (auto &KV : O) {

646 if (KV.first == DepJD)

647 continue;

648 DM.push_back(KV.first);

649 Worklist.push_back(KV.first);

650 }

651 });

652

653

654 auto RISItr = RegisteredInitSymbols.find(DepJD);

655 if (RISItr != RegisteredInitSymbols.end()) {

656 NewInitSymbols[DepJD] = std::move(RISItr->second);

657 RegisteredInitSymbols.erase(RISItr);

658 }

659 }

660 });

661

662

663

664 if (NewInitSymbols.empty()) {

665

666

667

668

669

670 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;

672 {

673 std::lock_guardstd::mutex Lock(PlatformMutex);

674 for (auto &KV : JDDepMap) {

675 auto I = JITDylibToHeaderAddr.find(KV.first);

676 if (I != JITDylibToHeaderAddr.end())

677 HeaderAddrs[KV.first] = I->second;

678 }

679 }

680

681

683 DIM.reserve(JDDepMap.size());

684 for (auto &KV : JDDepMap) {

685 auto HI = HeaderAddrs.find(KV.first);

686

687 if (HI == HeaderAddrs.end())

688 continue;

689 auto H = HI->second;

691 for (auto &Dep : KV.second) {

692 auto HJ = HeaderAddrs.find(Dep);

693 if (HJ != HeaderAddrs.end())

694 DepInfo.DepHeaders.push_back(HJ->second);

695 }

696 DIM.push_back(std::make_pair(H, std::move(DepInfo)));

697 }

698 SendResult(DIM);

699 return;

700 }

701

702

704 [this, SendResult = std::move(SendResult), JD](Error Err) mutable {

705 if (Err)

706 SendResult(std::move(Err));

707 else

708 pushInitializersLoop(std::move(SendResult), JD);

709 },

710 ES, std::move(NewInitSymbols));

711}

712

713void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,

716 {

717 std::lock_guardstd::mutex Lock(PlatformMutex);

718 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);

719 if (I != HeaderAddrToJITDylib.end())

720 JD = I->second;

721 }

722

724 dbgs() << "MachOPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";

725 if (JD)

726 dbgs() << "pushing initializers for " << JD->getName() << "\n";

727 else

728 dbgs() << "No JITDylib for header address.\n";

729 });

730

731 if (!JD) {

733 formatv("{0:x}", JDHeaderAddr),

735 return;

736 }

737

738 pushInitializersLoop(std::move(SendResult), JD);

739}

740

741void MachOPlatform::rt_pushSymbols(

742 PushSymbolsInSendResultFn SendResult, ExecutorAddr Handle,

743 const std::vector<std::pair<StringRef, bool>> &SymbolNames) {

744

745 JITDylib *JD = nullptr;

746

747 {

748 std::lock_guardstd::mutex Lock(PlatformMutex);

749 auto I = HeaderAddrToJITDylib.find(Handle);

750 if (I != HeaderAddrToJITDylib.end())

751 JD = I->second;

752 }

754 dbgs() << "MachOPlatform::rt_pushSymbols(";

755 if (JD)

756 dbgs() << "\"" << JD->getName() << "\", [ ";

757 else

758 dbgs() << "<invalid handle " << Handle << ">, [ ";

759 for (auto &Name : SymbolNames)

760 dbgs() << "\"" << Name.first << "\" ";

761 dbgs() << "])\n";

762 });

763

764 if (!JD) {

766 formatv("{0:x}", Handle),

768 return;

769 }

770

771 SymbolLookupSet LS;

772 for (auto &[Name, Required] : SymbolNames)

776

777 ES.lookup(

780 [SendResult = std::move(SendResult)](Expected Result) mutable {

781 SendResult(Result.takeError());

782 },

784}

785

786Expected<uint64_t> MachOPlatform::createPThreadKey() {

787 if (!CreatePThreadKey.Addr)

789 "Attempting to create pthread key in target, but runtime support has "

790 "not been loaded yet",

792

793 Expected<uint64_t> Result(0);

794 if (auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(void)>(

795 CreatePThreadKey.Addr, Result))

796 return std::move(Err);

798}

799

800void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(

802 jitlink::PassConfiguration &Config) {

803

804 using namespace jitlink;

805

806 bool InBootstrapPhase = false;

807

808 ExecutorAddr HeaderAddr;

809 {

810 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

812 if (MP.Bootstrap) {

813 InBootstrapPhase = true;

814 ++MP.Bootstrap->ActiveGraphs;

815 }

816 }

817

818

820 if (I != MP.JITDylibToHeaderAddr.end())

821 HeaderAddr = I->second;

822 }

823

824

825

826 if (MP.ForceEHFrames)

829

830

831

832

833 if (HeaderAddr)

834 LG.addAbsoluteSymbol("__jitlink$libunwind_dso_base", HeaderAddr, 0,

835 Linkage::Strong, Scope::Local, true);

836

837

840 return bootstrapPipelineRecordRuntimeFunctions(G);

841 });

842

843

845

846

847

848

849 if (InitSymbol == MP.MachOHeaderStartSymbol && !InBootstrapPhase) {

851 return associateJITDylibHeaderSymbol(G, MR);

852 });

853 return;

854 }

855

856

857

858

859 Config.PrePrunePasses.push_back([this, &MR](LinkGraph &G) {

860 if (auto Err = preserveImportantSections(G, MR))

861 return Err;

862 return processObjCImageInfo(G, MR);

863 });

865 [this](LinkGraph &G) { return createObjCRuntimeObject(G); });

867 [this, &MR](LinkGraph &G) { return populateObjCRuntimeObject(G, MR); });

868 }

869

870

871

875 return fixTLVSectionsAndEdges(G, JD);

876 });

877

878

879

880

881 auto JITSymTabInfo = std::make_shared();

882 Config.PostPrunePasses.push_back([this, JITSymTabInfo](LinkGraph &G) {

883 return prepareSymbolTableRegistration(G, *JITSymTabInfo);

884 });

885 Config.PostFixupPasses.push_back([this, &MR, JITSymTabInfo,

886 InBootstrapPhase](LinkGraph &G) {

887 return addSymbolTableRegistration(G, MR, *JITSymTabInfo, InBootstrapPhase);

888 });

889

890

891

893 HeaderAddr,

894 InBootstrapPhase](LinkGraph &G) {

895 return registerObjectPlatformSections(G, JD, HeaderAddr, InBootstrapPhase);

896 });

897

898

899

900 if (InBootstrapPhase)

902 [this](LinkGraph &G) { return bootstrapPipelineEnd(G); });

903}

904

905Error MachOPlatform::MachOPlatformPlugin::

906 bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G) {

907

908 std::pair<StringRef, ExecutorAddr *> RuntimeSymbols[] = {

909 {*MP.MachOHeaderStartSymbol, &MP.Bootstrap->MachOHeaderAddr},

910 {*MP.PlatformBootstrap.Name, &MP.PlatformBootstrap.Addr},

911 {*MP.PlatformShutdown.Name, &MP.PlatformShutdown.Addr},

912 {*MP.RegisterJITDylib.Name, &MP.RegisterJITDylib.Addr},

913 {*MP.DeregisterJITDylib.Name, &MP.DeregisterJITDylib.Addr},

914 {*MP.RegisterObjectSymbolTable.Name, &MP.RegisterObjectSymbolTable.Addr},

915 {*MP.DeregisterObjectSymbolTable.Name,

916 &MP.DeregisterObjectSymbolTable.Addr},

917 {*MP.RegisterObjectPlatformSections.Name,

918 &MP.RegisterObjectPlatformSections.Addr},

919 {*MP.DeregisterObjectPlatformSections.Name,

920 &MP.DeregisterObjectPlatformSections.Addr},

921 {*MP.CreatePThreadKey.Name, &MP.CreatePThreadKey.Addr},

922 {*MP.RegisterObjCRuntimeObject.Name, &MP.RegisterObjCRuntimeObject.Addr},

923 {*MP.DeregisterObjCRuntimeObject.Name,

924 &MP.DeregisterObjCRuntimeObject.Addr}};

925

926 bool RegisterMachOHeader = false;

927

928 for (auto *Sym : G.defined_symbols()) {

929 for (auto &RTSym : RuntimeSymbols) {

930 if (Sym->hasName() && *Sym->getName() == RTSym.first) {

931 if (*RTSym.second)

933 "Duplicate " + RTSym.first +

934 " detected during MachOPlatform bootstrap",

936

937 if (Sym->getName() == MP.MachOHeaderStartSymbol)

938 RegisterMachOHeader = true;

939

941 }

942 }

943 }

944

945 if (RegisterMachOHeader) {

946

947

948 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

949 MP.JITDylibToHeaderAddr[&MP.PlatformJD] = MP.Bootstrap->MachOHeaderAddr;

950 MP.HeaderAddrToJITDylib[MP.Bootstrap->MachOHeaderAddr] = &MP.PlatformJD;

951 }

952

954}

955

956Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(

957 jitlink::LinkGraph &G) {

958 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

959

960 --MP.Bootstrap->ActiveGraphs;

961

962

963 if (MP.Bootstrap->ActiveGraphs == 0)

964 MP.Bootstrap->CV.notify_all();

966}

967

968Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(

969 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

970 auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {

971 return Sym->getName() == MP.MachOHeaderStartSymbol;

972 });

973 assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");

974

976 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

977 auto HeaderAddr = (*I)->getAddress();

978 MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;

979 MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;

980

981

982 G.allocActions().push_back(

985 MP.RegisterJITDylib.Addr, JD.getName(), HeaderAddr)),

987 MP.DeregisterJITDylib.Addr, HeaderAddr))});

989}

990

991Error MachOPlatform::MachOPlatformPlugin::preserveImportantSections(

992 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

993

994

995

996

997 if (auto *ObjCImageInfoSec =

999 if (ObjCImageInfoSec->blocks_size() != 1)

1001 "In " + G.getName() +

1002 "__DATA,__objc_imageinfo contains multiple blocks",

1004 G.addAnonymousSymbol(**ObjCImageInfoSec->blocks().begin(), 0, 0, false,

1005 true);

1006

1007 for (auto *B : ObjCImageInfoSec->blocks())

1008 if (B->edges_empty())

1011 " contains references to symbols",

1013 }

1014

1015

1016

1017

1019

1020 jitlink::Symbol *InitSym = nullptr;

1022

1023

1025 continue;

1026

1027

1028 auto *InitSection = G.findSectionByName(InitSectionName);

1029 if (!InitSection || InitSection->empty())

1030 continue;

1031

1032

1033

1034 if (!InitSym) {

1035 auto &B = **InitSection->blocks().begin();

1036 InitSym = &G.addDefinedSymbol(

1039 }

1040

1041

1042 for (auto *B : InitSection->blocks()) {

1044 continue;

1045

1046 auto &S = G.addAnonymousSymbol(*B, 0, B->getSize(), false, true);

1047 InitSym->getBlock().addEdge(jitlink::Edge::KeepAlive, 0, S, 0);

1048 }

1049 }

1050 }

1051

1053}

1054

1055Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(

1056 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

1057

1058

1059

1060

1061

1062

1063

1065 if (!ObjCImageInfo)

1067

1068 auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();

1069

1070

1071 if (ObjCImageInfoBlocks.empty())

1073 " section in " + G.getName(),

1075

1076

1077 if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())

1080 " section in " + G.getName(),

1082

1083

1084

1085 for (auto &Sec : G.sections()) {

1086 if (&Sec != ObjCImageInfo)

1087 for (auto *B : Sec.blocks())

1088 for (auto &E : B->edges())

1089 if (E.getTarget().isDefined() &&

1090 &E.getTarget().getSection() == ObjCImageInfo)

1092 " is referenced within file " +

1093 G.getName(),

1095 }

1096

1097 auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();

1098 auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();

1102

1103

1104 std::lock_guardstd::mutex Lock(PluginMutex);

1105

1106 auto ObjCImageInfoItr = ObjCImageInfos.find(&MR.getTargetJITDylib());

1107 if (ObjCImageInfoItr != ObjCImageInfos.end()) {

1108

1109

1110 if (ObjCImageInfoItr->second.Version != Version)

1112 "ObjC version in " + G.getName() +

1113 " does not match first registered version",

1115 if (ObjCImageInfoItr->second.Flags != Flags)

1116 if (Error E = mergeImageInfoFlags(G, MR, ObjCImageInfoItr->second, Flags))

1117 return E;

1118

1119

1120 for (auto *S : ObjCImageInfo->symbols())

1121 G.removeDefinedSymbol(*S);

1122 G.removeBlock(ObjCImageInfoBlock);

1123 } else {

1125 dbgs() << "MachOPlatform: Registered __objc_imageinfo for "

1127 << "; flags = " << formatv("{0:x4}", Flags) << "\n";

1128 });

1129

1130

1131 G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,

1135 {{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),

1136 JITSymbolFlags()}}))

1137 return Err;

1139 }

1140

1142}

1143

1144Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(

1146 ObjCImageInfo &Info, uint32_t NewFlags) {

1147 if (Info.Flags == NewFlags)

1149

1150 ObjCImageInfoFlags Old(Info.Flags);

1151 ObjCImageInfoFlags New(NewFlags);

1152

1153

1154 if (Old.SwiftABIVersion && New.SwiftABIVersion &&

1155 Old.SwiftABIVersion != New.SwiftABIVersion)

1157 " does not match first registered flags",

1159

1160

1161

1162

1163 if (Info.Finalized && Old.HasCategoryClassProperties &&

1164 New.HasCategoryClassProperties)

1166 G.getName() +

1167 " does not match first registered flags",

1169 if (Info.Finalized && Old.HasSignedObjCClassROs && New.HasSignedObjCClassROs)

1171 G.getName() +

1172 " does not match first registered flags",

1174

1175

1176

1177 if (Info.Finalized)

1179

1180

1181 if (Old.SwiftVersion && New.SwiftVersion)

1182 New.SwiftVersion = std::min(Old.SwiftVersion, New.SwiftVersion);

1183 else if (Old.SwiftVersion)

1184 New.SwiftVersion = Old.SwiftVersion;

1185

1186 if (New.SwiftABIVersion)

1187 New.SwiftABIVersion = Old.SwiftABIVersion;

1188

1189 if (Old.HasCategoryClassProperties != New.HasCategoryClassProperties)

1190 New.HasCategoryClassProperties = false;

1191

1192 if (Old.HasSignedObjCClassROs != New.HasSignedObjCClassROs)

1193 New.HasSignedObjCClassROs = false;

1194

1196 dbgs() << "MachOPlatform: Merging __objc_imageinfo flags for "

1198 << formatv("{0:x4}", Old.rawFlags()) << ")"

1199 << " with " << G.getName() << " (" << formatv("{0:x4}", NewFlags)

1200 << ")"

1201 << " -> " << formatv("{0:x4}", New.rawFlags()) << "\n";

1202 });

1203

1204 Info.Flags = New.rawFlags();

1206}

1207

1208Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(

1209 jitlink::LinkGraph &G, JITDylib &JD) {

1210 auto TLVBootStrapSymbolName = G.intern("__tlv_bootstrap");

1211

1212 for (auto *Sym : G.external_symbols())

1213 if (Sym->getName() == TLVBootStrapSymbolName) {

1214 auto TLSGetADDR =

1215 MP.getExecutionSession().intern("___orc_rt_macho_tlv_get_addr");

1216 Sym->setName(std::move(TLSGetADDR));

1217 break;

1218 }

1219

1220

1222 std::optional<uint64_t> Key;

1223 {

1224 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

1225 auto I = MP.JITDylibToPThreadKey.find(&JD);

1226 if (I != MP.JITDylibToPThreadKey.end())

1227 Key = I->second;

1228 }

1229

1230 if (Key) {

1231 if (auto KeyOrErr = MP.createPThreadKey())

1232 Key = *KeyOrErr;

1233 else

1234 return KeyOrErr.takeError();

1235 }

1236

1237 uint64_t PlatformKeyBits =

1239

1240 for (auto *B : ThreadDataSec->blocks()) {

1241 if (B->getSize() != 3 * G.getPointerSize())

1243 formatv("{0:x}", B->getAddress()) +

1244 " has unexpected size",

1246

1247 auto NewBlockContent = G.allocateBuffer(B->getSize());

1248 llvm::copy(B->getContent(), NewBlockContent.data());

1249 memcpy(NewBlockContent.data() + G.getPointerSize(), &PlatformKeyBits,

1250 G.getPointerSize());

1251 B->setContent(NewBlockContent);

1252 }

1253 }

1254

1255

1256 for (auto *B : G.blocks())

1257 for (auto &E : B->edges())

1258 if (E.getKind() ==

1260 E.setKind(jitlink::x86_64::

1261 RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable);

1262

1264}

1265

1266std::optionalMachOPlatform::MachOPlatformPlugin::UnwindSections

1267MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(

1268 jitlink::LinkGraph &G) {

1269 using namespace jitlink;

1270

1271 UnwindSections US;

1272

1273

1274

1276 auto ScanUnwindInfoSection = [&](Section &Sec, ExecutorAddrRange &SecRange,

1277 auto AddCodeBlocks) {

1278 if (Sec.blocks().empty())

1279 return;

1280 SecRange = (*Sec.blocks().begin())->getRange();

1281 for (auto *B : Sec.blocks()) {

1282 auto R = B->getRange();

1283 SecRange.Start = std::min(SecRange.Start, R.Start);

1284 SecRange.End = std::max(SecRange.End, R.End);

1285 AddCodeBlocks(*B);

1286 }

1287 };

1288

1290 ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection, [&](Block &B) {

1291 if (auto *Fn = jitlink::EHFrameCFIBlockInspector::FromEdgeScan(B)

1292 .getPCBeginEdge())

1293 if (Fn->getTarget().isDefined())

1294 CodeBlocks.push_back(&Fn->getTarget().getBlock());

1295 });

1296 }

1297

1299 ScanUnwindInfoSection(

1300 *CUInfoSec, US.CompactUnwindSection, [&](Block &B) {

1301 for (auto &E : B.edges()) {

1302 assert(E.getTarget().isDefined() &&

1303 "unwind-info record edge has external target");

1304 assert(E.getKind() == Edge::KeepAlive &&

1305 "unwind-info record has unexpected edge kind");

1306 CodeBlocks.push_back(&E.getTarget().getBlock());

1307 }

1308 });

1309 }

1310

1311

1312

1313 if (CodeBlocks.empty())

1314 return std::nullopt;

1315

1316

1317

1319 return LHS->getAddress() < RHS->getAddress();

1320 });

1321 for (auto *B : CodeBlocks) {

1322 if (US.CodeRanges.empty() || US.CodeRanges.back().End != B->getAddress())

1323 US.CodeRanges.push_back(B->getRange());

1324 else

1325 US.CodeRanges.back().End = B->getRange().End;

1326 }

1327

1329 dbgs() << "MachOPlatform identified unwind info in " << G.getName() << ":\n"

1330 << " DWARF: ";

1331 if (US.DwarfSection.Start)

1332 dbgs() << US.DwarfSection << "\n";

1333 else

1334 dbgs() << "none\n";

1335 dbgs() << " Compact-unwind: ";

1336 if (US.CompactUnwindSection.Start)

1337 dbgs() << US.CompactUnwindSection << "\n";

1338 else

1339 dbgs() << "none\n"

1340 << "for code ranges:\n";

1341 for (auto &CR : US.CodeRanges)

1342 dbgs() << " " << CR << "\n";

1343 if (US.CodeRanges.size() >= G.sections_size())

1344 dbgs() << "WARNING: High number of discontiguous code ranges! "

1345 "Padding may be interfering with coalescing.\n";

1346 });

1347

1348 return US;

1349}

1350

1351Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(

1353 bool InBootstrapPhase) {

1354

1355

1356

1357 jitlink::Section *ThreadDataSection =

1359

1360

1362

1363

1364

1365 if (ThreadDataSection)

1366 G.mergeSections(*ThreadDataSection, *ThreadBSSSection);

1367 else

1368 ThreadDataSection = ThreadBSSSection;

1369 }

1370

1372

1373

1377 for (auto &SecName : DataSections) {

1378 if (auto *Sec = G.findSectionByName(SecName)) {

1379 jitlink::SectionRange R(*Sec);

1380 if (R.empty())

1381 MachOPlatformSecs.push_back({SecName, R.getRange()});

1382 }

1383 }

1384

1385

1386

1387 if (ThreadDataSection) {

1388 jitlink::SectionRange R(*ThreadDataSection);

1389 if (R.empty())

1391 }

1392

1393

1394

1396 ObjCRuntimeObjectSectionName};

1397

1398 for (auto &SecName : PlatformSections) {

1399 auto *Sec = G.findSectionByName(SecName);

1400 if (!Sec)

1401 continue;

1402 jitlink::SectionRange R(*Sec);

1403 if (R.empty())

1404 continue;

1405

1406 MachOPlatformSecs.push_back({SecName, R.getRange()});

1407 }

1408

1409 std::optional<std::tuple<SmallVector, ExecutorAddrRange,

1410 ExecutorAddrRange>>

1411 UnwindInfo;

1412 if (auto UI = findUnwindSectionInfo(G))

1413 UnwindInfo = std::make_tuple(std::move(UI->CodeRanges), UI->DwarfSection,

1414 UI->CompactUnwindSection);

1415

1416 if (!MachOPlatformSecs.empty() || UnwindInfo) {

1417

1419 dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";

1420 for (auto &KV : MachOPlatformSecs)

1421 dbgs() << " " << KV.first << ": " << KV.second << "\n";

1422 });

1423

1424 assert(HeaderAddr && "Null header registered for JD");

1425 using SPSRegisterObjectPlatformSectionsArgs = SPSArgList<

1426 SPSExecutorAddr,

1427 SPSOptional<SPSTuple<SPSSequence,

1429 SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;

1430

1434 MP.RegisterObjectPlatformSections.Addr, HeaderAddr, UnwindInfo,

1435 MachOPlatformSecs)),

1438 MP.DeregisterObjectPlatformSections.Addr, HeaderAddr,

1439 UnwindInfo, MachOPlatformSecs))};

1440

1442 G.allocActions().push_back(std::move(AllocActions));

1443 else {

1444 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

1445 MP.Bootstrap->DeferredAAs.push_back(std::move(AllocActions));

1446 }

1447 }

1448

1450}

1451

1452Error MachOPlatform::MachOPlatformPlugin::createObjCRuntimeObject(

1453 jitlink::LinkGraph &G) {

1454

1455 bool NeedTextSegment = false;

1456 size_t NumRuntimeSections = 0;

1457

1458 for (auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData)

1459 if (G.findSectionByName(ObjCRuntimeSectionName))

1460 ++NumRuntimeSections;

1461

1462 for (auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {

1463 if (G.findSectionByName(ObjCRuntimeSectionName)) {

1464 ++NumRuntimeSections;

1465 NeedTextSegment = true;

1466 }

1467 }

1468

1469

1470 if (NumRuntimeSections == 0)

1472

1473

1474

1475 ++NumRuntimeSections;

1476

1477 size_t MachOSize = sizeof(MachO::mach_header_64) +

1478 (NeedTextSegment + 1) * sizeof(MachO::segment_command_64) +

1479 NumRuntimeSections * sizeof(MachO::section_64);

1480

1481 auto &Sec = G.createSection(ObjCRuntimeObjectSectionName,

1483 G.createMutableContentBlock(Sec, MachOSize, ExecutorAddr(), 16, 0, true);

1484

1486}

1487

1488Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(

1489 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

1490

1491 auto *ObjCRuntimeObjectSec =

1492 G.findSectionByName(ObjCRuntimeObjectSectionName);

1493

1494 if (!ObjCRuntimeObjectSec)

1496

1497 switch (G.getTargetTriple().getArch()) {

1500

1501 break;

1502 default:

1504 G.getTargetTriple().str(),

1506 }

1507

1508 auto &SecBlock = **ObjCRuntimeObjectSec->blocks().begin();

1509

1510 struct SecDesc {

1511 MachO::section_64 Sec;

1512 unique_function<void(size_t RecordOffset)> AddFixups;

1513 };

1514

1515 std::vector TextSections, DataSections;

1516 auto AddSection = [&](SecDesc &SD, jitlink::Section &GraphSec) {

1517 jitlink::SectionRange SR(GraphSec);

1518 StringRef FQName = GraphSec.getName();

1519 memset(&SD.Sec, 0, sizeof(MachO::section_64));

1520 memcpy(SD.Sec.sectname, FQName.drop_front(7).data(), FQName.size() - 7);

1521 memcpy(SD.Sec.segname, FQName.data(), 6);

1522 SD.Sec.addr = SR.getStart() - SecBlock.getAddress();

1523 SD.Sec.size = SR.getSize();

1525 };

1526

1527

1528 {

1529 DataSections.push_back({});

1530 auto &SD = DataSections.back();

1531 memset(&SD.Sec, 0, sizeof(SD.Sec));

1532 memcpy(SD.Sec.sectname, "__objc_imageinfo", 16);

1533 strcpy(SD.Sec.segname, "__DATA");

1534 SD.Sec.size = 8;

1535 jitlink::Symbol *ObjCImageInfoSym = nullptr;

1536 SD.AddFixups = [&, ObjCImageInfoSym](size_t RecordOffset) mutable {

1537 auto PointerEdge = getPointerEdgeKind(G);

1538

1539

1540 if (!ObjCImageInfoSym) {

1541 auto Name = G.intern(ObjCImageInfoSymbolName);

1542 ObjCImageInfoSym = G.findExternalSymbolByName(Name);

1543 if (!ObjCImageInfoSym)

1544 ObjCImageInfoSym = G.findAbsoluteSymbolByName(Name);

1545 if (!ObjCImageInfoSym) {

1546 ObjCImageInfoSym = G.findDefinedSymbolByName(Name);

1547 if (ObjCImageInfoSym) {

1548 std::optional<uint32_t> Flags;

1549 {

1550 std::lock_guardstd::mutex Lock(PluginMutex);

1552 if (It != ObjCImageInfos.end()) {

1553 It->second.Finalized = true;

1554 Flags = It->second.Flags;

1555 }

1556 }

1557

1558 if (Flags) {

1559

1560

1563 Content.size() == 8 &&

1564 "__objc_image_info size should have been verified already");

1566 }

1567 }

1568 }

1569 if (!ObjCImageInfoSym)

1570 ObjCImageInfoSym = &G.addExternalSymbol(std::move(Name), 8, false);

1571 }

1572

1573 SecBlock.addEdge(PointerEdge,

1574 RecordOffset + ((char *)&SD.Sec.addr - (char *)&SD.Sec),

1575 *ObjCImageInfoSym, -SecBlock.getAddress().getValue());

1576 };

1577 }

1578

1579 for (auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData) {

1580 if (auto *GraphSec = G.findSectionByName(ObjCRuntimeSectionName)) {

1581 DataSections.push_back({});

1582 AddSection(DataSections.back(), *GraphSec);

1583 }

1584 }

1585

1586 for (auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {

1587 if (auto *GraphSec = G.findSectionByName(ObjCRuntimeSectionName)) {

1588 TextSections.push_back({});

1589 AddSection(TextSections.back(), *GraphSec);

1590 }

1591 }

1592

1593 assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&

1594 "Unexpected number of blocks in runtime sections object");

1595

1596

1597

1598 MachO::mach_header_64 Hdr;

1600 switch (G.getTargetTriple().getArch()) {

1604 break;

1608 break;

1609 default:

1611 }

1612

1614 Hdr.ncmds = 1 + !TextSections.empty();

1616 Hdr.ncmds * sizeof(MachO::segment_command_64) +

1617 (TextSections.size() + DataSections.size()) * sizeof(MachO::section_64);

1620

1621 auto SecContent = SecBlock.getAlreadyMutableContent();

1622 char *P = SecContent.data();

1623 auto WriteMachOStruct = [&](auto S) {

1626 memcpy(P, &S, sizeof(S));

1627 P += sizeof(S);

1628 };

1629

1630 auto WriteSegment = [&](StringRef Name, std::vector &Secs) {

1631 MachO::segment_command_64 SegLC;

1632 memset(&SegLC, 0, sizeof(SegLC));

1634 SegLC.cmd = MachO::LC_SEGMENT_64;

1635 SegLC.cmdsize = sizeof(MachO::segment_command_64) +

1636 Secs.size() * sizeof(MachO::section_64);

1637 SegLC.nsects = Secs.size();

1638 WriteMachOStruct(SegLC);

1639 for (auto &SD : Secs) {

1640 if (SD.AddFixups)

1641 SD.AddFixups(P - SecContent.data());

1642 WriteMachOStruct(SD.Sec);

1643 }

1644 };

1645

1646 WriteMachOStruct(Hdr);

1647 if (!TextSections.empty())

1648 WriteSegment("__TEXT", TextSections);

1649 if (!DataSections.empty())

1650 WriteSegment("__DATA", DataSections);

1651

1652 assert(P == SecContent.end() && "Underflow writing ObjC runtime object");

1654}

1655

1656Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(

1657 jitlink::LinkGraph &G, JITSymTabVector &JITSymTabInfo) {

1658

1660 if (!CStringSec)

1663

1664

1665 DenseMap<StringRef, jitlink::Symbol *> ExistingStrings;

1666 for (auto *Sym : CStringSec->symbols()) {

1667

1668

1669

1671 ExistingStrings.insert(

1672 std::make_pair(StringRef(Content.data(), Content.size()), Sym));

1673 }

1674

1675

1676

1677 {

1681

1682 for (auto *Sym : SymsToProcess) {

1684 continue;

1685

1686 auto I = ExistingStrings.find(*Sym->getName());

1687 if (I == ExistingStrings.end()) {

1688 auto &NameBlock = G.createMutableContentBlock(

1689 *CStringSec, G.allocateCString(*Sym->getName()),

1690 orc::ExecutorAddr(), 1, 0);

1691 auto &SymbolNameSym = G.addAnonymousSymbol(

1692 NameBlock, 0, NameBlock.getSize(), false, true);

1693 JITSymTabInfo.push_back({Sym, &SymbolNameSym});

1694 } else

1695 JITSymTabInfo.push_back({Sym, I->second});

1696 }

1697 }

1698

1700}

1701

1702Error MachOPlatform::MachOPlatformPlugin::addSymbolTableRegistration(

1703 jitlink::LinkGraph &G, MaterializationResponsibility &MR,

1704 JITSymTabVector &JITSymTabInfo, bool InBootstrapPhase) {

1705

1706 ExecutorAddr HeaderAddr;

1707 {

1708 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

1710 assert(I != MP.JITDylibToHeaderAddr.end() && "No header registered for JD");

1711 assert(I->second && "Null header registered for JD");

1712 HeaderAddr = I->second;

1713 }

1714

1716

1717

1718

1719 std::lock_guardstd::mutex Lock(MP.PlatformMutex);

1720 auto &SymTab = MP.Bootstrap->SymTab;

1721 for (auto &[OriginalSymbol, NameSym] : JITSymTabInfo)

1722 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),

1723 flagsForSymbol(*OriginalSymbol)});

1725 }

1726

1727 SymbolTableVector SymTab;

1728 for (auto &[OriginalSymbol, NameSym] : JITSymTabInfo)

1729 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),

1730 flagsForSymbol(*OriginalSymbol)});

1731

1732 G.allocActions().push_back(

1734 MP.RegisterObjectSymbolTable.Addr, HeaderAddr, SymTab)),

1736 MP.DeregisterObjectSymbolTable.Addr, HeaderAddr, SymTab))});

1737

1739}

1740

1741template

1746 auto HdrInfo =

1749

1751 B.Header.cputype = HdrInfo.CPUType;

1752 B.Header.cpusubtype = HdrInfo.CPUSubType;

1753

1755 B.template addLoadCommandMachO::LC\_ID\_DYLIB(

1757 Opts.IDDylib->CurrentVersion, Opts.IDDylib->CompatibilityVersion);

1758 else

1759 B.template addLoadCommandMachO::LC\_ID\_DYLIB(JD.getName(), 0, 0, 0);

1760

1762 B.template addLoadCommandMachO::LC\_BUILD\_VERSION(

1763 BV.Platform, BV.MinOS, BV.SDK, static_cast<uint32_t>(0));

1764

1767 switch (LD.K) {

1768 case LoadKind::Default:

1769 B.template addLoadCommandMachO::LC\_LOAD\_DYLIB(

1770 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,

1771 LD.D.CompatibilityVersion);

1772 break;

1773 case LoadKind::Weak:

1774 B.template addLoadCommandMachO::LC\_LOAD\_WEAK\_DYLIB(

1775 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,

1776 LD.D.CompatibilityVersion);

1777 break;

1778 }

1779 }

1780 for (auto &P : Opts.RPaths)

1781 B.template addLoadCommandMachO::LC\_RPATH(P);

1782

1783 auto HeaderContent = G.allocateBuffer(B.layout());

1784 B.write(HeaderContent);

1785

1786 return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,

1787 0);

1788}

1789

1794 createHeaderInterface(MOP, std::move(HeaderStartSymbol))),

1796

1798 std::unique_ptr R) {

1799 auto G = createPlatformGraph(MOP, "");

1800 addMachOHeader(R->getTargetJITDylib(), *G, R->getInitializerSymbol());

1801 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));

1802}

1803

1806

1807void SimpleMachOHeaderMU::addMachOHeader(

1810 auto &HeaderSection = G.createSection("__header", MemProt::Read);

1812

1813

1814 G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol, HeaderBlock.getSize(),

1816 true);

1817 for (auto &HS : AdditionalHeaderSymbols)

1818 G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),

1820 true);

1821}

1822

1826 switch (MOP.getExecutionSession().getTargetTriple().getArch()) {

1829 return ::createHeaderBlock(MOP, Opts, JD, G, HeaderSection);

1830 default:

1832 }

1833}

1834

1838

1840 for (auto &HS : AdditionalHeaderSymbols)

1843

1845 HeaderStartSymbol);

1846}

1847

1849 switch (TT.getArch()) {

1851 return { 16 * 1024,

1855 return { 4 * 1024,

1858 default:

1860 }

1861}

1862

1863}

1864}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Analysis containing CSE Info

#define LLVM_UNLIKELY(EXPR)

#define LLVM_LIKELY(EXPR)

static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")

static StringRef getName(Value *V)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

void reserve(size_type NumEntries)

Grow the densemap so that it can contain at least NumEntries items before resizing again.

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.

void push_back(const T &Elt)

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

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Manages the enabling and disabling of subtarget specific features.

Triple - Helper class for working with autoconf configuration names.

An Addressable with content and edges.

ArrayRef< char > getContent() const

Get the content for this block. Block must not be a zero-fill block.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

MutableArrayRef< char > getMutableContent(LinkGraph &G)

Get mutable content for this block.

const std::string & getName() const

Get the name for this JITLinkDylib.

void removeSection(Section &Sec)

Remove a section.

Section * findSectionByName(StringRef Name)

Returns the section with the given name if it exists, otherwise returns null.

Symbol & addAbsoluteSymbol(orc::SymbolStringPtr Name, orc::ExecutorAddr Address, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)

Add an absolute symbol.

Represents an object file section.

bool isCallable() const

Returns true is this symbol is callable.

void setName(const orc::SymbolStringPtr Name)

Rename this symbol.

const orc::SymbolStringPtr & getName() const

Returns the name of this symbol (empty if the symbol is anonymous).

Linkage getLinkage() const

Get the linkage for this Symbol.

orc::ExecutorAddr getAddress() const

Returns the address of this symbol.

Block & getBlock()

Return the Block for this Symbol (Symbol must be defined).

bool hasName() const

Returns true if this symbol has a name.

An ExecutionSession represents a running JIT program.

const Triple & getTargetTriple() const

Return the triple for the executor.

SymbolStringPtr intern(StringRef SymName)

Add a symbol name to the SymbolStringPool and return a pointer to it.

DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap

A map associating tag names with asynchronous wrapper function implementations in the JIT.

Represents an address in the executor process.

Represents a JIT'd dynamic library.

Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)

Define all symbols provided by the materialization unit to be part of this JITDylib.

Mediates between MachO initialization and ExecutionSession state.

Error teardownJITDylib(JITDylib &JD) override

This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...

Definition MachOPlatform.cpp:353

static ArrayRef< std::pair< const char *, const char * > > standardLazyCompilationAliases()

Returns a list of aliases required to enable lazy compilation via the ORC runtime.

Definition MachOPlatform.cpp:429

Error setupJITDylib(JITDylib &JD) override

This method will be called outside the session lock each time a JITDylib is created (unless it is cre...

Definition MachOPlatform.cpp:342

static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()

Returns the array of standard runtime utility aliases for MachO.

Definition MachOPlatform.cpp:413

std::vector< std::pair< ExecutorAddr, MachOJITDylibDepInfo > > MachOJITDylibDepInfoMap

unique_function< std::unique_ptr< MaterializationUnit >(MachOPlatform &MOP, HeaderOptions Opts)> MachOHeaderMUBuilder

Used by setupJITDylib to create MachO header MaterializationUnits for JITDylibs.

Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override

This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...

Definition MachOPlatform.cpp:366

static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)

Returns an AliasMap containing the default aliases for the MachOPlatform.

Definition MachOPlatform.cpp:396

ExecutionSession & getExecutionSession() const

Error notifyRemoving(ResourceTracker &RT) override

This method will be called under the ExecutionSession lock when a ResourceTracker is removed.

Definition MachOPlatform.cpp:382

static Expected< std::unique_ptr< MachOPlatform > > Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, std::unique_ptr< DefinitionGenerator > OrcRuntime, HeaderOptions PlatformJDOpts={}, MachOHeaderMUBuilder BuildMachOHeaderMU=buildSimpleMachOHeaderMU, std::optional< SymbolAliasMap > RuntimeAliases=std::nullopt)

Try to create a MachOPlatform instance, adding the ORC runtime to the given JITDylib.

Definition MachOPlatform.cpp:280

static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()

Returns the array of required CXX aliases.

Definition MachOPlatform.cpp:405

Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...

Error defineMaterializing(SymbolFlagsMap SymbolFlags)

Attempt to claim responsibility for new definitions.

const SymbolStringPtr & getInitializerSymbol() const

Returns the initialization pseudo-symbol, if any.

JITDylib & getTargetJITDylib() const

Returns the target JITDylib that these symbols are being materialized into.

A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...

MaterializationUnit(Interface I)

virtual StringRef getName() const =0

Return the name of this materialization unit.

const SymbolStringPtr & getInitializerSymbol() const

Returns the initialization symbol for this MaterializationUnit (if any).

An ObjectLayer implementation built on JITLink.

static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)

Performs an async lookup for the given symbols in each of the given JITDylibs, calling the given hand...

API to remove / transfer ownership of JIT resources.

JITDylib & getJITDylib() const

Return the JITDylib targeted by this tracker.

static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName, VisitMembersFunction VisitMembers=VisitMembersFunction(), GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())

Try to create a StaticLibraryDefinitionGenerator from the given path.

Pointer to a pooled string representing a symbol name.

#define llvm_unreachable(msg)

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

@ S_REGULAR

S_REGULAR - Regular section.

void swapStruct(fat_header &mh)

@ Pointer64

A plain 64-bit pointer value relocation.

@ RequestTLVPAndTransformToPCRel32TLVPLoadREXRelaxable

A TLVP entry getter/constructor, transformed to Delta32ToTLVPLoadREXRelaxable.

@ Pointer64

A plain 64-bit pointer value relocation.

LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)

Returns the string name of the given generic edge kind, or "unknown" otherwise.

LLVM_ABI StringRef MachOSwift5EntrySectionName

LLVM_ABI StringRef MachOThreadBSSSectionName

LLVM_ABI StringRef MachOThreadVarsSectionName

JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)

Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...

std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder

A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.

IntrusiveRefCntPtr< JITDylib > JITDylibSP

std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)

Create a ReExportsMaterializationUnit with the given aliases.

std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols)

Create an AbsoluteSymbolsMaterializationUnit with the given symbols.

LLVM_ABI StringRef MachOObjCProtoListSectionName

LLVM_ABI StringRef MachOSwift5ProtosSectionName

LLVM_ABI StringRef MachOEHFrameSectionName

LLVM_ABI StringRef MachOModInitFuncSectionName

LLVM_ABI StringRef MachOObjCConstSectionName

LLVM_ABI StringRef MachODataDataSectionName

LLVM_ABI StringRef MachOCompactUnwindSectionName

LLVM_ABI StringRef MachOSwift5ProtoSectionName

@ MatchExportedSymbolsOnly

static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * > > AL)

LLVM_ABI StringRef MachOObjCCatListSectionName

LLVM_ABI StringRef MachOObjCClassRefsSectionName

LLVM_ABI StringRef MachOObjCDataSectionName

LLVM_ABI StringRef MachOObjCClassNameSectionName

LLVM_ABI StringRef MachOObjCMethNameSectionName

LLVM_ABI StringRef MachOInitSectionNames[22]

LLVM_ABI StringRef MachOObjCClassListSectionName

LLVM_ABI StringRef MachOObjCSelRefsSectionName

LLVM_ABI StringRef MachOSwift5FieldMetadataSectionName

LLVM_ABI StringRef MachOCStringSectionName

LLVM_ABI StringRef MachOObjCMethTypeSectionName

LLVM_ABI StringRef MachOSwift5TypesSectionName

LLVM_ABI StringRef MachOObjCNLCatListSectionName

jitlink::Block & createHeaderBlock(MachOPlatform &MOP, const MachOPlatform::HeaderOptions &Opts, JITDylib &JD, jitlink::LinkGraph &G, jitlink::Section &HeaderSection)

Definition MachOPlatform.cpp:1742

LLVM_ABI StringRef MachOObjCNLClassListSectionName

LLVM_ABI StringRef MachOObjCImageInfoSectionName

LLVM_ABI MachOHeaderInfo getMachOHeaderInfoFromTriple(const Triple &TT)

Definition MachOPlatform.cpp:1848

LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister

This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...

LLVM_ABI StringRef MachOThreadDataSectionName

LLVM_ABI StringRef MachOUnwindInfoSectionName

LLVM_ABI StringRef MachODataCommonSectionName

LLVM_ABI StringRef MachOObjCProtoRefsSectionName

@ Ready

Emitted to memory, but waiting on transitive dependencies.

DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap

A map of Symbols to (Symbol, Flags) pairs.

LLVM_ABI StringRef MachOSwift5TypeRefSectionName

LLVM_ABI StringRef MachOObjCCatList2SectionName

DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap

A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.

LLVM_ABI iterator begin() const

value_type byte_swap(value_type value, endianness endian)

uint32_t read32(const void *P, endianness E)

void write32(void *P, uint32_t V, endianness E)

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::error_code inconvertibleErrorCode()

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

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

FunctionAddr VTableAddr uintptr_t uintptr_t Version

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

OutputIt copy(R &&Range, OutputIt Out)

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

Implement std::hash so that hash_code can be used in STL containers.

LinkGraphPassList PostAllocationPasses

Post-allocation passes.

LinkGraphPassList PostFixupPasses

Post-fixup passes.

LinkGraphPassList PostPrunePasses

Post-prune passes.

LinkGraphPassList PrePrunePasses

Pre-prune passes.

std::vector< ExecutorAddr > DepHeaders