File indexing completed on 2026-05-10 08:43:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
0014 #define LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_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 <unordered_map>
0025 #include <vector>
0026
0027 namespace llvm {
0028 namespace orc {
0029
0030 struct ELFPerObjectSectionsToRegister {
0031 ExecutorAddrRange EHFrameSection;
0032 ExecutorAddrRange ThreadDataSection;
0033 };
0034
0035 using ELFNixJITDylibDepInfo = std::vector<ExecutorAddr>;
0036 using ELFNixJITDylibDepInfoMap =
0037 std::vector<std::pair<ExecutorAddr, ELFNixJITDylibDepInfo>>;
0038
0039 struct RuntimeFunction {
0040 RuntimeFunction(SymbolStringPtr Name) : Name(std::move(Name)) {}
0041 SymbolStringPtr Name;
0042 ExecutorAddr Addr;
0043 };
0044
0045 struct FunctionPairKeyHash {
0046 std::size_t
0047 operator()(const std::pair<RuntimeFunction *, RuntimeFunction *> &key) const {
0048 return std::hash<void *>()(key.first->Addr.toPtr<void *>()) ^
0049 std::hash<void *>()(key.second->Addr.toPtr<void *>());
0050 }
0051 };
0052
0053 struct FunctionPairKeyEqual {
0054 std::size_t
0055 operator()(const std::pair<RuntimeFunction *, RuntimeFunction *> &lhs,
0056 const std::pair<RuntimeFunction *, RuntimeFunction *> &rhs) const {
0057 return lhs.first == rhs.first && lhs.second == rhs.second;
0058 }
0059 };
0060
0061 using DeferredRuntimeFnMap = std::unordered_map<
0062 std::pair<RuntimeFunction *, RuntimeFunction *>,
0063 SmallVector<std::pair<shared::WrapperFunctionCall::ArgDataBufferType,
0064 shared::WrapperFunctionCall::ArgDataBufferType>>,
0065 FunctionPairKeyHash, FunctionPairKeyEqual>;
0066
0067
0068 class ELFNixPlatform : public Platform {
0069 public:
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 static Expected<std::unique_ptr<ELFNixPlatform>>
0109 Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0110 std::unique_ptr<DefinitionGenerator> OrcRuntime,
0111 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0112
0113
0114 static Expected<std::unique_ptr<ELFNixPlatform>>
0115 Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0116 const char *OrcRuntimePath,
0117 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0118
0119 ExecutionSession &getExecutionSession() const { return ES; }
0120 ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
0121
0122 Error setupJITDylib(JITDylib &JD) override;
0123 Error teardownJITDylib(JITDylib &JD) override;
0124 Error notifyAdding(ResourceTracker &RT,
0125 const MaterializationUnit &MU) override;
0126 Error notifyRemoving(ResourceTracker &RT) override;
0127
0128
0129
0130
0131 static Expected<SymbolAliasMap> standardPlatformAliases(ExecutionSession &ES,
0132 JITDylib &PlatformJD);
0133
0134
0135 static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
0136
0137
0138 static ArrayRef<std::pair<const char *, const char *>>
0139 standardRuntimeUtilityAliases();
0140
0141
0142
0143 static ArrayRef<std::pair<const char *, const char *>>
0144 standardLazyCompilationAliases();
0145
0146 private:
0147
0148 struct BootstrapInfo {
0149 std::mutex Mutex;
0150 std::condition_variable CV;
0151 size_t ActiveGraphs = 0;
0152 ExecutorAddr ELFNixHeaderAddr;
0153 DeferredRuntimeFnMap DeferredRTFnMap;
0154
0155 void addArgumentsToRTFnMap(
0156 RuntimeFunction *func1, RuntimeFunction *func2,
0157 const shared::WrapperFunctionCall::ArgDataBufferType &arg1,
0158 const shared::WrapperFunctionCall::ArgDataBufferType &arg2) {
0159 std::lock_guard<std::mutex> Lock(Mutex);
0160 auto &argList = DeferredRTFnMap[std::make_pair(func1, func2)];
0161 argList.emplace_back(arg1, arg2);
0162 }
0163 };
0164
0165
0166
0167
0168 class ELFNixPlatformPlugin : public ObjectLinkingLayer::Plugin {
0169 public:
0170 ELFNixPlatformPlugin(ELFNixPlatform &MP) : MP(MP) {}
0171
0172 void modifyPassConfig(MaterializationResponsibility &MR,
0173 jitlink::LinkGraph &G,
0174 jitlink::PassConfiguration &Config) override;
0175
0176
0177
0178 Error notifyFailed(MaterializationResponsibility &MR) override {
0179 return Error::success();
0180 }
0181
0182 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
0183 return Error::success();
0184 }
0185
0186 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
0187 ResourceKey SrcKey) override {}
0188
0189 private:
0190 Error bootstrapPipelineStart(jitlink::LinkGraph &G);
0191 Error bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G);
0192 Error bootstrapPipelineEnd(jitlink::LinkGraph &G);
0193
0194 void addDSOHandleSupportPasses(MaterializationResponsibility &MR,
0195 jitlink::PassConfiguration &Config);
0196
0197 void addEHAndTLVSupportPasses(MaterializationResponsibility &MR,
0198 jitlink::PassConfiguration &Config,
0199 bool IsBootstrapping);
0200
0201 Error preserveInitSections(jitlink::LinkGraph &G,
0202 MaterializationResponsibility &MR);
0203
0204 Error registerInitSections(jitlink::LinkGraph &G, JITDylib &JD,
0205 bool IsBootstrapping);
0206
0207 Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
0208
0209 std::mutex PluginMutex;
0210 ELFNixPlatform &MP;
0211 };
0212
0213 using PushInitializersSendResultFn =
0214 unique_function<void(Expected<ELFNixJITDylibDepInfoMap>)>;
0215
0216 using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
0217
0218 static bool supportedTarget(const Triple &TT);
0219
0220 ELFNixPlatform(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0221 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
0222 Error &Err);
0223
0224
0225 Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
0226
0227 void pushInitializersLoop(PushInitializersSendResultFn SendResult,
0228 JITDylibSP JD);
0229
0230 void rt_recordInitializers(PushInitializersSendResultFn SendResult,
0231 ExecutorAddr JDHeader);
0232
0233 void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
0234 StringRef SymbolName);
0235
0236 Error registerPerObjectSections(jitlink::LinkGraph &G,
0237 const ELFPerObjectSectionsToRegister &POSR,
0238 bool IsBootstrapping);
0239
0240 Expected<uint64_t> createPThreadKey();
0241
0242 ExecutionSession &ES;
0243 JITDylib &PlatformJD;
0244 ObjectLinkingLayer &ObjLinkingLayer;
0245
0246 SymbolStringPtr DSOHandleSymbol;
0247
0248 RuntimeFunction PlatformBootstrap{
0249 ES.intern("__orc_rt_elfnix_platform_bootstrap")};
0250 RuntimeFunction PlatformShutdown{
0251 ES.intern("__orc_rt_elfnix_platform_shutdown")};
0252 RuntimeFunction RegisterJITDylib{
0253 ES.intern("__orc_rt_elfnix_register_jitdylib")};
0254 RuntimeFunction DeregisterJITDylib{
0255 ES.intern("__orc_rt_elfnix_deregister_jitdylib")};
0256 RuntimeFunction RegisterObjectSections{
0257 ES.intern("__orc_rt_elfnix_register_object_sections")};
0258 RuntimeFunction DeregisterObjectSections{
0259 ES.intern("__orc_rt_elfnix_deregister_object_sections")};
0260 RuntimeFunction RegisterInitSections{
0261 ES.intern("__orc_rt_elfnix_register_init_sections")};
0262 RuntimeFunction DeregisterInitSections{
0263 ES.intern("__orc_rt_elfnix_deregister_init_sections")};
0264 RuntimeFunction CreatePThreadKey{
0265 ES.intern("__orc_rt_elfnix_create_pthread_key")};
0266
0267 DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
0268
0269
0270
0271 std::mutex PlatformMutex;
0272 std::vector<ELFPerObjectSectionsToRegister> BootstrapPOSRs;
0273
0274 DenseMap<ExecutorAddr, JITDylib *> HandleAddrToJITDylib;
0275 DenseMap<JITDylib *, ExecutorAddr> JITDylibToHandleAddr;
0276 DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
0277
0278 std::atomic<BootstrapInfo *> Bootstrap;
0279 };
0280
0281 namespace shared {
0282
0283 using SPSELFPerObjectSectionsToRegister =
0284 SPSTuple<SPSExecutorAddrRange, SPSExecutorAddrRange>;
0285
0286 template <>
0287 class SPSSerializationTraits<SPSELFPerObjectSectionsToRegister,
0288 ELFPerObjectSectionsToRegister> {
0289
0290 public:
0291 static size_t size(const ELFPerObjectSectionsToRegister &MOPOSR) {
0292 return SPSELFPerObjectSectionsToRegister::AsArgList::size(
0293 MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
0294 }
0295
0296 static bool serialize(SPSOutputBuffer &OB,
0297 const ELFPerObjectSectionsToRegister &MOPOSR) {
0298 return SPSELFPerObjectSectionsToRegister::AsArgList::serialize(
0299 OB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
0300 }
0301
0302 static bool deserialize(SPSInputBuffer &IB,
0303 ELFPerObjectSectionsToRegister &MOPOSR) {
0304 return SPSELFPerObjectSectionsToRegister::AsArgList::deserialize(
0305 IB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
0306 }
0307 };
0308
0309 using SPSELFNixJITDylibDepInfoMap =
0310 SPSSequence<SPSTuple<SPSExecutorAddr, SPSSequence<SPSExecutorAddr>>>;
0311
0312 }
0313 }
0314 }
0315
0316 #endif