1 //===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===// 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/ExecutionUtils.h" 10 #include "llvm/ExecutionEngine/JITLink/x86_64.h" 11 #include "llvm/ExecutionEngine/Orc/Layer.h" 12 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/GlobalVariable.h" 16 #include "llvm/IR/Module.h" 17 #include "llvm/MC/TargetRegistry.h" 18 #include "llvm/Object/MachOUniversal.h" 19 #include "llvm/Support/FormatVariadic.h" 20 #include "llvm/Target/TargetMachine.h" 21 #include <string> 22 23 namespace llvm { 24 namespace orc { 25 26 CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) 27 : InitList( 28 GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), 29 I((InitList && End) ? InitList->getNumOperands() : 0) { 30 } 31 32 bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { 33 assert(InitList == Other.InitList && "Incomparable iterators."); 34 return I == Other.I; 35 } 36 37 bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { 38 return !(*this == Other); 39 } 40 41 CtorDtorIterator& CtorDtorIterator::operator++() { 42 ++I; 43 return *this; 44 } 45 46 CtorDtorIterator CtorDtorIterator::operator++(int) { 47 CtorDtorIterator Temp = *this; 48 ++I; 49 return Temp; 50 } 51 52 CtorDtorIterator::Element CtorDtorIterator::operator*() const { 53 ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); 54 assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); 55 56 Constant *FuncC = CS->getOperand(1); 57 Function *Func = nullptr; 58 59 // Extract function pointer, pulling off any casts. 60 while (FuncC) { 61 if (Function *F = dyn_cast_or_null<Function>(FuncC)) { 62 Func = F; 63 break; 64 } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { 65 if (CE->isCast()) 66 FuncC = CE->getOperand(0); 67 else 68 break; 69 } else { 70 // This isn't anything we recognize. Bail out with Func left set to null. 71 break; 72 } 73 } 74 75 auto *Priority = cast<ConstantInt>(CS->getOperand(0)); 76 Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; 77 if (Data && !isa<GlobalValue>(Data)) 78 Data = nullptr; 79 return Element(Priority->getZExtValue(), Func, Data); 80 } 81 82 iterator_range<CtorDtorIterator> getConstructors(const Module &M) { 83 const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); 84 return make_range(CtorDtorIterator(CtorsList, false), 85 CtorDtorIterator(CtorsList, true)); 86 } 87 88 iterator_range<CtorDtorIterator> getDestructors(const Module &M) { 89 const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); 90 return make_range(CtorDtorIterator(DtorsList, false), 91 CtorDtorIterator(DtorsList, true)); 92 } 93 94 bool StaticInitGVIterator::isStaticInitGlobal(GlobalValue &GV) { 95 if (GV.isDeclaration()) 96 return false; 97 98 if (GV.hasName() && (GV.getName() == "llvm.global_ctors" || 99 GV.getName() == "llvm.global_dtors")) 100 return true; 101 102 if (ObjFmt == Triple::MachO) { 103 // FIXME: These section checks are too strict: We should match first and 104 // second word split by comma. 105 if (GV.hasSection() && 106 (GV.getSection().startswith("__DATA,__objc_classlist") || 107 GV.getSection().startswith("__DATA,__objc_selrefs"))) 108 return true; 109 } 110 111 return false; 112 } 113 114 void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { 115 if (CtorDtors.empty()) 116 return; 117 118 MangleAndInterner Mangle( 119 JD.getExecutionSession(), 120 (*CtorDtors.begin()).Func->getParent()->getDataLayout()); 121 122 for (auto CtorDtor : CtorDtors) { 123 assert(CtorDtor.Func && CtorDtor.Func->hasName() && 124 "Ctor/Dtor function must be named to be runnable under the JIT"); 125 126 // FIXME: Maybe use a symbol promoter here instead. 127 if (CtorDtor.Func->hasLocalLinkage()) { 128 CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage); 129 CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility); 130 } 131 132 if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) { 133 dbgs() << " Skipping because why now?\n"; 134 continue; 135 } 136 137 CtorDtorsByPriority[CtorDtor.Priority].push_back( 138 Mangle(CtorDtor.Func->getName())); 139 } 140 } 141 142 Error CtorDtorRunner::run() { 143 using CtorDtorTy = void (*)(); 144 145 SymbolLookupSet LookupSet; 146 for (auto &KV : CtorDtorsByPriority) 147 for (auto &Name : KV.second) 148 LookupSet.add(Name); 149 assert(!LookupSet.containsDuplicates() && 150 "Ctor/Dtor list contains duplicates"); 151 152 auto &ES = JD.getExecutionSession(); 153 if (auto CtorDtorMap = ES.lookup( 154 makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 155 std::move(LookupSet))) { 156 for (auto &KV : CtorDtorsByPriority) { 157 for (auto &Name : KV.second) { 158 assert(CtorDtorMap->count(Name) && "No entry for Name"); 159 auto CtorDtor = reinterpret_cast<CtorDtorTy>( 160 static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress())); 161 CtorDtor(); 162 } 163 } 164 CtorDtorsByPriority.clear(); 165 return Error::success(); 166 } else 167 return CtorDtorMap.takeError(); 168 } 169 170 void LocalCXXRuntimeOverridesBase::runDestructors() { 171 auto& CXXDestructorDataPairs = DSOHandleOverride; 172 for (auto &P : CXXDestructorDataPairs) 173 P.first(P.second); 174 CXXDestructorDataPairs.clear(); 175 } 176 177 int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, 178 void *Arg, 179 void *DSOHandle) { 180 auto& CXXDestructorDataPairs = 181 *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); 182 CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); 183 return 0; 184 } 185 186 Error LocalCXXRuntimeOverrides::enable(JITDylib &JD, 187 MangleAndInterner &Mangle) { 188 SymbolMap RuntimeInterposes; 189 RuntimeInterposes[Mangle("__dso_handle")] = 190 JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), 191 JITSymbolFlags::Exported); 192 RuntimeInterposes[Mangle("__cxa_atexit")] = 193 JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), 194 JITSymbolFlags::Exported); 195 196 return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); 197 } 198 199 void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx, 200 void *DSOHandle) { 201 std::lock_guard<std::mutex> Lock(AtExitsMutex); 202 AtExitRecords[DSOHandle].push_back({F, Ctx}); 203 } 204 205 void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) { 206 std::vector<AtExitRecord> AtExitsToRun; 207 208 { 209 std::lock_guard<std::mutex> Lock(AtExitsMutex); 210 auto I = AtExitRecords.find(DSOHandle); 211 if (I != AtExitRecords.end()) { 212 AtExitsToRun = std::move(I->second); 213 AtExitRecords.erase(I); 214 } 215 } 216 217 while (!AtExitsToRun.empty()) { 218 AtExitsToRun.back().F(AtExitsToRun.back().Ctx); 219 AtExitsToRun.pop_back(); 220 } 221 } 222 223 DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator( 224 sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow) 225 : Dylib(std::move(Dylib)), Allow(std::move(Allow)), 226 GlobalPrefix(GlobalPrefix) {} 227 228 Expected<std::unique_ptr<DynamicLibrarySearchGenerator>> 229 DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix, 230 SymbolPredicate Allow) { 231 std::string ErrMsg; 232 auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg); 233 if (!Lib.isValid()) 234 return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 235 return std::make_unique<DynamicLibrarySearchGenerator>( 236 std::move(Lib), GlobalPrefix, std::move(Allow)); 237 } 238 239 Error DynamicLibrarySearchGenerator::tryToGenerate( 240 LookupState &LS, LookupKind K, JITDylib &JD, 241 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 242 orc::SymbolMap NewSymbols; 243 244 bool HasGlobalPrefix = (GlobalPrefix != '\0'); 245 246 for (auto &KV : Symbols) { 247 auto &Name = KV.first; 248 249 if ((*Name).empty()) 250 continue; 251 252 if (Allow && !Allow(Name)) 253 continue; 254 255 if (HasGlobalPrefix && (*Name).front() != GlobalPrefix) 256 continue; 257 258 std::string Tmp((*Name).data() + HasGlobalPrefix, 259 (*Name).size() - HasGlobalPrefix); 260 if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) { 261 NewSymbols[Name] = JITEvaluatedSymbol( 262 static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)), 263 JITSymbolFlags::Exported); 264 } 265 } 266 267 if (NewSymbols.empty()) 268 return Error::success(); 269 270 return JD.define(absoluteSymbols(std::move(NewSymbols))); 271 } 272 273 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 274 StaticLibraryDefinitionGenerator::Load( 275 ObjectLayer &L, const char *FileName, 276 GetObjectFileInterface GetObjFileInterface) { 277 auto ArchiveBuffer = MemoryBuffer::getFile(FileName); 278 279 if (!ArchiveBuffer) 280 return createFileError(FileName, ArchiveBuffer.getError()); 281 282 return Create(L, std::move(*ArchiveBuffer), std::move(GetObjFileInterface)); 283 } 284 285 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 286 StaticLibraryDefinitionGenerator::Load( 287 ObjectLayer &L, const char *FileName, const Triple &TT, 288 GetObjectFileInterface GetObjFileInterface) { 289 290 auto B = object::createBinary(FileName); 291 if (!B) 292 return createFileError(FileName, B.takeError()); 293 294 // If this is a regular archive then create an instance from it. 295 if (isa<object::Archive>(B->getBinary())) 296 return Create(L, std::move(B->takeBinary().second), 297 std::move(GetObjFileInterface)); 298 299 // If this is a universal binary then search for a slice matching the given 300 // Triple. 301 if (auto *UB = cast<object::MachOUniversalBinary>(B->getBinary())) { 302 for (const auto &Obj : UB->objects()) { 303 auto ObjTT = Obj.getTriple(); 304 if (ObjTT.getArch() == TT.getArch() && 305 ObjTT.getSubArch() == TT.getSubArch() && 306 (TT.getVendor() == Triple::UnknownVendor || 307 ObjTT.getVendor() == TT.getVendor())) { 308 // We found a match. Create an instance from a buffer covering this 309 // slice. 310 auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, Obj.getSize(), 311 Obj.getOffset()); 312 if (!SliceBuffer) 313 return make_error<StringError>( 314 Twine("Could not create buffer for ") + TT.str() + " slice of " + 315 FileName + ": [ " + formatv("{0:x}", Obj.getOffset()) + 316 " .. " + formatv("{0:x}", Obj.getOffset() + Obj.getSize()) + 317 ": " + SliceBuffer.getError().message(), 318 SliceBuffer.getError()); 319 return Create(L, std::move(*SliceBuffer), 320 std::move(GetObjFileInterface)); 321 } 322 } 323 324 return make_error<StringError>(Twine("Universal binary ") + FileName + 325 " does not contain a slice for " + 326 TT.str(), 327 inconvertibleErrorCode()); 328 } 329 330 return make_error<StringError>(Twine("Unrecognized file type for ") + 331 FileName, 332 inconvertibleErrorCode()); 333 } 334 335 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 336 StaticLibraryDefinitionGenerator::Create( 337 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, 338 GetObjectFileInterface GetObjFileInterface) { 339 Error Err = Error::success(); 340 341 std::unique_ptr<StaticLibraryDefinitionGenerator> ADG( 342 new StaticLibraryDefinitionGenerator( 343 L, std::move(ArchiveBuffer), std::move(GetObjFileInterface), Err)); 344 345 if (Err) 346 return std::move(Err); 347 348 return std::move(ADG); 349 } 350 351 Error StaticLibraryDefinitionGenerator::tryToGenerate( 352 LookupState &LS, LookupKind K, JITDylib &JD, 353 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 354 // Don't materialize symbols from static archives unless this is a static 355 // lookup. 356 if (K != LookupKind::Static) 357 return Error::success(); 358 359 // Bail out early if we've already freed the archive. 360 if (!Archive) 361 return Error::success(); 362 363 DenseSet<std::pair<StringRef, StringRef>> ChildBufferInfos; 364 365 for (const auto &KV : Symbols) { 366 const auto &Name = KV.first; 367 if (!ObjectFilesMap.count(Name)) 368 continue; 369 auto ChildBuffer = ObjectFilesMap[Name]; 370 ChildBufferInfos.insert( 371 {ChildBuffer.getBuffer(), ChildBuffer.getBufferIdentifier()}); 372 } 373 374 for (auto ChildBufferInfo : ChildBufferInfos) { 375 MemoryBufferRef ChildBufferRef(ChildBufferInfo.first, 376 ChildBufferInfo.second); 377 378 auto I = GetObjFileInterface(L.getExecutionSession(), ChildBufferRef); 379 if (!I) 380 return I.takeError(); 381 382 if (auto Err = L.add(JD, MemoryBuffer::getMemBuffer(ChildBufferRef, false), 383 std::move(*I))) 384 return Err; 385 } 386 387 return Error::success(); 388 } 389 390 Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() { 391 DenseMap<uint64_t, MemoryBufferRef> MemoryBuffers; 392 DenseSet<uint64_t> Visited; 393 DenseSet<uint64_t> Excluded; 394 for (auto &S : Archive->symbols()) { 395 StringRef SymName = S.getName(); 396 auto Member = S.getMember(); 397 if (!Member) 398 return Member.takeError(); 399 auto DataOffset = Member->getDataOffset(); 400 if (!Visited.count(DataOffset)) { 401 Visited.insert(DataOffset); 402 auto Child = Member->getAsBinary(); 403 if (!Child) 404 return Child.takeError(); 405 if ((*Child)->isCOFFImportFile()) { 406 ImportedDynamicLibraries.insert((*Child)->getFileName().str()); 407 Excluded.insert(DataOffset); 408 continue; 409 } 410 MemoryBuffers[DataOffset] = (*Child)->getMemoryBufferRef(); 411 } 412 if (!Excluded.count(DataOffset)) 413 ObjectFilesMap[L.getExecutionSession().intern(SymName)] = 414 MemoryBuffers[DataOffset]; 415 } 416 417 return Error::success(); 418 } 419 420 StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator( 421 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, 422 GetObjectFileInterface GetObjFileInterface, Error &Err) 423 : L(L), GetObjFileInterface(std::move(GetObjFileInterface)), 424 ArchiveBuffer(std::move(ArchiveBuffer)), 425 Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) { 426 ErrorAsOutParameter _(&Err); 427 if (!this->GetObjFileInterface) 428 this->GetObjFileInterface = getObjectFileInterface; 429 if (!Err) 430 Err = buildObjectFilesMap(); 431 } 432 433 std::unique_ptr<DLLImportDefinitionGenerator> 434 DLLImportDefinitionGenerator::Create(ExecutionSession &ES, 435 ObjectLinkingLayer &L) { 436 return std::unique_ptr<DLLImportDefinitionGenerator>( 437 new DLLImportDefinitionGenerator(ES, L)); 438 } 439 440 Error DLLImportDefinitionGenerator::tryToGenerate( 441 LookupState &LS, LookupKind K, JITDylib &JD, 442 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 443 JITDylibSearchOrder LinkOrder; 444 JD.withLinkOrderDo([&](const JITDylibSearchOrder &LO) { 445 LinkOrder.reserve(LO.size()); 446 for (auto &KV : LO) { 447 if (KV.first == &JD) 448 continue; 449 LinkOrder.push_back(KV); 450 } 451 }); 452 453 // FIXME: if regular symbol name start with __imp_ we have to issue lookup of 454 // both __imp_ and stripped name and use the lookup information to resolve the 455 // real symbol name. 456 SymbolLookupSet LookupSet; 457 DenseMap<StringRef, SymbolLookupFlags> ToLookUpSymbols; 458 for (auto &KV : Symbols) { 459 StringRef Deinterned = *KV.first; 460 if (Deinterned.startswith(getImpPrefix())) 461 Deinterned = Deinterned.drop_front(StringRef(getImpPrefix()).size()); 462 // Don't degrade the required state 463 if (ToLookUpSymbols.count(Deinterned) && 464 ToLookUpSymbols[Deinterned] == SymbolLookupFlags::RequiredSymbol) 465 continue; 466 ToLookUpSymbols[Deinterned] = KV.second; 467 } 468 469 for (auto &KV : ToLookUpSymbols) 470 LookupSet.add(ES.intern(KV.first), KV.second); 471 472 auto Resolved = 473 ES.lookup(LinkOrder, LookupSet, LookupKind::DLSym, SymbolState::Resolved); 474 if (!Resolved) 475 return Resolved.takeError(); 476 477 auto G = createStubsGraph(*Resolved); 478 if (!G) 479 return G.takeError(); 480 return L.add(JD, std::move(*G)); 481 } 482 483 Expected<unsigned> 484 DLLImportDefinitionGenerator::getTargetPointerSize(const Triple &TT) { 485 switch (TT.getArch()) { 486 case Triple::x86_64: 487 return 8; 488 default: 489 return make_error<StringError>( 490 "architecture unsupported by DLLImportDefinitionGenerator", 491 inconvertibleErrorCode()); 492 } 493 } 494 495 Expected<support::endianness> 496 DLLImportDefinitionGenerator::getTargetEndianness(const Triple &TT) { 497 switch (TT.getArch()) { 498 case Triple::x86_64: 499 return support::endianness::little; 500 default: 501 return make_error<StringError>( 502 "architecture unsupported by DLLImportDefinitionGenerator", 503 inconvertibleErrorCode()); 504 } 505 } 506 507 Expected<std::unique_ptr<jitlink::LinkGraph>> 508 DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) { 509 Triple TT = ES.getExecutorProcessControl().getTargetTriple(); 510 auto PointerSize = getTargetEndianness(TT); 511 if (!PointerSize) 512 return PointerSize.takeError(); 513 auto Endianness = getTargetEndianness(TT); 514 if (!Endianness) 515 return Endianness.takeError(); 516 517 auto G = std::make_unique<jitlink::LinkGraph>( 518 "<DLLIMPORT_STUBS>", TT, *PointerSize, *Endianness, 519 jitlink::getGenericEdgeKindName); 520 jitlink::Section &Sec = 521 G->createSection(getSectionName(), MemProt::Read | MemProt::Exec); 522 523 for (auto &KV : Resolved) { 524 jitlink::Symbol &Target = G->addAbsoluteSymbol( 525 *KV.first, ExecutorAddr(KV.second.getAddress()), *PointerSize, 526 jitlink::Linkage::Strong, jitlink::Scope::Local, false); 527 528 // Create __imp_ symbol 529 jitlink::Symbol &Ptr = 530 jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target); 531 auto NameCopy = G->allocateString(Twine(getImpPrefix()) + *KV.first); 532 StringRef NameCopyRef = StringRef(NameCopy.data(), NameCopy.size()); 533 Ptr.setName(NameCopyRef); 534 Ptr.setLinkage(jitlink::Linkage::Strong); 535 Ptr.setScope(jitlink::Scope::Default); 536 537 // Create PLT stub 538 // FIXME: check PLT stub of data symbol is not accessed 539 jitlink::Block &StubBlock = 540 jitlink::x86_64::createPointerJumpStubBlock(*G, Sec, Ptr); 541 G->addDefinedSymbol(StubBlock, 0, *KV.first, StubBlock.getSize(), 542 jitlink::Linkage::Strong, jitlink::Scope::Default, true, 543 false); 544 } 545 546 return std::move(G); 547 } 548 549 } // End namespace orc. 550 } // End namespace llvm. 551