File indexing completed on 2026-05-10 08:43:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
0014 #define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
0015
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/ExecutionEngine/Orc/Core.h"
0018 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
0019 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
0020 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0021
0022 #include <future>
0023 #include <thread>
0024 #include <vector>
0025
0026 namespace llvm {
0027 namespace orc {
0028
0029
0030 class MachOPlatform : public Platform {
0031 public:
0032
0033 struct MachOJITDylibDepInfo {
0034 bool Sealed = false;
0035 std::vector<ExecutorAddr> DepHeaders;
0036 };
0037
0038
0039 using MachOJITDylibDepInfoMap =
0040 std::vector<std::pair<ExecutorAddr, MachOJITDylibDepInfo>>;
0041
0042
0043 enum class MachOExecutorSymbolFlags : uint8_t {
0044 None = 0,
0045 Weak = 1U << 0,
0046 Callable = 1U << 1,
0047 LLVM_MARK_AS_BITMASK_ENUM( Callable)
0048 };
0049
0050
0051
0052 struct HeaderOptions {
0053
0054 struct Dylib {
0055 std::string Name;
0056 uint32_t Timestamp;
0057 uint32_t CurrentVersion;
0058 uint32_t CompatibilityVersion;
0059 };
0060
0061 struct BuildVersionOpts {
0062
0063
0064 static std::optional<BuildVersionOpts>
0065 fromTriple(const Triple &TT, uint32_t MinOS, uint32_t SDK);
0066
0067 uint32_t Platform;
0068 uint32_t MinOS;
0069 uint32_t SDK;
0070 };
0071
0072
0073
0074 std::optional<Dylib> IDDylib;
0075
0076
0077 std::vector<Dylib> LoadDylibs;
0078
0079 std::vector<std::string> RPaths;
0080
0081 std::vector<BuildVersionOpts> BuildVersions;
0082
0083 HeaderOptions() = default;
0084 HeaderOptions(Dylib D) : IDDylib(std::move(D)) {}
0085 };
0086
0087
0088
0089 using MachOHeaderMUBuilder =
0090 unique_function<std::unique_ptr<MaterializationUnit>(MachOPlatform &MOP,
0091 HeaderOptions Opts)>;
0092
0093
0094 static inline std::unique_ptr<MaterializationUnit>
0095 buildSimpleMachOHeaderMU(MachOPlatform &MOP, HeaderOptions Opts);
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static Expected<std::unique_ptr<MachOPlatform>>
0136 Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0137 std::unique_ptr<DefinitionGenerator> OrcRuntime,
0138 HeaderOptions PlatformJDOpts = {},
0139 MachOHeaderMUBuilder BuildMachOHeaderMU = buildSimpleMachOHeaderMU,
0140 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0141
0142
0143 static Expected<std::unique_ptr<MachOPlatform>>
0144 Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0145 const char *OrcRuntimePath, HeaderOptions PlatformJDOpts = {},
0146 MachOHeaderMUBuilder BuildMachOHeaderMU = buildSimpleMachOHeaderMU,
0147 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0148
0149 ExecutionSession &getExecutionSession() const { return ES; }
0150 ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
0151
0152 NonOwningSymbolStringPtr getMachOHeaderStartSymbol() const {
0153 return NonOwningSymbolStringPtr(MachOHeaderStartSymbol);
0154 }
0155
0156 Error setupJITDylib(JITDylib &JD) override;
0157
0158
0159
0160 Error setupJITDylib(JITDylib &JD, HeaderOptions Opts);
0161
0162 Error teardownJITDylib(JITDylib &JD) override;
0163 Error notifyAdding(ResourceTracker &RT,
0164 const MaterializationUnit &MU) override;
0165 Error notifyRemoving(ResourceTracker &RT) override;
0166
0167
0168
0169
0170 static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES);
0171
0172
0173 static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
0174
0175
0176 static ArrayRef<std::pair<const char *, const char *>>
0177 standardRuntimeUtilityAliases();
0178
0179
0180
0181 static ArrayRef<std::pair<const char *, const char *>>
0182 standardLazyCompilationAliases();
0183
0184 private:
0185 using SymbolTableVector = SmallVector<
0186 std::tuple<ExecutorAddr, ExecutorAddr, MachOExecutorSymbolFlags>>;
0187
0188
0189 struct BootstrapInfo {
0190 std::mutex Mutex;
0191 std::condition_variable CV;
0192 size_t ActiveGraphs = 0;
0193 shared::AllocActions DeferredAAs;
0194 ExecutorAddr MachOHeaderAddr;
0195 SymbolTableVector SymTab;
0196 };
0197
0198
0199
0200
0201 class MachOPlatformPlugin : public ObjectLinkingLayer::Plugin {
0202 public:
0203 MachOPlatformPlugin(MachOPlatform &MP) : MP(MP) {}
0204
0205 void modifyPassConfig(MaterializationResponsibility &MR,
0206 jitlink::LinkGraph &G,
0207 jitlink::PassConfiguration &Config) override;
0208
0209
0210
0211 Error notifyFailed(MaterializationResponsibility &MR) override {
0212 return Error::success();
0213 }
0214
0215 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
0216 return Error::success();
0217 }
0218
0219 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
0220 ResourceKey SrcKey) override {}
0221
0222 private:
0223 struct UnwindSections {
0224 SmallVector<ExecutorAddrRange> CodeRanges;
0225 ExecutorAddrRange DwarfSection;
0226 ExecutorAddrRange CompactUnwindSection;
0227 };
0228
0229 struct ObjCImageInfo {
0230 uint32_t Version = 0;
0231 uint32_t Flags = 0;
0232
0233
0234 bool Finalized = false;
0235 };
0236
0237 struct SymbolTablePair {
0238 jitlink::Symbol *OriginalSym = nullptr;
0239 jitlink::Symbol *NameSym = nullptr;
0240 };
0241 using JITSymTabVector = SmallVector<SymbolTablePair>;
0242
0243 Error bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G);
0244 Error bootstrapPipelineEnd(jitlink::LinkGraph &G);
0245
0246 Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
0247 MaterializationResponsibility &MR);
0248
0249 Error preserveImportantSections(jitlink::LinkGraph &G,
0250 MaterializationResponsibility &MR);
0251
0252 Error processObjCImageInfo(jitlink::LinkGraph &G,
0253 MaterializationResponsibility &MR);
0254 Error mergeImageInfoFlags(jitlink::LinkGraph &G,
0255 MaterializationResponsibility &MR,
0256 ObjCImageInfo &Info, uint32_t NewFlags);
0257
0258 Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
0259
0260 std::optional<UnwindSections> findUnwindSectionInfo(jitlink::LinkGraph &G);
0261 Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD,
0262 ExecutorAddr HeaderAddr,
0263 bool InBootstrapPhase);
0264
0265 Error createObjCRuntimeObject(jitlink::LinkGraph &G);
0266 Error populateObjCRuntimeObject(jitlink::LinkGraph &G,
0267 MaterializationResponsibility &MR);
0268
0269 Error prepareSymbolTableRegistration(jitlink::LinkGraph &G,
0270 JITSymTabVector &JITSymTabInfo);
0271 Error addSymbolTableRegistration(jitlink::LinkGraph &G,
0272 MaterializationResponsibility &MR,
0273 JITSymTabVector &JITSymTabInfo,
0274 bool InBootstrapPhase);
0275
0276 std::mutex PluginMutex;
0277 MachOPlatform &MP;
0278
0279
0280
0281 DenseMap<JITDylib *, ObjCImageInfo> ObjCImageInfos;
0282 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
0283 };
0284
0285 using GetJITDylibHeaderSendResultFn =
0286 unique_function<void(Expected<ExecutorAddr>)>;
0287 using GetJITDylibNameSendResultFn =
0288 unique_function<void(Expected<StringRef>)>;
0289 using PushInitializersSendResultFn =
0290 unique_function<void(Expected<MachOJITDylibDepInfoMap>)>;
0291 using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
0292 using PushSymbolsInSendResultFn = unique_function<void(Error)>;
0293
0294 static bool supportedTarget(const Triple &TT);
0295
0296 static jitlink::Edge::Kind getPointerEdgeKind(jitlink::LinkGraph &G);
0297
0298 static MachOExecutorSymbolFlags flagsForSymbol(jitlink::Symbol &Sym);
0299
0300 MachOPlatform(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0301 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
0302 HeaderOptions PlatformJDOpts,
0303 MachOHeaderMUBuilder BuildMachOHeaderMU, Error &Err);
0304
0305
0306 Error associateRuntimeSupportFunctions();
0307
0308
0309
0310
0311 void pushInitializersLoop(PushInitializersSendResultFn SendResult,
0312 JITDylibSP JD);
0313
0314
0315 void rt_pushInitializers(PushInitializersSendResultFn SendResult,
0316 ExecutorAddr JDHeaderAddr);
0317
0318
0319
0320
0321
0322 void rt_pushSymbols(PushSymbolsInSendResultFn SendResult, ExecutorAddr Handle,
0323 const std::vector<std::pair<StringRef, bool>> &Symbols);
0324
0325
0326 Expected<uint64_t> createPThreadKey();
0327
0328 ExecutionSession &ES;
0329 JITDylib &PlatformJD;
0330 ObjectLinkingLayer &ObjLinkingLayer;
0331 MachOHeaderMUBuilder BuildMachOHeaderMU;
0332
0333 SymbolStringPtr MachOHeaderStartSymbol = ES.intern("___dso_handle");
0334
0335 struct RuntimeFunction {
0336 RuntimeFunction(SymbolStringPtr Name) : Name(std::move(Name)) {}
0337 SymbolStringPtr Name;
0338 ExecutorAddr Addr;
0339 };
0340
0341 RuntimeFunction PlatformBootstrap{
0342 ES.intern("___orc_rt_macho_platform_bootstrap")};
0343 RuntimeFunction PlatformShutdown{
0344 ES.intern("___orc_rt_macho_platform_shutdown")};
0345 RuntimeFunction RegisterEHFrameSection{
0346 ES.intern("___orc_rt_macho_register_ehframe_section")};
0347 RuntimeFunction DeregisterEHFrameSection{
0348 ES.intern("___orc_rt_macho_deregister_ehframe_section")};
0349 RuntimeFunction RegisterJITDylib{
0350 ES.intern("___orc_rt_macho_register_jitdylib")};
0351 RuntimeFunction DeregisterJITDylib{
0352 ES.intern("___orc_rt_macho_deregister_jitdylib")};
0353 RuntimeFunction RegisterObjectSymbolTable{
0354 ES.intern("___orc_rt_macho_register_object_symbol_table")};
0355 RuntimeFunction DeregisterObjectSymbolTable{
0356 ES.intern("___orc_rt_macho_deregister_object_symbol_table")};
0357 RuntimeFunction RegisterObjectPlatformSections{
0358 ES.intern("___orc_rt_macho_register_object_platform_sections")};
0359 RuntimeFunction DeregisterObjectPlatformSections{
0360 ES.intern("___orc_rt_macho_deregister_object_platform_sections")};
0361 RuntimeFunction CreatePThreadKey{
0362 ES.intern("___orc_rt_macho_create_pthread_key")};
0363 RuntimeFunction RegisterObjCRuntimeObject{
0364 ES.intern("___orc_rt_macho_register_objc_runtime_object")};
0365 RuntimeFunction DeregisterObjCRuntimeObject{
0366 ES.intern("___orc_rt_macho_deregister_objc_runtime_object")};
0367
0368 DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
0369
0370 std::mutex PlatformMutex;
0371 bool ForceEHFrames = false;
0372 BootstrapInfo *Bootstrap = nullptr;
0373 DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
0374 DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
0375 DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
0376 };
0377
0378
0379 class SimpleMachOHeaderMU : public MaterializationUnit {
0380 public:
0381 SimpleMachOHeaderMU(MachOPlatform &MOP, SymbolStringPtr HeaderStartSymbol,
0382 MachOPlatform::HeaderOptions Opts);
0383 StringRef getName() const override { return "MachOHeaderMU"; }
0384 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
0385 void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override;
0386
0387 protected:
0388 virtual jitlink::Block &createHeaderBlock(JITDylib &JD, jitlink::LinkGraph &G,
0389 jitlink::Section &HeaderSection);
0390
0391 MachOPlatform &MOP;
0392 MachOPlatform::HeaderOptions Opts;
0393
0394 private:
0395 struct HeaderSymbol {
0396 const char *Name;
0397 uint64_t Offset;
0398 };
0399
0400 static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
0401 {"___mh_executable_header", 0}};
0402
0403 void addMachOHeader(JITDylib &JD, jitlink::LinkGraph &G,
0404 const SymbolStringPtr &InitializerSymbol);
0405 static MaterializationUnit::Interface
0406 createHeaderInterface(MachOPlatform &MOP,
0407 const SymbolStringPtr &HeaderStartSymbol);
0408 };
0409
0410
0411 inline std::unique_ptr<MaterializationUnit>
0412 MachOPlatform::buildSimpleMachOHeaderMU(MachOPlatform &MOP,
0413 HeaderOptions Opts) {
0414 return std::make_unique<SimpleMachOHeaderMU>(MOP, MOP.MachOHeaderStartSymbol,
0415 std::move(Opts));
0416 }
0417
0418 struct MachOHeaderInfo {
0419 size_t PageSize = 0;
0420 uint32_t CPUType = 0;
0421 uint32_t CPUSubType = 0;
0422 };
0423 MachOHeaderInfo getMachOHeaderInfoFromTriple(const Triple &TT);
0424
0425 }
0426 }
0427
0428 #endif