1*b3d2548dSLang Hames //===----- LinkGraphLayer.cpp - Add LinkGraphs to an ExecutionSession -----===// 2*b3d2548dSLang Hames // 3*b3d2548dSLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*b3d2548dSLang Hames // See https://llvm.org/LICENSE.txt for license information. 5*b3d2548dSLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*b3d2548dSLang Hames // 7*b3d2548dSLang Hames //===----------------------------------------------------------------------===// 8*b3d2548dSLang Hames 9*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/LinkGraphLayer.h" 10*b3d2548dSLang Hames 11*b3d2548dSLang Hames #include "llvm/ExecutionEngine/JITLink/JITLink.h" 12*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h" 13*b3d2548dSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h" 14*b3d2548dSLang Hames 15*b3d2548dSLang Hames #define DEBUG_TYPE "orc" 16*b3d2548dSLang Hames 17*b3d2548dSLang Hames using namespace llvm; 18*b3d2548dSLang Hames using namespace llvm::jitlink; 19*b3d2548dSLang Hames using namespace llvm::orc; 20*b3d2548dSLang Hames 21*b3d2548dSLang Hames namespace { 22*b3d2548dSLang Hames 23*b3d2548dSLang Hames bool hasInitializerSection(LinkGraph &G) { 24*b3d2548dSLang Hames bool IsMachO = G.getTargetTriple().isOSBinFormatMachO(); 25*b3d2548dSLang Hames bool IsElf = G.getTargetTriple().isOSBinFormatELF(); 26*b3d2548dSLang Hames if (!IsMachO && !IsElf) 27*b3d2548dSLang Hames return false; 28*b3d2548dSLang Hames 29*b3d2548dSLang Hames for (auto &Sec : G.sections()) { 30*b3d2548dSLang Hames if (IsMachO && isMachOInitializerSection(Sec.getName())) 31*b3d2548dSLang Hames return true; 32*b3d2548dSLang Hames if (IsElf && isELFInitializerSection(Sec.getName())) 33*b3d2548dSLang Hames return true; 34*b3d2548dSLang Hames } 35*b3d2548dSLang Hames 36*b3d2548dSLang Hames return false; 37*b3d2548dSLang Hames } 38*b3d2548dSLang Hames 39*b3d2548dSLang Hames } // end anonymous namespace 40*b3d2548dSLang Hames 41*b3d2548dSLang Hames namespace llvm::orc { 42*b3d2548dSLang Hames 43*b3d2548dSLang Hames LinkGraphLayer::~LinkGraphLayer() = default; 44*b3d2548dSLang Hames 45*b3d2548dSLang Hames MaterializationUnit::Interface LinkGraphLayer::getInterface(LinkGraph &G) { 46*b3d2548dSLang Hames 47*b3d2548dSLang Hames MaterializationUnit::Interface LGI; 48*b3d2548dSLang Hames 49*b3d2548dSLang Hames auto AddSymbol = [&](Symbol *Sym) { 50*b3d2548dSLang Hames // Skip local symbols. 51*b3d2548dSLang Hames if (Sym->getScope() == Scope::Local) 52*b3d2548dSLang Hames return; 53*b3d2548dSLang Hames assert(Sym->hasName() && "Anonymous non-local symbol?"); 54*b3d2548dSLang Hames 55*b3d2548dSLang Hames LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym); 56*b3d2548dSLang Hames }; 57*b3d2548dSLang Hames 58*b3d2548dSLang Hames for (auto *Sym : G.defined_symbols()) 59*b3d2548dSLang Hames AddSymbol(Sym); 60*b3d2548dSLang Hames for (auto *Sym : G.absolute_symbols()) 61*b3d2548dSLang Hames AddSymbol(Sym); 62*b3d2548dSLang Hames 63*b3d2548dSLang Hames if (hasInitializerSection(G)) { 64*b3d2548dSLang Hames std::string InitSymString; 65*b3d2548dSLang Hames { 66*b3d2548dSLang Hames raw_string_ostream(InitSymString) 67*b3d2548dSLang Hames << "$." << G.getName() << ".__inits" << Counter++; 68*b3d2548dSLang Hames } 69*b3d2548dSLang Hames LGI.InitSymbol = ES.intern(InitSymString); 70*b3d2548dSLang Hames } 71*b3d2548dSLang Hames 72*b3d2548dSLang Hames return LGI; 73*b3d2548dSLang Hames } 74*b3d2548dSLang Hames 75*b3d2548dSLang Hames JITSymbolFlags LinkGraphLayer::getJITSymbolFlagsForSymbol(Symbol &Sym) { 76*b3d2548dSLang Hames JITSymbolFlags Flags; 77*b3d2548dSLang Hames 78*b3d2548dSLang Hames if (Sym.getLinkage() == Linkage::Weak) 79*b3d2548dSLang Hames Flags |= JITSymbolFlags::Weak; 80*b3d2548dSLang Hames 81*b3d2548dSLang Hames if (Sym.getScope() == Scope::Default) 82*b3d2548dSLang Hames Flags |= JITSymbolFlags::Exported; 83*b3d2548dSLang Hames else if (Sym.getScope() == Scope::SideEffectsOnly) 84*b3d2548dSLang Hames Flags |= JITSymbolFlags::MaterializationSideEffectsOnly; 85*b3d2548dSLang Hames 86*b3d2548dSLang Hames if (Sym.isCallable()) 87*b3d2548dSLang Hames Flags |= JITSymbolFlags::Callable; 88*b3d2548dSLang Hames 89*b3d2548dSLang Hames return Flags; 90*b3d2548dSLang Hames } 91*b3d2548dSLang Hames 92*b3d2548dSLang Hames StringRef LinkGraphMaterializationUnit::getName() const { return G->getName(); } 93*b3d2548dSLang Hames 94*b3d2548dSLang Hames void LinkGraphMaterializationUnit::discard(const JITDylib &JD, 95*b3d2548dSLang Hames const SymbolStringPtr &Name) { 96*b3d2548dSLang Hames for (auto *Sym : G->defined_symbols()) 97*b3d2548dSLang Hames if (Sym->getName() == Name) { 98*b3d2548dSLang Hames assert(Sym->getLinkage() == Linkage::Weak && 99*b3d2548dSLang Hames "Discarding non-weak definition"); 100*b3d2548dSLang Hames G->makeExternal(*Sym); 101*b3d2548dSLang Hames break; 102*b3d2548dSLang Hames } 103*b3d2548dSLang Hames } 104*b3d2548dSLang Hames 105*b3d2548dSLang Hames } // namespace llvm::orc 106