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