1f597ce03SSahilPatidar //===------ ELFNixPlatform.cpp - Utilities for executing ELFNix in Orc 2f597ce03SSahilPatidar //-----===// 3b749ef9eSLang Hames // 4b749ef9eSLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5b749ef9eSLang Hames // See https://llvm.org/LICENSE.txt for license information. 6b749ef9eSLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7b749ef9eSLang Hames // 8b749ef9eSLang Hames //===----------------------------------------------------------------------===// 9b749ef9eSLang Hames 10b749ef9eSLang Hames #include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h" 11b749ef9eSLang Hames 12e093e421SSunho Kim #include "llvm/ExecutionEngine/JITLink/aarch64.h" 13*79231a86SAmi-zhang #include "llvm/ExecutionEngine/JITLink/loongarch.h" 145cb2a78aSKai Luo #include "llvm/ExecutionEngine/JITLink/ppc64.h" 15b749ef9eSLang Hames #include "llvm/ExecutionEngine/JITLink/x86_64.h" 16dc11c060SLang Hames #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" 17b749ef9eSLang Hames #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 183d4e9d5eSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h" 19b749ef9eSLang Hames #include "llvm/Support/Debug.h" 206698a2b6SKazu Hirata #include <optional> 21b749ef9eSLang Hames 22b749ef9eSLang Hames #define DEBUG_TYPE "orc" 23b749ef9eSLang Hames 24b749ef9eSLang Hames using namespace llvm; 25b749ef9eSLang Hames using namespace llvm::orc; 26b749ef9eSLang Hames using namespace llvm::orc::shared; 27b749ef9eSLang Hames 28b749ef9eSLang Hames namespace { 29b749ef9eSLang Hames 30f597ce03SSahilPatidar template <typename SPSSerializer, typename... ArgTs> 31f597ce03SSahilPatidar shared::WrapperFunctionCall::ArgDataBufferType 32f597ce03SSahilPatidar getArgDataBufferType(const ArgTs &...Args) { 33f597ce03SSahilPatidar shared::WrapperFunctionCall::ArgDataBufferType ArgData; 34f597ce03SSahilPatidar ArgData.resize(SPSSerializer::size(Args...)); 35f597ce03SSahilPatidar SPSOutputBuffer OB(ArgData.empty() ? nullptr : ArgData.data(), 36f597ce03SSahilPatidar ArgData.size()); 37f597ce03SSahilPatidar if (SPSSerializer::serialize(OB, Args...)) 38f597ce03SSahilPatidar return ArgData; 39f597ce03SSahilPatidar return {}; 40f597ce03SSahilPatidar } 41f597ce03SSahilPatidar 42f597ce03SSahilPatidar std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(ELFNixPlatform &MOP, 43f597ce03SSahilPatidar std::string Name) { 444eaff6c5SLang Hames auto &ES = MOP.getExecutionSession(); 452ccf7ed2SJared Wyles return std::make_unique<jitlink::LinkGraph>( 464eaff6c5SLang Hames std::move(Name), ES.getSymbolStringPool(), ES.getTargetTriple(), 474eaff6c5SLang Hames SubtargetFeatures(), jitlink::getGenericEdgeKindName); 48f597ce03SSahilPatidar } 49f597ce03SSahilPatidar 50f597ce03SSahilPatidar // Creates a Bootstrap-Complete LinkGraph to run deferred actions. 51f597ce03SSahilPatidar class ELFNixPlatformCompleteBootstrapMaterializationUnit 52f597ce03SSahilPatidar : public MaterializationUnit { 53f597ce03SSahilPatidar public: 54f597ce03SSahilPatidar ELFNixPlatformCompleteBootstrapMaterializationUnit( 55f597ce03SSahilPatidar ELFNixPlatform &MOP, StringRef PlatformJDName, 56f597ce03SSahilPatidar SymbolStringPtr CompleteBootstrapSymbol, DeferredRuntimeFnMap DeferredAAs, 57f597ce03SSahilPatidar ExecutorAddr ELFNixHeaderAddr, ExecutorAddr PlatformBootstrap, 58f597ce03SSahilPatidar ExecutorAddr PlatformShutdown, ExecutorAddr RegisterJITDylib, 59f597ce03SSahilPatidar ExecutorAddr DeregisterJITDylib) 60f597ce03SSahilPatidar : MaterializationUnit( 61f597ce03SSahilPatidar {{{CompleteBootstrapSymbol, JITSymbolFlags::None}}, nullptr}), 62f597ce03SSahilPatidar MOP(MOP), PlatformJDName(PlatformJDName), 63f597ce03SSahilPatidar CompleteBootstrapSymbol(std::move(CompleteBootstrapSymbol)), 64f597ce03SSahilPatidar DeferredAAsMap(std::move(DeferredAAs)), 65f597ce03SSahilPatidar ELFNixHeaderAddr(ELFNixHeaderAddr), 66f597ce03SSahilPatidar PlatformBootstrap(PlatformBootstrap), 67f597ce03SSahilPatidar PlatformShutdown(PlatformShutdown), RegisterJITDylib(RegisterJITDylib), 68f597ce03SSahilPatidar DeregisterJITDylib(DeregisterJITDylib) {} 69f597ce03SSahilPatidar 70f597ce03SSahilPatidar StringRef getName() const override { 71f597ce03SSahilPatidar return "ELFNixPlatformCompleteBootstrap"; 72f597ce03SSahilPatidar } 73f597ce03SSahilPatidar 74f597ce03SSahilPatidar void materialize(std::unique_ptr<MaterializationResponsibility> R) override { 75f597ce03SSahilPatidar using namespace jitlink; 76f597ce03SSahilPatidar auto G = createPlatformGraph(MOP, "<OrcRTCompleteBootstrap>"); 77f597ce03SSahilPatidar auto &PlaceholderSection = 78f597ce03SSahilPatidar G->createSection("__orc_rt_cplt_bs", MemProt::Read); 79f597ce03SSahilPatidar auto &PlaceholderBlock = 80f597ce03SSahilPatidar G->createZeroFillBlock(PlaceholderSection, 1, ExecutorAddr(), 1, 0); 81f597ce03SSahilPatidar G->addDefinedSymbol(PlaceholderBlock, 0, *CompleteBootstrapSymbol, 1, 82f597ce03SSahilPatidar Linkage::Strong, Scope::Hidden, false, true); 83f597ce03SSahilPatidar 84f597ce03SSahilPatidar // 1. Bootstrap the platform support code. 85f597ce03SSahilPatidar G->allocActions().push_back( 86f597ce03SSahilPatidar {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>( 87f597ce03SSahilPatidar PlatformBootstrap, ELFNixHeaderAddr)), 88f597ce03SSahilPatidar cantFail( 89f597ce03SSahilPatidar WrapperFunctionCall::Create<SPSArgList<>>(PlatformShutdown))}); 90f597ce03SSahilPatidar 91f597ce03SSahilPatidar // 2. Register the platform JITDylib. 92f597ce03SSahilPatidar G->allocActions().push_back( 93f597ce03SSahilPatidar {cantFail(WrapperFunctionCall::Create< 94f597ce03SSahilPatidar SPSArgList<SPSString, SPSExecutorAddr>>( 95f597ce03SSahilPatidar RegisterJITDylib, PlatformJDName, ELFNixHeaderAddr)), 96f597ce03SSahilPatidar cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>( 97f597ce03SSahilPatidar DeregisterJITDylib, ELFNixHeaderAddr))}); 98f597ce03SSahilPatidar 99f597ce03SSahilPatidar // 4. Add the deferred actions to the graph. 100f597ce03SSahilPatidar for (auto &[Fn, CallDatas] : DeferredAAsMap) { 101f597ce03SSahilPatidar for (auto &CallData : CallDatas) { 102f597ce03SSahilPatidar G->allocActions().push_back( 103f597ce03SSahilPatidar {WrapperFunctionCall(Fn.first->Addr, std::move(CallData.first)), 104f597ce03SSahilPatidar WrapperFunctionCall(Fn.second->Addr, std::move(CallData.second))}); 105f597ce03SSahilPatidar } 106f597ce03SSahilPatidar } 107f597ce03SSahilPatidar 108f597ce03SSahilPatidar MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G)); 109f597ce03SSahilPatidar } 110f597ce03SSahilPatidar 111f597ce03SSahilPatidar void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {} 112f597ce03SSahilPatidar 113f597ce03SSahilPatidar private: 114f597ce03SSahilPatidar ELFNixPlatform &MOP; 115f597ce03SSahilPatidar StringRef PlatformJDName; 116f597ce03SSahilPatidar SymbolStringPtr CompleteBootstrapSymbol; 117f597ce03SSahilPatidar DeferredRuntimeFnMap DeferredAAsMap; 118f597ce03SSahilPatidar ExecutorAddr ELFNixHeaderAddr; 119f597ce03SSahilPatidar ExecutorAddr PlatformBootstrap; 120f597ce03SSahilPatidar ExecutorAddr PlatformShutdown; 121f597ce03SSahilPatidar ExecutorAddr RegisterJITDylib; 122f597ce03SSahilPatidar ExecutorAddr DeregisterJITDylib; 123f597ce03SSahilPatidar }; 124f597ce03SSahilPatidar 125b749ef9eSLang Hames class DSOHandleMaterializationUnit : public MaterializationUnit { 126b749ef9eSLang Hames public: 127b749ef9eSLang Hames DSOHandleMaterializationUnit(ELFNixPlatform &ENP, 128b749ef9eSLang Hames const SymbolStringPtr &DSOHandleSymbol) 129ae73f3fdSLang Hames : MaterializationUnit( 130ae73f3fdSLang Hames createDSOHandleSectionInterface(ENP, DSOHandleSymbol)), 131b749ef9eSLang Hames ENP(ENP) {} 132b749ef9eSLang Hames 133b749ef9eSLang Hames StringRef getName() const override { return "DSOHandleMU"; } 134b749ef9eSLang Hames 135b749ef9eSLang Hames void materialize(std::unique_ptr<MaterializationResponsibility> R) override { 136b749ef9eSLang Hames 1374eaff6c5SLang Hames auto &ES = ENP.getExecutionSession(); 1384eaff6c5SLang Hames 1394eaff6c5SLang Hames jitlink::Edge::Kind EdgeKind; 1404eaff6c5SLang Hames 1414eaff6c5SLang Hames switch (ES.getTargetTriple().getArch()) { 142b749ef9eSLang Hames case Triple::x86_64: 143b749ef9eSLang Hames EdgeKind = jitlink::x86_64::Pointer64; 144b749ef9eSLang Hames break; 145e093e421SSunho Kim case Triple::aarch64: 146e093e421SSunho Kim EdgeKind = jitlink::aarch64::Pointer64; 147e093e421SSunho Kim break; 1485cb2a78aSKai Luo case Triple::ppc64: 1495cb2a78aSKai Luo EdgeKind = jitlink::ppc64::Pointer64; 1505cb2a78aSKai Luo break; 1515cb2a78aSKai Luo case Triple::ppc64le: 1525cb2a78aSKai Luo EdgeKind = jitlink::ppc64::Pointer64; 1535cb2a78aSKai Luo break; 154*79231a86SAmi-zhang case Triple::loongarch64: 155*79231a86SAmi-zhang EdgeKind = jitlink::loongarch::Pointer64; 156*79231a86SAmi-zhang break; 157b749ef9eSLang Hames default: 158b749ef9eSLang Hames llvm_unreachable("Unrecognized architecture"); 159b749ef9eSLang Hames } 160b749ef9eSLang Hames 161b749ef9eSLang Hames // void *__dso_handle = &__dso_handle; 162b749ef9eSLang Hames auto G = std::make_unique<jitlink::LinkGraph>( 1634eaff6c5SLang Hames "<DSOHandleMU>", ES.getSymbolStringPool(), ES.getTargetTriple(), 1644eaff6c5SLang Hames SubtargetFeatures(), jitlink::getGenericEdgeKindName); 165b749ef9eSLang Hames auto &DSOHandleSection = 166d3d9f7caSLang Hames G->createSection(".data.__dso_handle", MemProt::Read); 167b749ef9eSLang Hames auto &DSOHandleBlock = G->createContentBlock( 1684eaff6c5SLang Hames DSOHandleSection, getDSOHandleContent(G->getPointerSize()), 1694eaff6c5SLang Hames orc::ExecutorAddr(), 8, 0); 170b749ef9eSLang Hames auto &DSOHandleSymbol = G->addDefinedSymbol( 171b749ef9eSLang Hames DSOHandleBlock, 0, *R->getInitializerSymbol(), DSOHandleBlock.getSize(), 17228e2a891SLang Hames jitlink::Linkage::Strong, jitlink::Scope::Default, false, true); 173b749ef9eSLang Hames DSOHandleBlock.addEdge(EdgeKind, 0, DSOHandleSymbol, 0); 174b749ef9eSLang Hames 175b749ef9eSLang Hames ENP.getObjectLinkingLayer().emit(std::move(R), std::move(G)); 176b749ef9eSLang Hames } 177b749ef9eSLang Hames 178b749ef9eSLang Hames void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {} 179b749ef9eSLang Hames 180b749ef9eSLang Hames private: 181ae73f3fdSLang Hames static MaterializationUnit::Interface 182ae73f3fdSLang Hames createDSOHandleSectionInterface(ELFNixPlatform &ENP, 183b749ef9eSLang Hames const SymbolStringPtr &DSOHandleSymbol) { 184b749ef9eSLang Hames SymbolFlagsMap SymbolFlags; 185b749ef9eSLang Hames SymbolFlags[DSOHandleSymbol] = JITSymbolFlags::Exported; 186ae73f3fdSLang Hames return MaterializationUnit::Interface(std::move(SymbolFlags), 187ae73f3fdSLang Hames DSOHandleSymbol); 188b749ef9eSLang Hames } 189b749ef9eSLang Hames 190b749ef9eSLang Hames ArrayRef<char> getDSOHandleContent(size_t PointerSize) { 191b749ef9eSLang Hames static const char Content[8] = {0}; 192b749ef9eSLang Hames assert(PointerSize <= sizeof Content); 193b749ef9eSLang Hames return {Content, PointerSize}; 194b749ef9eSLang Hames } 195b749ef9eSLang Hames 196b749ef9eSLang Hames ELFNixPlatform &ENP; 197b749ef9eSLang Hames }; 198b749ef9eSLang Hames 199b749ef9eSLang Hames } // end anonymous namespace 200b749ef9eSLang Hames 201b749ef9eSLang Hames namespace llvm { 202b749ef9eSLang Hames namespace orc { 203b749ef9eSLang Hames 204cc20dd28SLang Hames Expected<std::unique_ptr<ELFNixPlatform>> 205cc20dd28SLang Hames ELFNixPlatform::Create(ObjectLinkingLayer &ObjLinkingLayer, 206cc20dd28SLang Hames JITDylib &PlatformJD, 207cc20dd28SLang Hames std::unique_ptr<DefinitionGenerator> OrcRuntime, 20879e3e65bSFangrui Song std::optional<SymbolAliasMap> RuntimeAliases) { 209b749ef9eSLang Hames 210cc20dd28SLang Hames auto &ES = ObjLinkingLayer.getExecutionSession(); 211cc20dd28SLang Hames 212b749ef9eSLang Hames // If the target is not supported then bail out immediately. 2130df66569SLang Hames if (!supportedTarget(ES.getTargetTriple())) 214b749ef9eSLang Hames return make_error<StringError>("Unsupported ELFNixPlatform triple: " + 2150df66569SLang Hames ES.getTargetTriple().str(), 216b749ef9eSLang Hames inconvertibleErrorCode()); 217b749ef9eSLang Hames 2180df66569SLang Hames auto &EPC = ES.getExecutorProcessControl(); 2190df66569SLang Hames 220b749ef9eSLang Hames // Create default aliases if the caller didn't supply any. 221981523b2SPeter S. Housel if (!RuntimeAliases) { 222981523b2SPeter S. Housel auto StandardRuntimeAliases = standardPlatformAliases(ES, PlatformJD); 223981523b2SPeter S. Housel if (!StandardRuntimeAliases) 224981523b2SPeter S. Housel return StandardRuntimeAliases.takeError(); 225981523b2SPeter S. Housel RuntimeAliases = std::move(*StandardRuntimeAliases); 226981523b2SPeter S. Housel } 227b749ef9eSLang Hames 228b749ef9eSLang Hames // Define the aliases. 229b749ef9eSLang Hames if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases)))) 230b749ef9eSLang Hames return std::move(Err); 231b749ef9eSLang Hames 232b749ef9eSLang Hames // Add JIT-dispatch function support symbols. 2338b1771bdSLang Hames if (auto Err = PlatformJD.define( 2348b1771bdSLang Hames absoluteSymbols({{ES.intern("__orc_rt_jit_dispatch"), 2358b1771bdSLang Hames {EPC.getJITDispatchInfo().JITDispatchFunction, 236b749ef9eSLang Hames JITSymbolFlags::Exported}}, 237b749ef9eSLang Hames {ES.intern("__orc_rt_jit_dispatch_ctx"), 2388b1771bdSLang Hames {EPC.getJITDispatchInfo().JITDispatchContext, 239b749ef9eSLang Hames JITSymbolFlags::Exported}}}))) 240b749ef9eSLang Hames return std::move(Err); 241b749ef9eSLang Hames 242b749ef9eSLang Hames // Create the instance. 243b749ef9eSLang Hames Error Err = Error::success(); 244ef6d474aSLang Hames auto P = std::unique_ptr<ELFNixPlatform>(new ELFNixPlatform( 245cc20dd28SLang Hames ObjLinkingLayer, PlatformJD, std::move(OrcRuntime), Err)); 246b749ef9eSLang Hames if (Err) 247b749ef9eSLang Hames return std::move(Err); 248b749ef9eSLang Hames return std::move(P); 249b749ef9eSLang Hames } 250b749ef9eSLang Hames 251ef6d474aSLang Hames Expected<std::unique_ptr<ELFNixPlatform>> 252cc20dd28SLang Hames ELFNixPlatform::Create(ObjectLinkingLayer &ObjLinkingLayer, 253ef6d474aSLang Hames JITDylib &PlatformJD, const char *OrcRuntimePath, 254ef6d474aSLang Hames std::optional<SymbolAliasMap> RuntimeAliases) { 255ef6d474aSLang Hames 256ef6d474aSLang Hames // Create a generator for the ORC runtime archive. 25738d16f50SLang Hames auto OrcRuntimeArchiveGenerator = 25838d16f50SLang Hames StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer, OrcRuntimePath); 259ef6d474aSLang Hames if (!OrcRuntimeArchiveGenerator) 260ef6d474aSLang Hames return OrcRuntimeArchiveGenerator.takeError(); 261ef6d474aSLang Hames 262cc20dd28SLang Hames return Create(ObjLinkingLayer, PlatformJD, 263ef6d474aSLang Hames std::move(*OrcRuntimeArchiveGenerator), 264ef6d474aSLang Hames std::move(RuntimeAliases)); 265ef6d474aSLang Hames } 266ef6d474aSLang Hames 267b749ef9eSLang Hames Error ELFNixPlatform::setupJITDylib(JITDylib &JD) { 268f597ce03SSahilPatidar if (auto Err = JD.define(std::make_unique<DSOHandleMaterializationUnit>( 269f597ce03SSahilPatidar *this, DSOHandleSymbol))) 270f597ce03SSahilPatidar return Err; 271f597ce03SSahilPatidar 272f597ce03SSahilPatidar return ES.lookup({&JD}, DSOHandleSymbol).takeError(); 273b749ef9eSLang Hames } 274b749ef9eSLang Hames 275ade71641SLang Hames Error ELFNixPlatform::teardownJITDylib(JITDylib &JD) { 276f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(PlatformMutex); 277f597ce03SSahilPatidar auto I = JITDylibToHandleAddr.find(&JD); 278f597ce03SSahilPatidar if (I != JITDylibToHandleAddr.end()) { 279f597ce03SSahilPatidar assert(HandleAddrToJITDylib.count(I->second) && 280f597ce03SSahilPatidar "HandleAddrToJITDylib missing entry"); 281f597ce03SSahilPatidar HandleAddrToJITDylib.erase(I->second); 282f597ce03SSahilPatidar JITDylibToHandleAddr.erase(I); 283f597ce03SSahilPatidar } 284ade71641SLang Hames return Error::success(); 285ade71641SLang Hames } 286ade71641SLang Hames 287b749ef9eSLang Hames Error ELFNixPlatform::notifyAdding(ResourceTracker &RT, 288b749ef9eSLang Hames const MaterializationUnit &MU) { 289f597ce03SSahilPatidar 290b749ef9eSLang Hames auto &JD = RT.getJITDylib(); 291b749ef9eSLang Hames const auto &InitSym = MU.getInitializerSymbol(); 292b749ef9eSLang Hames if (!InitSym) 293b749ef9eSLang Hames return Error::success(); 294b749ef9eSLang Hames 295b749ef9eSLang Hames RegisteredInitSymbols[&JD].add(InitSym, 296b749ef9eSLang Hames SymbolLookupFlags::WeaklyReferencedSymbol); 297b749ef9eSLang Hames LLVM_DEBUG({ 298b749ef9eSLang Hames dbgs() << "ELFNixPlatform: Registered init symbol " << *InitSym 299b749ef9eSLang Hames << " for MU " << MU.getName() << "\n"; 300b749ef9eSLang Hames }); 301b749ef9eSLang Hames return Error::success(); 302b749ef9eSLang Hames } 303b749ef9eSLang Hames 304b749ef9eSLang Hames Error ELFNixPlatform::notifyRemoving(ResourceTracker &RT) { 305b749ef9eSLang Hames llvm_unreachable("Not supported yet"); 306b749ef9eSLang Hames } 307b749ef9eSLang Hames 308b749ef9eSLang Hames static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, 309b749ef9eSLang Hames ArrayRef<std::pair<const char *, const char *>> AL) { 310b749ef9eSLang Hames for (auto &KV : AL) { 311b749ef9eSLang Hames auto AliasName = ES.intern(KV.first); 312b749ef9eSLang Hames assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map"); 313b749ef9eSLang Hames Aliases[std::move(AliasName)] = {ES.intern(KV.second), 314b749ef9eSLang Hames JITSymbolFlags::Exported}; 315b749ef9eSLang Hames } 316b749ef9eSLang Hames } 317b749ef9eSLang Hames 318981523b2SPeter S. Housel Expected<SymbolAliasMap> 319981523b2SPeter S. Housel ELFNixPlatform::standardPlatformAliases(ExecutionSession &ES, 320981523b2SPeter S. Housel JITDylib &PlatformJD) { 321b749ef9eSLang Hames SymbolAliasMap Aliases; 322b749ef9eSLang Hames addAliases(ES, Aliases, requiredCXXAliases()); 323b749ef9eSLang Hames addAliases(ES, Aliases, standardRuntimeUtilityAliases()); 324f2d18a4dSLang Hames addAliases(ES, Aliases, standardLazyCompilationAliases()); 325b749ef9eSLang Hames return Aliases; 326b749ef9eSLang Hames } 327b749ef9eSLang Hames 328b749ef9eSLang Hames ArrayRef<std::pair<const char *, const char *>> 329b749ef9eSLang Hames ELFNixPlatform::requiredCXXAliases() { 330b749ef9eSLang Hames static const std::pair<const char *, const char *> RequiredCXXAliases[] = { 33159032638Sluxufan {"__cxa_atexit", "__orc_rt_elfnix_cxa_atexit"}, 33259032638Sluxufan {"atexit", "__orc_rt_elfnix_atexit"}}; 333b749ef9eSLang Hames 334b749ef9eSLang Hames return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases); 335b749ef9eSLang Hames } 336b749ef9eSLang Hames 337b749ef9eSLang Hames ArrayRef<std::pair<const char *, const char *>> 338b749ef9eSLang Hames ELFNixPlatform::standardRuntimeUtilityAliases() { 339b749ef9eSLang Hames static const std::pair<const char *, const char *> 340b749ef9eSLang Hames StandardRuntimeUtilityAliases[] = { 341b749ef9eSLang Hames {"__orc_rt_run_program", "__orc_rt_elfnix_run_program"}, 3421aa71f86SPeter S. Housel {"__orc_rt_jit_dlerror", "__orc_rt_elfnix_jit_dlerror"}, 3431aa71f86SPeter S. Housel {"__orc_rt_jit_dlopen", "__orc_rt_elfnix_jit_dlopen"}, 344f363f9d6SSahilPatidar {"__orc_rt_jit_dlupdate", "__orc_rt_elfnix_jit_dlupdate"}, 3451aa71f86SPeter S. Housel {"__orc_rt_jit_dlclose", "__orc_rt_elfnix_jit_dlclose"}, 3461aa71f86SPeter S. Housel {"__orc_rt_jit_dlsym", "__orc_rt_elfnix_jit_dlsym"}, 347b749ef9eSLang Hames {"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}}; 348b749ef9eSLang Hames 349b749ef9eSLang Hames return ArrayRef<std::pair<const char *, const char *>>( 350b749ef9eSLang Hames StandardRuntimeUtilityAliases); 351b749ef9eSLang Hames } 352b749ef9eSLang Hames 353f2d18a4dSLang Hames ArrayRef<std::pair<const char *, const char *>> 354f2d18a4dSLang Hames ELFNixPlatform::standardLazyCompilationAliases() { 355f2d18a4dSLang Hames static const std::pair<const char *, const char *> 356f2d18a4dSLang Hames StandardLazyCompilationAliases[] = { 357f2d18a4dSLang Hames {"__orc_rt_reenter", "__orc_rt_sysv_reenter"}}; 358f2d18a4dSLang Hames 359f2d18a4dSLang Hames return ArrayRef<std::pair<const char *, const char *>>( 360f2d18a4dSLang Hames StandardLazyCompilationAliases); 361f2d18a4dSLang Hames } 362f2d18a4dSLang Hames 363b749ef9eSLang Hames bool ELFNixPlatform::supportedTarget(const Triple &TT) { 364b749ef9eSLang Hames switch (TT.getArch()) { 365b749ef9eSLang Hames case Triple::x86_64: 366e093e421SSunho Kim case Triple::aarch64: 3675cb2a78aSKai Luo // FIXME: jitlink for ppc64 hasn't been well tested, leave it unsupported 3685cb2a78aSKai Luo // right now. 3695cb2a78aSKai Luo case Triple::ppc64le: 370*79231a86SAmi-zhang case Triple::loongarch64: 371b749ef9eSLang Hames return true; 372b749ef9eSLang Hames default: 373b749ef9eSLang Hames return false; 374b749ef9eSLang Hames } 375b749ef9eSLang Hames } 376b749ef9eSLang Hames 377b749ef9eSLang Hames ELFNixPlatform::ELFNixPlatform( 378cc20dd28SLang Hames ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, 379b749ef9eSLang Hames std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err) 380cc20dd28SLang Hames : ES(ObjLinkingLayer.getExecutionSession()), PlatformJD(PlatformJD), 381cc20dd28SLang Hames ObjLinkingLayer(ObjLinkingLayer), 382b749ef9eSLang Hames DSOHandleSymbol(ES.intern("__dso_handle")) { 383d02c1676SLang Hames ErrorAsOutParameter _(Err); 384b749ef9eSLang Hames ObjLinkingLayer.addPlugin(std::make_unique<ELFNixPlatformPlugin>(*this)); 385b749ef9eSLang Hames 386b749ef9eSLang Hames PlatformJD.addGenerator(std::move(OrcRuntimeGenerator)); 387b749ef9eSLang Hames 388f597ce03SSahilPatidar BootstrapInfo BI; 389f597ce03SSahilPatidar Bootstrap = &BI; 390f597ce03SSahilPatidar 391b749ef9eSLang Hames // PlatformJD hasn't been 'set-up' by the platform yet (since we're creating 392b749ef9eSLang Hames // the platform now), so set it up. 393b749ef9eSLang Hames if (auto E2 = setupJITDylib(PlatformJD)) { 394b749ef9eSLang Hames Err = std::move(E2); 395b749ef9eSLang Hames return; 396b749ef9eSLang Hames } 397b749ef9eSLang Hames 398f597ce03SSahilPatidar // Step (2) Request runtime registration functions to trigger 399f597ce03SSahilPatidar // materialization.. 400f597ce03SSahilPatidar if ((Err = ES.lookup( 401f597ce03SSahilPatidar makeJITDylibSearchOrder(&PlatformJD), 402f597ce03SSahilPatidar SymbolLookupSet( 403f597ce03SSahilPatidar {PlatformBootstrap.Name, PlatformShutdown.Name, 404f597ce03SSahilPatidar RegisterJITDylib.Name, DeregisterJITDylib.Name, 405f597ce03SSahilPatidar RegisterInitSections.Name, DeregisterInitSections.Name, 406f597ce03SSahilPatidar RegisterObjectSections.Name, 407f597ce03SSahilPatidar DeregisterObjectSections.Name, CreatePThreadKey.Name})) 408f597ce03SSahilPatidar .takeError())) 409f597ce03SSahilPatidar return; 410f597ce03SSahilPatidar 411f597ce03SSahilPatidar // Step (3) Wait for any incidental linker work to complete. 412f597ce03SSahilPatidar { 413f597ce03SSahilPatidar std::unique_lock<std::mutex> Lock(BI.Mutex); 414f597ce03SSahilPatidar BI.CV.wait(Lock, [&]() { return BI.ActiveGraphs == 0; }); 415f597ce03SSahilPatidar Bootstrap = nullptr; 416f597ce03SSahilPatidar } 417f597ce03SSahilPatidar 418f597ce03SSahilPatidar // Step (4) Add complete-bootstrap materialization unit and request. 419f597ce03SSahilPatidar auto BootstrapCompleteSymbol = 420f597ce03SSahilPatidar ES.intern("__orc_rt_elfnix_complete_bootstrap"); 421f597ce03SSahilPatidar if ((Err = PlatformJD.define( 422f597ce03SSahilPatidar std::make_unique<ELFNixPlatformCompleteBootstrapMaterializationUnit>( 423f597ce03SSahilPatidar *this, PlatformJD.getName(), BootstrapCompleteSymbol, 424f597ce03SSahilPatidar std::move(BI.DeferredRTFnMap), BI.ELFNixHeaderAddr, 425f597ce03SSahilPatidar PlatformBootstrap.Addr, PlatformShutdown.Addr, 426f597ce03SSahilPatidar RegisterJITDylib.Addr, DeregisterJITDylib.Addr)))) 427f597ce03SSahilPatidar return; 428f597ce03SSahilPatidar if ((Err = ES.lookup(makeJITDylibSearchOrder( 429f597ce03SSahilPatidar &PlatformJD, JITDylibLookupFlags::MatchAllSymbols), 430f597ce03SSahilPatidar std::move(BootstrapCompleteSymbol)) 431f597ce03SSahilPatidar .takeError())) 432f597ce03SSahilPatidar return; 433b749ef9eSLang Hames 434b749ef9eSLang Hames // Associate wrapper function tags with JIT-side function implementations. 435b749ef9eSLang Hames if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) { 436b749ef9eSLang Hames Err = std::move(E2); 437b749ef9eSLang Hames return; 438b749ef9eSLang Hames } 439b749ef9eSLang Hames } 440b749ef9eSLang Hames 441b749ef9eSLang Hames Error ELFNixPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) { 442b749ef9eSLang Hames ExecutionSession::JITDispatchHandlerAssociationMap WFs; 443b749ef9eSLang Hames 444f597ce03SSahilPatidar using RecordInitializersSPSSig = 445f597ce03SSahilPatidar SPSExpected<SPSELFNixJITDylibDepInfoMap>(SPSExecutorAddr); 446f597ce03SSahilPatidar WFs[ES.intern("__orc_rt_elfnix_push_initializers_tag")] = 447f597ce03SSahilPatidar ES.wrapAsyncWithSPS<RecordInitializersSPSSig>( 448f597ce03SSahilPatidar this, &ELFNixPlatform::rt_recordInitializers); 449b749ef9eSLang Hames 450b749ef9eSLang Hames using LookupSymbolSPSSig = 451ef391df2SLang Hames SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSString); 452b749ef9eSLang Hames WFs[ES.intern("__orc_rt_elfnix_symbol_lookup_tag")] = 453b749ef9eSLang Hames ES.wrapAsyncWithSPS<LookupSymbolSPSSig>(this, 454b749ef9eSLang Hames &ELFNixPlatform::rt_lookupSymbol); 455b749ef9eSLang Hames 456b749ef9eSLang Hames return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs)); 457b749ef9eSLang Hames } 458b749ef9eSLang Hames 459f597ce03SSahilPatidar void ELFNixPlatform::pushInitializersLoop( 460f597ce03SSahilPatidar PushInitializersSendResultFn SendResult, JITDylibSP JD) { 461b749ef9eSLang Hames DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols; 462f597ce03SSahilPatidar DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap; 463f597ce03SSahilPatidar SmallVector<JITDylib *, 16> Worklist({JD.get()}); 464f597ce03SSahilPatidar 465b749ef9eSLang Hames ES.runSessionLocked([&]() { 466f597ce03SSahilPatidar while (!Worklist.empty()) { 467f597ce03SSahilPatidar // FIXME: Check for defunct dylibs. 468f597ce03SSahilPatidar 469f597ce03SSahilPatidar auto DepJD = Worklist.back(); 470f597ce03SSahilPatidar Worklist.pop_back(); 471f597ce03SSahilPatidar 472f597ce03SSahilPatidar // If we've already visited this JITDylib on this iteration then continue. 473f597ce03SSahilPatidar if (JDDepMap.count(DepJD)) 474f597ce03SSahilPatidar continue; 475f597ce03SSahilPatidar 476f597ce03SSahilPatidar // Add dep info. 477f597ce03SSahilPatidar auto &DM = JDDepMap[DepJD]; 478f597ce03SSahilPatidar DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) { 479f597ce03SSahilPatidar for (auto &KV : O) { 480f597ce03SSahilPatidar if (KV.first == DepJD) 481f597ce03SSahilPatidar continue; 482f597ce03SSahilPatidar DM.push_back(KV.first); 483f597ce03SSahilPatidar Worklist.push_back(KV.first); 484f597ce03SSahilPatidar } 485f597ce03SSahilPatidar }); 486f597ce03SSahilPatidar 487f597ce03SSahilPatidar // Add any registered init symbols. 488f597ce03SSahilPatidar auto RISItr = RegisteredInitSymbols.find(DepJD); 489b749ef9eSLang Hames if (RISItr != RegisteredInitSymbols.end()) { 490f597ce03SSahilPatidar NewInitSymbols[DepJD] = std::move(RISItr->second); 491b749ef9eSLang Hames RegisteredInitSymbols.erase(RISItr); 492b749ef9eSLang Hames } 493b749ef9eSLang Hames } 494b749ef9eSLang Hames }); 495b749ef9eSLang Hames 496f597ce03SSahilPatidar // If there are no further init symbols to look up then send the link order 497f597ce03SSahilPatidar // (as a list of header addresses) to the caller. 498b749ef9eSLang Hames if (NewInitSymbols.empty()) { 499f597ce03SSahilPatidar 500f597ce03SSahilPatidar // To make the list intelligible to the runtime we need to convert all 501f597ce03SSahilPatidar // JITDylib pointers to their header addresses. Only include JITDylibs 502f597ce03SSahilPatidar // that appear in the JITDylibToHandleAddr map (i.e. those that have been 503f597ce03SSahilPatidar // through setupJITDylib) -- bare JITDylibs aren't managed by the platform. 504f597ce03SSahilPatidar DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs; 505f597ce03SSahilPatidar HeaderAddrs.reserve(JDDepMap.size()); 506f597ce03SSahilPatidar { 507f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(PlatformMutex); 508f597ce03SSahilPatidar for (auto &KV : JDDepMap) { 509f597ce03SSahilPatidar auto I = JITDylibToHandleAddr.find(KV.first); 510f597ce03SSahilPatidar if (I != JITDylibToHandleAddr.end()) 511f597ce03SSahilPatidar HeaderAddrs[KV.first] = I->second; 512f597ce03SSahilPatidar } 513f597ce03SSahilPatidar } 514f597ce03SSahilPatidar 515f597ce03SSahilPatidar // Build the dep info map to return. 516f597ce03SSahilPatidar ELFNixJITDylibDepInfoMap DIM; 517f597ce03SSahilPatidar DIM.reserve(JDDepMap.size()); 518f597ce03SSahilPatidar for (auto &KV : JDDepMap) { 519f597ce03SSahilPatidar auto HI = HeaderAddrs.find(KV.first); 520f597ce03SSahilPatidar // Skip unmanaged JITDylibs. 521f597ce03SSahilPatidar if (HI == HeaderAddrs.end()) 522f597ce03SSahilPatidar continue; 523f597ce03SSahilPatidar auto H = HI->second; 524f597ce03SSahilPatidar ELFNixJITDylibDepInfo DepInfo; 525f597ce03SSahilPatidar for (auto &Dep : KV.second) { 526f597ce03SSahilPatidar auto HJ = HeaderAddrs.find(Dep); 527f597ce03SSahilPatidar if (HJ != HeaderAddrs.end()) 528f597ce03SSahilPatidar DepInfo.push_back(HJ->second); 529f597ce03SSahilPatidar } 530f597ce03SSahilPatidar DIM.push_back(std::make_pair(H, std::move(DepInfo))); 531f597ce03SSahilPatidar } 532f597ce03SSahilPatidar SendResult(DIM); 533b749ef9eSLang Hames return; 534b749ef9eSLang Hames } 535b749ef9eSLang Hames 536b749ef9eSLang Hames // Otherwise issue a lookup and re-run this phase when it completes. 537b749ef9eSLang Hames lookupInitSymbolsAsync( 538f597ce03SSahilPatidar [this, SendResult = std::move(SendResult), JD](Error Err) mutable { 539b749ef9eSLang Hames if (Err) 540b749ef9eSLang Hames SendResult(std::move(Err)); 541b749ef9eSLang Hames else 542f597ce03SSahilPatidar pushInitializersLoop(std::move(SendResult), JD); 543b749ef9eSLang Hames }, 544b749ef9eSLang Hames ES, std::move(NewInitSymbols)); 545b749ef9eSLang Hames } 546b749ef9eSLang Hames 547f597ce03SSahilPatidar void ELFNixPlatform::rt_recordInitializers( 548f597ce03SSahilPatidar PushInitializersSendResultFn SendResult, ExecutorAddr JDHeaderAddr) { 549f597ce03SSahilPatidar JITDylibSP JD; 550b749ef9eSLang Hames { 551b749ef9eSLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex); 552f597ce03SSahilPatidar auto I = HandleAddrToJITDylib.find(JDHeaderAddr); 553b749ef9eSLang Hames if (I != HandleAddrToJITDylib.end()) 554b749ef9eSLang Hames JD = I->second; 555b749ef9eSLang Hames } 556b749ef9eSLang Hames 557f597ce03SSahilPatidar LLVM_DEBUG({ 558f597ce03SSahilPatidar dbgs() << "ELFNixPlatform::rt_recordInitializers(" << JDHeaderAddr << ") "; 559f597ce03SSahilPatidar if (JD) 560f597ce03SSahilPatidar dbgs() << "pushing initializers for " << JD->getName() << "\n"; 561f597ce03SSahilPatidar else 562f597ce03SSahilPatidar dbgs() << "No JITDylib for header address.\n"; 563f597ce03SSahilPatidar }); 564f597ce03SSahilPatidar 565b749ef9eSLang Hames if (!JD) { 566f597ce03SSahilPatidar SendResult(make_error<StringError>("No JITDylib with header addr " + 567f597ce03SSahilPatidar formatv("{0:x}", JDHeaderAddr), 568b749ef9eSLang Hames inconvertibleErrorCode())); 569b749ef9eSLang Hames return; 570b749ef9eSLang Hames } 571b749ef9eSLang Hames 572f597ce03SSahilPatidar pushInitializersLoop(std::move(SendResult), JD); 573b749ef9eSLang Hames } 574b749ef9eSLang Hames 575b749ef9eSLang Hames void ELFNixPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult, 576ef391df2SLang Hames ExecutorAddr Handle, 577b749ef9eSLang Hames StringRef SymbolName) { 578b749ef9eSLang Hames LLVM_DEBUG({ 579fdd9df19SLang Hames dbgs() << "ELFNixPlatform::rt_lookupSymbol(\"" << Handle << "\")\n"; 580b749ef9eSLang Hames }); 581b749ef9eSLang Hames 582b749ef9eSLang Hames JITDylib *JD = nullptr; 583b749ef9eSLang Hames 584b749ef9eSLang Hames { 585b749ef9eSLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex); 586118e953bSLang Hames auto I = HandleAddrToJITDylib.find(Handle); 587b749ef9eSLang Hames if (I != HandleAddrToJITDylib.end()) 588b749ef9eSLang Hames JD = I->second; 589b749ef9eSLang Hames } 590b749ef9eSLang Hames 591b749ef9eSLang Hames if (!JD) { 592fdd9df19SLang Hames LLVM_DEBUG(dbgs() << " No JITDylib for handle " << Handle << "\n"); 593b749ef9eSLang Hames SendResult(make_error<StringError>("No JITDylib associated with handle " + 594fdd9df19SLang Hames formatv("{0:x}", Handle), 595b749ef9eSLang Hames inconvertibleErrorCode())); 596b749ef9eSLang Hames return; 597b749ef9eSLang Hames } 598b749ef9eSLang Hames 599b749ef9eSLang Hames // Use functor class to work around XL build compiler issue on AIX. 600b749ef9eSLang Hames class RtLookupNotifyComplete { 601b749ef9eSLang Hames public: 602b749ef9eSLang Hames RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult) 603b749ef9eSLang Hames : SendResult(std::move(SendResult)) {} 604b749ef9eSLang Hames void operator()(Expected<SymbolMap> Result) { 605b749ef9eSLang Hames if (Result) { 606b749ef9eSLang Hames assert(Result->size() == 1 && "Unexpected result map count"); 6078b1771bdSLang Hames SendResult(Result->begin()->second.getAddress()); 608b749ef9eSLang Hames } else { 609b749ef9eSLang Hames SendResult(Result.takeError()); 610b749ef9eSLang Hames } 611b749ef9eSLang Hames } 612b749ef9eSLang Hames 613b749ef9eSLang Hames private: 614b749ef9eSLang Hames SendSymbolAddressFn SendResult; 615b749ef9eSLang Hames }; 616b749ef9eSLang Hames 617b749ef9eSLang Hames ES.lookup( 618b749ef9eSLang Hames LookupKind::DLSym, {{JD, JITDylibLookupFlags::MatchExportedSymbolsOnly}}, 619b749ef9eSLang Hames SymbolLookupSet(ES.intern(SymbolName)), SymbolState::Ready, 620b749ef9eSLang Hames RtLookupNotifyComplete(std::move(SendResult)), NoDependenciesToRegister); 621b749ef9eSLang Hames } 622b749ef9eSLang Hames 623f597ce03SSahilPatidar Error ELFNixPlatform::ELFNixPlatformPlugin::bootstrapPipelineStart( 624f597ce03SSahilPatidar jitlink::LinkGraph &G) { 625f597ce03SSahilPatidar // Increment the active graphs count in BootstrapInfo. 626f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(MP.Bootstrap.load()->Mutex); 627f597ce03SSahilPatidar ++MP.Bootstrap.load()->ActiveGraphs; 628f597ce03SSahilPatidar return Error::success(); 629b749ef9eSLang Hames } 630b749ef9eSLang Hames 631f597ce03SSahilPatidar Error ELFNixPlatform::ELFNixPlatformPlugin:: 632f597ce03SSahilPatidar bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G) { 633f597ce03SSahilPatidar // Record bootstrap function names. 634f597ce03SSahilPatidar std::pair<StringRef, ExecutorAddr *> RuntimeSymbols[] = { 635f597ce03SSahilPatidar {*MP.DSOHandleSymbol, &MP.Bootstrap.load()->ELFNixHeaderAddr}, 636f597ce03SSahilPatidar {*MP.PlatformBootstrap.Name, &MP.PlatformBootstrap.Addr}, 637f597ce03SSahilPatidar {*MP.PlatformShutdown.Name, &MP.PlatformShutdown.Addr}, 638f597ce03SSahilPatidar {*MP.RegisterJITDylib.Name, &MP.RegisterJITDylib.Addr}, 639f597ce03SSahilPatidar {*MP.DeregisterJITDylib.Name, &MP.DeregisterJITDylib.Addr}, 640f597ce03SSahilPatidar {*MP.RegisterObjectSections.Name, &MP.RegisterObjectSections.Addr}, 641f597ce03SSahilPatidar {*MP.DeregisterObjectSections.Name, &MP.DeregisterObjectSections.Addr}, 642f597ce03SSahilPatidar {*MP.RegisterInitSections.Name, &MP.RegisterInitSections.Addr}, 643f597ce03SSahilPatidar {*MP.DeregisterInitSections.Name, &MP.DeregisterInitSections.Addr}, 644f597ce03SSahilPatidar {*MP.CreatePThreadKey.Name, &MP.CreatePThreadKey.Addr}}; 645b749ef9eSLang Hames 646f597ce03SSahilPatidar bool RegisterELFNixHeader = false; 647f597ce03SSahilPatidar 648f597ce03SSahilPatidar for (auto *Sym : G.defined_symbols()) { 649f597ce03SSahilPatidar for (auto &RTSym : RuntimeSymbols) { 6502ccf7ed2SJared Wyles if (Sym->hasName() && *Sym->getName() == RTSym.first) { 651f597ce03SSahilPatidar if (*RTSym.second) 652f597ce03SSahilPatidar return make_error<StringError>( 653f597ce03SSahilPatidar "Duplicate " + RTSym.first + 654f597ce03SSahilPatidar " detected during ELFNixPlatform bootstrap", 655f597ce03SSahilPatidar inconvertibleErrorCode()); 656f597ce03SSahilPatidar 6572ccf7ed2SJared Wyles if (*Sym->getName() == *MP.DSOHandleSymbol) 658f597ce03SSahilPatidar RegisterELFNixHeader = true; 659f597ce03SSahilPatidar 660f597ce03SSahilPatidar *RTSym.second = Sym->getAddress(); 661f597ce03SSahilPatidar } 662f597ce03SSahilPatidar } 663b749ef9eSLang Hames } 664b749ef9eSLang Hames 665f597ce03SSahilPatidar if (RegisterELFNixHeader) { 666f597ce03SSahilPatidar // If this graph defines the elfnix header symbol then create the internal 667f597ce03SSahilPatidar // mapping between it and PlatformJD. 668f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(MP.PlatformMutex); 669f597ce03SSahilPatidar MP.JITDylibToHandleAddr[&MP.PlatformJD] = 670f597ce03SSahilPatidar MP.Bootstrap.load()->ELFNixHeaderAddr; 671f597ce03SSahilPatidar MP.HandleAddrToJITDylib[MP.Bootstrap.load()->ELFNixHeaderAddr] = 672f597ce03SSahilPatidar &MP.PlatformJD; 673b749ef9eSLang Hames } 674b749ef9eSLang Hames 675b749ef9eSLang Hames return Error::success(); 676b749ef9eSLang Hames } 677b749ef9eSLang Hames 678f597ce03SSahilPatidar Error ELFNixPlatform::ELFNixPlatformPlugin::bootstrapPipelineEnd( 679f597ce03SSahilPatidar jitlink::LinkGraph &G) { 680f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(MP.Bootstrap.load()->Mutex); 681f597ce03SSahilPatidar assert(MP.Bootstrap && "DeferredAAs reset before bootstrap completed"); 682f597ce03SSahilPatidar --MP.Bootstrap.load()->ActiveGraphs; 683f597ce03SSahilPatidar // Notify Bootstrap->CV while holding the mutex because the mutex is 684f597ce03SSahilPatidar // also keeping Bootstrap->CV alive. 685f597ce03SSahilPatidar if (MP.Bootstrap.load()->ActiveGraphs == 0) 686f597ce03SSahilPatidar MP.Bootstrap.load()->CV.notify_all(); 687b749ef9eSLang Hames return Error::success(); 688b749ef9eSLang Hames } 689b749ef9eSLang Hames 690b749ef9eSLang Hames Error ELFNixPlatform::registerPerObjectSections( 691f597ce03SSahilPatidar jitlink::LinkGraph &G, const ELFPerObjectSectionsToRegister &POSR, 692f597ce03SSahilPatidar bool IsBootstrapping) { 693f597ce03SSahilPatidar using SPSRegisterPerObjSectionsArgs = 694f597ce03SSahilPatidar SPSArgList<SPSELFPerObjectSectionsToRegister>; 695b749ef9eSLang Hames 696f597ce03SSahilPatidar if (LLVM_UNLIKELY(IsBootstrapping)) { 697f597ce03SSahilPatidar Bootstrap.load()->addArgumentsToRTFnMap( 698f597ce03SSahilPatidar &RegisterObjectSections, &DeregisterObjectSections, 699f597ce03SSahilPatidar getArgDataBufferType<SPSRegisterPerObjSectionsArgs>(POSR), 700f597ce03SSahilPatidar getArgDataBufferType<SPSRegisterPerObjSectionsArgs>(POSR)); 701f597ce03SSahilPatidar return Error::success(); 702f597ce03SSahilPatidar } 703b749ef9eSLang Hames 704f597ce03SSahilPatidar G.allocActions().push_back( 705f597ce03SSahilPatidar {cantFail(WrapperFunctionCall::Create<SPSRegisterPerObjSectionsArgs>( 706f597ce03SSahilPatidar RegisterObjectSections.Addr, POSR)), 707f597ce03SSahilPatidar cantFail(WrapperFunctionCall::Create<SPSRegisterPerObjSectionsArgs>( 708f597ce03SSahilPatidar DeregisterObjectSections.Addr, POSR))}); 709f597ce03SSahilPatidar 710f597ce03SSahilPatidar return Error::success(); 711b749ef9eSLang Hames } 712b749ef9eSLang Hames 713ff6069b8Sluxufan Expected<uint64_t> ELFNixPlatform::createPThreadKey() { 714f597ce03SSahilPatidar if (!CreatePThreadKey.Addr) 715ff6069b8Sluxufan return make_error<StringError>( 716ff6069b8Sluxufan "Attempting to create pthread key in target, but runtime support has " 717ff6069b8Sluxufan "not been loaded yet", 718ff6069b8Sluxufan inconvertibleErrorCode()); 719ff6069b8Sluxufan 720ff6069b8Sluxufan Expected<uint64_t> Result(0); 721ff6069b8Sluxufan if (auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(void)>( 722f597ce03SSahilPatidar CreatePThreadKey.Addr, Result)) 723ff6069b8Sluxufan return std::move(Err); 724ff6069b8Sluxufan return Result; 725ff6069b8Sluxufan } 726ff6069b8Sluxufan 727b749ef9eSLang Hames void ELFNixPlatform::ELFNixPlatformPlugin::modifyPassConfig( 728b749ef9eSLang Hames MaterializationResponsibility &MR, jitlink::LinkGraph &LG, 729b749ef9eSLang Hames jitlink::PassConfiguration &Config) { 730f597ce03SSahilPatidar using namespace jitlink; 731f597ce03SSahilPatidar 732f597ce03SSahilPatidar bool InBootstrapPhase = 733f597ce03SSahilPatidar &MR.getTargetJITDylib() == &MP.PlatformJD && MP.Bootstrap; 734f597ce03SSahilPatidar 735f597ce03SSahilPatidar // If we're in the bootstrap phase then increment the active graphs. 736f597ce03SSahilPatidar if (InBootstrapPhase) { 737f597ce03SSahilPatidar Config.PrePrunePasses.push_back( 738f597ce03SSahilPatidar [this](LinkGraph &G) { return bootstrapPipelineStart(G); }); 739f597ce03SSahilPatidar Config.PostAllocationPasses.push_back([this](LinkGraph &G) { 740f597ce03SSahilPatidar return bootstrapPipelineRecordRuntimeFunctions(G); 741f597ce03SSahilPatidar }); 742f597ce03SSahilPatidar } 743b749ef9eSLang Hames 744b749ef9eSLang Hames // If the initializer symbol is the __dso_handle symbol then just add 745b749ef9eSLang Hames // the DSO handle support passes. 746f597ce03SSahilPatidar if (auto InitSymbol = MR.getInitializerSymbol()) { 747f597ce03SSahilPatidar if (InitSymbol == MP.DSOHandleSymbol && !InBootstrapPhase) { 748b749ef9eSLang Hames addDSOHandleSupportPasses(MR, Config); 749b749ef9eSLang Hames // The DSOHandle materialization unit doesn't require any other 750b749ef9eSLang Hames // support, so we can bail out early. 751b749ef9eSLang Hames return; 752b749ef9eSLang Hames } 753b749ef9eSLang Hames 754b749ef9eSLang Hames /// Preserve init sections. 755f597ce03SSahilPatidar Config.PrePrunePasses.push_back( 756f597ce03SSahilPatidar [this, &MR](jitlink::LinkGraph &G) -> Error { 757b749ef9eSLang Hames if (auto Err = preserveInitSections(G, MR)) 758b749ef9eSLang Hames return Err; 759b749ef9eSLang Hames return Error::success(); 760b749ef9eSLang Hames }); 761f597ce03SSahilPatidar } 762b749ef9eSLang Hames 763f597ce03SSahilPatidar // Add passes for eh-frame and TLV support. 764f597ce03SSahilPatidar addEHAndTLVSupportPasses(MR, Config, InBootstrapPhase); 765f597ce03SSahilPatidar 766f597ce03SSahilPatidar // If the object contains initializers then add passes to record them. 767f597ce03SSahilPatidar Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib(), 768f597ce03SSahilPatidar InBootstrapPhase](jitlink::LinkGraph &G) { 769f597ce03SSahilPatidar return registerInitSections(G, JD, InBootstrapPhase); 770b749ef9eSLang Hames }); 771f597ce03SSahilPatidar 772f597ce03SSahilPatidar // If we're in the bootstrap phase then steal allocation actions and then 773f597ce03SSahilPatidar // decrement the active graphs. 774f597ce03SSahilPatidar if (InBootstrapPhase) 775f597ce03SSahilPatidar Config.PostFixupPasses.push_back( 776f597ce03SSahilPatidar [this](LinkGraph &G) { return bootstrapPipelineEnd(G); }); 777b749ef9eSLang Hames } 778b749ef9eSLang Hames 779b749ef9eSLang Hames void ELFNixPlatform::ELFNixPlatformPlugin::addDSOHandleSupportPasses( 780b749ef9eSLang Hames MaterializationResponsibility &MR, jitlink::PassConfiguration &Config) { 781b749ef9eSLang Hames 782b749ef9eSLang Hames Config.PostAllocationPasses.push_back([this, &JD = MR.getTargetJITDylib()]( 783b749ef9eSLang Hames jitlink::LinkGraph &G) -> Error { 784b749ef9eSLang Hames auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) { 7852ccf7ed2SJared Wyles return Sym->getName() == MP.DSOHandleSymbol; 786b749ef9eSLang Hames }); 787b749ef9eSLang Hames assert(I != G.defined_symbols().end() && "Missing DSO handle symbol"); 788b749ef9eSLang Hames { 789b749ef9eSLang Hames std::lock_guard<std::mutex> Lock(MP.PlatformMutex); 790118e953bSLang Hames auto HandleAddr = (*I)->getAddress(); 791b749ef9eSLang Hames MP.HandleAddrToJITDylib[HandleAddr] = &JD; 792f597ce03SSahilPatidar MP.JITDylibToHandleAddr[&JD] = HandleAddr; 793f597ce03SSahilPatidar 794f597ce03SSahilPatidar G.allocActions().push_back( 795f597ce03SSahilPatidar {cantFail(WrapperFunctionCall::Create< 796f597ce03SSahilPatidar SPSArgList<SPSString, SPSExecutorAddr>>( 797f597ce03SSahilPatidar MP.RegisterJITDylib.Addr, JD.getName(), HandleAddr)), 798f597ce03SSahilPatidar cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>( 799f597ce03SSahilPatidar MP.DeregisterJITDylib.Addr, HandleAddr))}); 800b749ef9eSLang Hames } 801b749ef9eSLang Hames return Error::success(); 802b749ef9eSLang Hames }); 803b749ef9eSLang Hames } 804b749ef9eSLang Hames 805b749ef9eSLang Hames void ELFNixPlatform::ELFNixPlatformPlugin::addEHAndTLVSupportPasses( 806f597ce03SSahilPatidar MaterializationResponsibility &MR, jitlink::PassConfiguration &Config, 807f597ce03SSahilPatidar bool IsBootstrapping) { 808b749ef9eSLang Hames 809b749ef9eSLang Hames // Insert TLV lowering at the start of the PostPrunePasses, since we want 810b749ef9eSLang Hames // it to run before GOT/PLT lowering. 811ff6069b8Sluxufan 812ff6069b8Sluxufan // TODO: Check that before the fixTLVSectionsAndEdges pass, the GOT/PLT build 813ff6069b8Sluxufan // pass has done. Because the TLS descriptor need to be allocate in GOT. 814ff6069b8Sluxufan Config.PostPrunePasses.push_back( 815b749ef9eSLang Hames [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) { 816b749ef9eSLang Hames return fixTLVSectionsAndEdges(G, JD); 817b749ef9eSLang Hames }); 818b749ef9eSLang Hames 819b749ef9eSLang Hames // Add a pass to register the final addresses of the eh-frame and TLV sections 820b749ef9eSLang Hames // with the runtime. 821f597ce03SSahilPatidar Config.PostFixupPasses.push_back([this, IsBootstrapping]( 822f597ce03SSahilPatidar jitlink::LinkGraph &G) -> Error { 823b749ef9eSLang Hames ELFPerObjectSectionsToRegister POSR; 824b749ef9eSLang Hames 8253d4e9d5eSLang Hames if (auto *EHFrameSection = G.findSectionByName(ELFEHFrameSectionName)) { 826b749ef9eSLang Hames jitlink::SectionRange R(*EHFrameSection); 827b749ef9eSLang Hames if (!R.empty()) 82822d4688eSLang Hames POSR.EHFrameSection = R.getRange(); 829b749ef9eSLang Hames } 830b749ef9eSLang Hames 831b749ef9eSLang Hames // Get a pointer to the thread data section if there is one. It will be used 832b749ef9eSLang Hames // below. 833b749ef9eSLang Hames jitlink::Section *ThreadDataSection = 8343d4e9d5eSLang Hames G.findSectionByName(ELFThreadDataSectionName); 835b749ef9eSLang Hames 836b749ef9eSLang Hames // Handle thread BSS section if there is one. 8373d4e9d5eSLang Hames if (auto *ThreadBSSSection = G.findSectionByName(ELFThreadBSSSectionName)) { 838b749ef9eSLang Hames // If there's already a thread data section in this graph then merge the 839b749ef9eSLang Hames // thread BSS section content into it, otherwise just treat the thread 840b749ef9eSLang Hames // BSS section as the thread data section. 841b749ef9eSLang Hames if (ThreadDataSection) 842b749ef9eSLang Hames G.mergeSections(*ThreadDataSection, *ThreadBSSSection); 843b749ef9eSLang Hames else 844b749ef9eSLang Hames ThreadDataSection = ThreadBSSSection; 845b749ef9eSLang Hames } 846b749ef9eSLang Hames 847b749ef9eSLang Hames // Having merged thread BSS (if present) and thread data (if present), 848b749ef9eSLang Hames // record the resulting section range. 849b749ef9eSLang Hames if (ThreadDataSection) { 850b749ef9eSLang Hames jitlink::SectionRange R(*ThreadDataSection); 851b749ef9eSLang Hames if (!R.empty()) 85222d4688eSLang Hames POSR.ThreadDataSection = R.getRange(); 853b749ef9eSLang Hames } 854b749ef9eSLang Hames 855ef391df2SLang Hames if (POSR.EHFrameSection.Start || POSR.ThreadDataSection.Start) { 856f597ce03SSahilPatidar if (auto Err = MP.registerPerObjectSections(G, POSR, IsBootstrapping)) 857b749ef9eSLang Hames return Err; 858b749ef9eSLang Hames } 859b749ef9eSLang Hames 860b749ef9eSLang Hames return Error::success(); 861b749ef9eSLang Hames }); 862b749ef9eSLang Hames } 863b749ef9eSLang Hames 864b749ef9eSLang Hames Error ELFNixPlatform::ELFNixPlatformPlugin::preserveInitSections( 865b749ef9eSLang Hames jitlink::LinkGraph &G, MaterializationResponsibility &MR) { 866b749ef9eSLang Hames 8670074cea4SLang Hames if (const auto &InitSymName = MR.getInitializerSymbol()) { 8680074cea4SLang Hames 8690074cea4SLang Hames jitlink::Symbol *InitSym = nullptr; 8700074cea4SLang Hames 8712be5abb7SPeter S. Housel for (auto &InitSection : G.sections()) { 872b749ef9eSLang Hames // Skip non-init sections. 8730074cea4SLang Hames if (!isELFInitializerSection(InitSection.getName()) || 8740074cea4SLang Hames InitSection.empty()) 875b749ef9eSLang Hames continue; 876b749ef9eSLang Hames 8770074cea4SLang Hames // Create the init symbol if it has not been created already and attach it 8780074cea4SLang Hames // to the first block. 8790074cea4SLang Hames if (!InitSym) { 8800074cea4SLang Hames auto &B = **InitSection.blocks().begin(); 881d0970707SLang Hames InitSym = &G.addDefinedSymbol( 882d0970707SLang Hames B, 0, *InitSymName, B.getSize(), jitlink::Linkage::Strong, 883d0970707SLang Hames jitlink::Scope::SideEffectsOnly, false, true); 884b749ef9eSLang Hames } 885b749ef9eSLang Hames 8860074cea4SLang Hames // Add keep-alive edges to anonymous symbols in all other init blocks. 8870074cea4SLang Hames for (auto *B : InitSection.blocks()) { 8880074cea4SLang Hames if (B == &InitSym->getBlock()) 8890074cea4SLang Hames continue; 890b749ef9eSLang Hames 8910074cea4SLang Hames auto &S = G.addAnonymousSymbol(*B, 0, B->getSize(), false, true); 8920074cea4SLang Hames InitSym->getBlock().addEdge(jitlink::Edge::KeepAlive, 0, S, 0); 8930074cea4SLang Hames } 8940074cea4SLang Hames } 895b749ef9eSLang Hames } 896b749ef9eSLang Hames 897b749ef9eSLang Hames return Error::success(); 898b749ef9eSLang Hames } 899b749ef9eSLang Hames 900b749ef9eSLang Hames Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections( 901f597ce03SSahilPatidar jitlink::LinkGraph &G, JITDylib &JD, bool IsBootstrapping) { 902f597ce03SSahilPatidar SmallVector<ExecutorAddrRange> ELFNixPlatformSecs; 903fdd9df19SLang Hames LLVM_DEBUG(dbgs() << "ELFNixPlatform::registerInitSections\n"); 904b749ef9eSLang Hames 905f04aaf94SLang Hames SmallVector<jitlink::Section *> OrderedInitSections; 906f04aaf94SLang Hames for (auto &Sec : G.sections()) 907f04aaf94SLang Hames if (isELFInitializerSection(Sec.getName())) 908f04aaf94SLang Hames OrderedInitSections.push_back(&Sec); 909f04aaf94SLang Hames 910f04aaf94SLang Hames // FIXME: This handles priority order within the current graph, but we'll need 911f04aaf94SLang Hames // to include priority information in the initializer allocation 912f04aaf94SLang Hames // actions in order to respect the ordering across multiple graphs. 913f04aaf94SLang Hames llvm::sort(OrderedInitSections, [](const jitlink::Section *LHS, 914f04aaf94SLang Hames const jitlink::Section *RHS) { 915f04aaf94SLang Hames if (LHS->getName().starts_with(".init_array")) { 916f04aaf94SLang Hames if (RHS->getName().starts_with(".init_array")) { 917f04aaf94SLang Hames StringRef LHSPrioStr(LHS->getName()); 918f04aaf94SLang Hames StringRef RHSPrioStr(RHS->getName()); 919f04aaf94SLang Hames uint64_t LHSPriority; 920f04aaf94SLang Hames bool LHSHasPriority = LHSPrioStr.consume_front(".init_array.") && 921f04aaf94SLang Hames !LHSPrioStr.getAsInteger(10, LHSPriority); 922f04aaf94SLang Hames uint64_t RHSPriority; 923f04aaf94SLang Hames bool RHSHasPriority = RHSPrioStr.consume_front(".init_array.") && 924f04aaf94SLang Hames !RHSPrioStr.getAsInteger(10, RHSPriority); 925f04aaf94SLang Hames if (LHSHasPriority) 926f04aaf94SLang Hames return RHSHasPriority ? LHSPriority < RHSPriority : true; 927f04aaf94SLang Hames else if (RHSHasPriority) 928f04aaf94SLang Hames return false; 929f04aaf94SLang Hames // If we get here we'll fall through to the 930f04aaf94SLang Hames // LHS->getName() < RHS->getName() test below. 931f04aaf94SLang Hames } else { 932f04aaf94SLang Hames // .init_array[.N] comes before any non-.init_array[.N] section. 933f04aaf94SLang Hames return true; 934b749ef9eSLang Hames } 935b749ef9eSLang Hames } 936f04aaf94SLang Hames return LHS->getName() < RHS->getName(); 937f04aaf94SLang Hames }); 938f04aaf94SLang Hames 939f04aaf94SLang Hames for (auto &Sec : OrderedInitSections) 940f04aaf94SLang Hames ELFNixPlatformSecs.push_back(jitlink::SectionRange(*Sec).getRange()); 941b749ef9eSLang Hames 942b749ef9eSLang Hames // Dump the scraped inits. 943b749ef9eSLang Hames LLVM_DEBUG({ 944b749ef9eSLang Hames dbgs() << "ELFNixPlatform: Scraped " << G.getName() << " init sections:\n"; 945f597ce03SSahilPatidar for (auto &Sec : G.sections()) { 946f597ce03SSahilPatidar jitlink::SectionRange R(Sec); 947f597ce03SSahilPatidar dbgs() << " " << Sec.getName() << ": " << R.getRange() << "\n"; 948b749ef9eSLang Hames } 949b749ef9eSLang Hames }); 950b749ef9eSLang Hames 951f597ce03SSahilPatidar ExecutorAddr HeaderAddr; 952f597ce03SSahilPatidar { 953f597ce03SSahilPatidar std::lock_guard<std::mutex> Lock(MP.PlatformMutex); 954f597ce03SSahilPatidar auto I = MP.JITDylibToHandleAddr.find(&JD); 955f597ce03SSahilPatidar assert(I != MP.JITDylibToHandleAddr.end() && "No header registered for JD"); 956f597ce03SSahilPatidar assert(I->second && "Null header registered for JD"); 957f597ce03SSahilPatidar HeaderAddr = I->second; 958f597ce03SSahilPatidar } 959f597ce03SSahilPatidar 960f597ce03SSahilPatidar using SPSRegisterInitSectionsArgs = 961f597ce03SSahilPatidar SPSArgList<SPSExecutorAddr, SPSSequence<SPSExecutorAddrRange>>; 962f597ce03SSahilPatidar 963f597ce03SSahilPatidar if (LLVM_UNLIKELY(IsBootstrapping)) { 964f597ce03SSahilPatidar MP.Bootstrap.load()->addArgumentsToRTFnMap( 965f597ce03SSahilPatidar &MP.RegisterInitSections, &MP.DeregisterInitSections, 966f597ce03SSahilPatidar getArgDataBufferType<SPSRegisterInitSectionsArgs>(HeaderAddr, 967f597ce03SSahilPatidar ELFNixPlatformSecs), 968f597ce03SSahilPatidar getArgDataBufferType<SPSRegisterInitSectionsArgs>(HeaderAddr, 969f597ce03SSahilPatidar ELFNixPlatformSecs)); 970f597ce03SSahilPatidar return Error::success(); 971f597ce03SSahilPatidar } 972f597ce03SSahilPatidar 973f597ce03SSahilPatidar G.allocActions().push_back( 974f597ce03SSahilPatidar {cantFail(WrapperFunctionCall::Create<SPSRegisterInitSectionsArgs>( 975f597ce03SSahilPatidar MP.RegisterInitSections.Addr, HeaderAddr, ELFNixPlatformSecs)), 976f597ce03SSahilPatidar cantFail(WrapperFunctionCall::Create<SPSRegisterInitSectionsArgs>( 977f597ce03SSahilPatidar MP.DeregisterInitSections.Addr, HeaderAddr, ELFNixPlatformSecs))}); 978f597ce03SSahilPatidar 979f597ce03SSahilPatidar return Error::success(); 980b749ef9eSLang Hames } 981b749ef9eSLang Hames 982b749ef9eSLang Hames Error ELFNixPlatform::ELFNixPlatformPlugin::fixTLVSectionsAndEdges( 983b749ef9eSLang Hames jitlink::LinkGraph &G, JITDylib &JD) { 9842ccf7ed2SJared Wyles auto TLSGetAddrSymbolName = G.intern("__tls_get_addr"); 9852ccf7ed2SJared Wyles auto TLSDescResolveSymbolName = G.intern("__tlsdesc_resolver"); 98630b6c51fSSunho Kim for (auto *Sym : G.external_symbols()) { 9872ccf7ed2SJared Wyles if (Sym->getName() == TLSGetAddrSymbolName) { 9882ccf7ed2SJared Wyles auto TLSGetAddr = 9892ccf7ed2SJared Wyles MP.getExecutionSession().intern("___orc_rt_elfnix_tls_get_addr"); 9902ccf7ed2SJared Wyles Sym->setName(std::move(TLSGetAddr)); 9912ccf7ed2SJared Wyles } else if (Sym->getName() == TLSDescResolveSymbolName) { 9922ccf7ed2SJared Wyles auto TLSGetAddr = 9932ccf7ed2SJared Wyles MP.getExecutionSession().intern("___orc_rt_elfnix_tlsdesc_resolver"); 9942ccf7ed2SJared Wyles Sym->setName(std::move(TLSGetAddr)); 99530b6c51fSSunho Kim } 996ff6069b8Sluxufan } 997ff6069b8Sluxufan 998ff6069b8Sluxufan auto *TLSInfoEntrySection = G.findSectionByName("$__TLSINFO"); 999ff6069b8Sluxufan 1000ff6069b8Sluxufan if (TLSInfoEntrySection) { 10016698a2b6SKazu Hirata std::optional<uint64_t> Key; 1002ff6069b8Sluxufan { 1003ff6069b8Sluxufan std::lock_guard<std::mutex> Lock(MP.PlatformMutex); 1004ff6069b8Sluxufan auto I = MP.JITDylibToPThreadKey.find(&JD); 1005ff6069b8Sluxufan if (I != MP.JITDylibToPThreadKey.end()) 1006ff6069b8Sluxufan Key = I->second; 1007ff6069b8Sluxufan } 1008ff6069b8Sluxufan if (!Key) { 1009ff6069b8Sluxufan if (auto KeyOrErr = MP.createPThreadKey()) 1010ff6069b8Sluxufan Key = *KeyOrErr; 1011ff6069b8Sluxufan else 1012ff6069b8Sluxufan return KeyOrErr.takeError(); 1013ff6069b8Sluxufan } 1014ff6069b8Sluxufan 1015ff6069b8Sluxufan uint64_t PlatformKeyBits = 1016ff6069b8Sluxufan support::endian::byte_swap(*Key, G.getEndianness()); 1017ff6069b8Sluxufan 1018ff6069b8Sluxufan for (auto *B : TLSInfoEntrySection->blocks()) { 1019ff6069b8Sluxufan // FIXME: The TLS descriptor byte length may different with different 1020ff6069b8Sluxufan // ISA 1021ff6069b8Sluxufan assert(B->getSize() == (G.getPointerSize() * 2) && 1022ff6069b8Sluxufan "TLS descriptor must be 2 words length"); 1023ff6069b8Sluxufan auto TLSInfoEntryContent = B->getMutableContent(G); 1024ff6069b8Sluxufan memcpy(TLSInfoEntryContent.data(), &PlatformKeyBits, G.getPointerSize()); 1025ff6069b8Sluxufan } 1026ff6069b8Sluxufan } 1027b749ef9eSLang Hames 1028b749ef9eSLang Hames return Error::success(); 1029b749ef9eSLang Hames } 1030b749ef9eSLang Hames 1031b749ef9eSLang Hames } // End namespace orc. 1032b749ef9eSLang Hames } // End namespace llvm. 1033