1 //===-------------------- Layer.cpp - Layer interfaces --------------------===// 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/Layer.h" 10 11 #include "llvm/ExecutionEngine/Orc/DebugUtils.h" 12 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/Object/MachO.h" 15 #include "llvm/Object/ObjectFile.h" 16 #include "llvm/Support/Debug.h" 17 18 #define DEBUG_TYPE "orc" 19 20 namespace llvm { 21 namespace orc { 22 23 IRLayer::~IRLayer() {} 24 25 Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) { 26 return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>( 27 *this, *getManglingOptions(), std::move(TSM), std::move(K))); 28 } 29 30 IRMaterializationUnit::IRMaterializationUnit( 31 ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, 32 ThreadSafeModule TSM, VModuleKey K) 33 : MaterializationUnit(SymbolFlagsMap(), nullptr, std::move(K)), 34 TSM(std::move(TSM)) { 35 36 assert(this->TSM && "Module must not be null"); 37 38 MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout()); 39 this->TSM.withModuleDo([&](Module &M) { 40 for (auto &G : M.global_values()) { 41 // Skip globals that don't generate symbols. 42 43 if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() || 44 G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage()) 45 continue; 46 47 // thread locals generate different symbols depending on whether or not 48 // emulated TLS is enabled. 49 if (G.isThreadLocal() && MO.EmulatedTLS) { 50 auto &GV = cast<GlobalVariable>(G); 51 52 auto Flags = JITSymbolFlags::fromGlobalValue(GV); 53 54 auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str()); 55 SymbolFlags[EmuTLSV] = Flags; 56 SymbolToDefinition[EmuTLSV] = &GV; 57 58 // If this GV has a non-zero initializer we'll need to emit an 59 // __emutls.t symbol too. 60 if (GV.hasInitializer()) { 61 const auto *InitVal = GV.getInitializer(); 62 63 // Skip zero-initializers. 64 if (isa<ConstantAggregateZero>(InitVal)) 65 continue; 66 const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal); 67 if (InitIntValue && InitIntValue->isZero()) 68 continue; 69 70 auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str()); 71 SymbolFlags[EmuTLST] = Flags; 72 } 73 continue; 74 } 75 76 // Otherwise we just need a normal linker mangling. 77 auto MangledName = Mangle(G.getName()); 78 SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); 79 SymbolToDefinition[MangledName] = &G; 80 } 81 82 // If we need an init symbol for this module then create one. 83 if (!llvm::empty(getStaticInitGVs(M))) { 84 std::string InitSymbolName; 85 raw_string_ostream(InitSymbolName) 86 << "$." << M.getModuleIdentifier() << ".__inits"; 87 InitSymbol = ES.intern(InitSymbolName); 88 SymbolFlags[InitSymbol] = JITSymbolFlags(); 89 } 90 }); 91 } 92 93 IRMaterializationUnit::IRMaterializationUnit( 94 ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags, 95 SymbolStringPtr InitSymbol, SymbolNameToDefinitionMap SymbolToDefinition) 96 : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol), 97 std::move(K)), 98 TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {} 99 100 StringRef IRMaterializationUnit::getName() const { 101 if (TSM) 102 return TSM.withModuleDo( 103 [](const Module &M) -> StringRef { return M.getModuleIdentifier(); }); 104 return "<null module>"; 105 } 106 107 void IRMaterializationUnit::discard(const JITDylib &JD, 108 const SymbolStringPtr &Name) { 109 LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() { 110 dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@" 111 << this << " (" << getName() << ")\n"; 112 });); 113 114 auto I = SymbolToDefinition.find(Name); 115 assert(I != SymbolToDefinition.end() && 116 "Symbol not provided by this MU, or previously discarded"); 117 assert(!I->second->isDeclaration() && 118 "Discard should only apply to definitions"); 119 I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); 120 SymbolToDefinition.erase(I); 121 } 122 123 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 124 IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, 125 VModuleKey K) 126 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM), 127 std::move(K)), 128 L(L), K(std::move(K)) {} 129 130 void BasicIRLayerMaterializationUnit::materialize( 131 MaterializationResponsibility R) { 132 133 // Throw away the SymbolToDefinition map: it's not usable after we hand 134 // off the module. 135 SymbolToDefinition.clear(); 136 137 // If cloneToNewContextOnEmit is set, clone the module now. 138 if (L.getCloneToNewContextOnEmit()) 139 TSM = cloneToNewContext(TSM); 140 141 #ifndef NDEBUG 142 auto &ES = R.getTargetJITDylib().getExecutionSession(); 143 auto &N = R.getTargetJITDylib().getName(); 144 #endif // NDEBUG 145 146 LLVM_DEBUG(ES.runSessionLocked( 147 [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; });); 148 L.emit(std::move(R), std::move(TSM)); 149 LLVM_DEBUG(ES.runSessionLocked([&]() { 150 dbgs() << "Finished emitting, for " << N << ", " << *this << "\n"; 151 });); 152 } 153 154 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 155 156 ObjectLayer::~ObjectLayer() {} 157 158 Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O, 159 VModuleKey K) { 160 auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K), 161 std::move(O)); 162 if (!ObjMU) 163 return ObjMU.takeError(); 164 return JD.define(std::move(*ObjMU)); 165 } 166 167 Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 168 BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, VModuleKey K, 169 std::unique_ptr<MemoryBuffer> O) { 170 auto ObjSymInfo = 171 getObjectSymbolInfo(L.getExecutionSession(), O->getMemBufferRef()); 172 173 if (!ObjSymInfo) 174 return ObjSymInfo.takeError(); 175 176 auto &SymbolFlags = ObjSymInfo->first; 177 auto &InitSymbol = ObjSymInfo->second; 178 179 return std::unique_ptr<BasicObjectLayerMaterializationUnit>( 180 new BasicObjectLayerMaterializationUnit( 181 L, K, std::move(O), std::move(SymbolFlags), std::move(InitSymbol))); 182 } 183 184 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 185 ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O, 186 SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) 187 : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol), 188 std::move(K)), 189 L(L), O(std::move(O)) {} 190 191 StringRef BasicObjectLayerMaterializationUnit::getName() const { 192 if (O) 193 return O->getBufferIdentifier(); 194 return "<null object>"; 195 } 196 197 void BasicObjectLayerMaterializationUnit::materialize( 198 MaterializationResponsibility R) { 199 L.emit(std::move(R), std::move(O)); 200 } 201 202 void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD, 203 const SymbolStringPtr &Name) { 204 // This is a no-op for object files: Having removed 'Name' from SymbolFlags 205 // the symbol will be dead-stripped by the JIT linker. 206 } 207 208 } // End namespace orc. 209 } // End namespace llvm. 210