MachOPlatform.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Utilities for executing JIT'd MachO in Orc.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  18. #define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  19. #include "llvm/ADT/StringRef.h"
  20. #include "llvm/ExecutionEngine/Orc/Core.h"
  21. #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
  22. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  23. #include <future>
  24. #include <thread>
  25. #include <vector>
  26. namespace llvm {
  27. namespace orc {
  28. /// Enable registration of JIT'd ObjC classes and selectors.
  29. Error enableObjCRegistration(const char *PathToLibObjC);
  30. bool objCRegistrationEnabled();
  31. class MachOJITDylibInitializers {
  32. public:
  33. struct SectionExtent {
  34. SectionExtent() = default;
  35. SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
  36. : Address(Address), NumPtrs(NumPtrs) {}
  37. JITTargetAddress Address = 0;
  38. uint64_t NumPtrs = 0;
  39. };
  40. using RawPointerSectionList = std::vector<SectionExtent>;
  41. void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
  42. this->ObjCImageInfoAddr = ObjCImageInfoAddr;
  43. }
  44. void addModInitsSection(SectionExtent ModInit) {
  45. ModInitSections.push_back(std::move(ModInit));
  46. }
  47. const RawPointerSectionList &getModInitsSections() const {
  48. return ModInitSections;
  49. }
  50. void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
  51. ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
  52. }
  53. const RawPointerSectionList &getObjCSelRefsSections() const {
  54. return ObjCSelRefsSections;
  55. }
  56. void addObjCClassListSection(SectionExtent ObjCClassList) {
  57. ObjCClassListSections.push_back(std::move(ObjCClassList));
  58. }
  59. const RawPointerSectionList &getObjCClassListSections() const {
  60. return ObjCClassListSections;
  61. }
  62. void runModInits() const;
  63. void registerObjCSelectors() const;
  64. Error registerObjCClasses() const;
  65. private:
  66. JITTargetAddress ObjCImageInfoAddr;
  67. RawPointerSectionList ModInitSections;
  68. RawPointerSectionList ObjCSelRefsSections;
  69. RawPointerSectionList ObjCClassListSections;
  70. };
  71. class MachOJITDylibDeinitializers {};
  72. /// Mediates between MachO initialization and ExecutionSession state.
  73. class MachOPlatform : public Platform {
  74. public:
  75. using InitializerSequence =
  76. std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
  77. using DeinitializerSequence =
  78. std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
  79. MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
  80. std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
  81. ExecutionSession &getExecutionSession() const { return ES; }
  82. Error setupJITDylib(JITDylib &JD) override;
  83. Error notifyAdding(ResourceTracker &RT,
  84. const MaterializationUnit &MU) override;
  85. Error notifyRemoving(ResourceTracker &RT) override;
  86. Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
  87. Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
  88. private:
  89. // This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,
  90. // __objc_classlist and __sel_ref sections and records their extents so that
  91. // they can be run in the target process.
  92. class InitScraperPlugin : public ObjectLinkingLayer::Plugin {
  93. public:
  94. InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
  95. void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
  96. jitlink::PassConfiguration &Config) override;
  97. LocalDependenciesMap getSyntheticSymbolLocalDependencies(
  98. MaterializationResponsibility &MR) override;
  99. // FIXME: We should be tentatively tracking scraped sections and discarding
  100. // if the MR fails.
  101. Error notifyFailed(MaterializationResponsibility &MR) override {
  102. return Error::success();
  103. }
  104. Error notifyRemovingResources(ResourceKey K) override {
  105. return Error::success();
  106. }
  107. void notifyTransferringResources(ResourceKey DstKey,
  108. ResourceKey SrcKey) override {}
  109. private:
  110. using InitSymbolDepMap =
  111. DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
  112. void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
  113. jitlink::LinkGraph &G,
  114. StringRef SectionName);
  115. Error processObjCImageInfo(jitlink::LinkGraph &G,
  116. MaterializationResponsibility &MR);
  117. std::mutex InitScraperMutex;
  118. MachOPlatform &MP;
  119. DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
  120. InitSymbolDepMap InitSymbolDeps;
  121. };
  122. void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
  123. MachOJITDylibInitializers::SectionExtent ModInits,
  124. MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
  125. MachOJITDylibInitializers::SectionExtent ObjCClassList);
  126. ExecutionSession &ES;
  127. ObjectLinkingLayer &ObjLinkingLayer;
  128. std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
  129. DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
  130. // InitSeqs gets its own mutex to avoid locking the whole session when
  131. // aggregating data from the jitlink.
  132. std::mutex InitSeqsMutex;
  133. DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
  134. };
  135. } // end namespace orc
  136. } // end namespace llvm
  137. #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  138. #ifdef __GNUC__
  139. #pragma GCC diagnostic pop
  140. #endif