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