xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp (revision 47e073941f4e7ca6e9bde3fa65abbfcfed6bfa2b)
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 = (*CtorDtorMap)[Name].getAddress().toPtr<CtorDtorTy>();
160          CtorDtor();
161        }
162      }
163      CtorDtorsByPriority.clear();
164      return Error::success();
165    } else
166      return CtorDtorMap.takeError();
167  }
168  
169  void LocalCXXRuntimeOverridesBase::runDestructors() {
170    auto& CXXDestructorDataPairs = DSOHandleOverride;
171    for (auto &P : CXXDestructorDataPairs)
172      P.first(P.second);
173    CXXDestructorDataPairs.clear();
174  }
175  
176  int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor,
177                                                      void *Arg,
178                                                      void *DSOHandle) {
179    auto& CXXDestructorDataPairs =
180      *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
181    CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
182    return 0;
183  }
184  
185  Error LocalCXXRuntimeOverrides::enable(JITDylib &JD,
186                                          MangleAndInterner &Mangle) {
187    SymbolMap RuntimeInterposes;
188    RuntimeInterposes[Mangle("__dso_handle")] = {
189        ExecutorAddr::fromPtr(&DSOHandleOverride), JITSymbolFlags::Exported};
190    RuntimeInterposes[Mangle("__cxa_atexit")] = {
191        ExecutorAddr::fromPtr(&CXAAtExitOverride), JITSymbolFlags::Exported};
192  
193    return JD.define(absoluteSymbols(std::move(RuntimeInterposes)));
194  }
195  
196  void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx,
197                                               void *DSOHandle) {
198    std::lock_guard<std::mutex> Lock(AtExitsMutex);
199    AtExitRecords[DSOHandle].push_back({F, Ctx});
200  }
201  
202  void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) {
203    std::vector<AtExitRecord> AtExitsToRun;
204  
205    {
206      std::lock_guard<std::mutex> Lock(AtExitsMutex);
207      auto I = AtExitRecords.find(DSOHandle);
208      if (I != AtExitRecords.end()) {
209        AtExitsToRun = std::move(I->second);
210        AtExitRecords.erase(I);
211      }
212    }
213  
214    while (!AtExitsToRun.empty()) {
215      AtExitsToRun.back().F(AtExitsToRun.back().Ctx);
216      AtExitsToRun.pop_back();
217    }
218  }
219  
220  DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator(
221      sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow)
222      : Dylib(std::move(Dylib)), Allow(std::move(Allow)),
223        GlobalPrefix(GlobalPrefix) {}
224  
225  Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
226  DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix,
227                                      SymbolPredicate Allow) {
228    std::string ErrMsg;
229    auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg);
230    if (!Lib.isValid())
231      return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
232    return std::make_unique<DynamicLibrarySearchGenerator>(
233        std::move(Lib), GlobalPrefix, std::move(Allow));
234  }
235  
236  Error DynamicLibrarySearchGenerator::tryToGenerate(
237      LookupState &LS, LookupKind K, JITDylib &JD,
238      JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
239    orc::SymbolMap NewSymbols;
240  
241    bool HasGlobalPrefix = (GlobalPrefix != '\0');
242  
243    for (auto &KV : Symbols) {
244      auto &Name = KV.first;
245  
246      if ((*Name).empty())
247        continue;
248  
249      if (Allow && !Allow(Name))
250        continue;
251  
252      if (HasGlobalPrefix && (*Name).front() != GlobalPrefix)
253        continue;
254  
255      std::string Tmp((*Name).data() + HasGlobalPrefix,
256                      (*Name).size() - HasGlobalPrefix);
257      if (void *P = Dylib.getAddressOfSymbol(Tmp.c_str()))
258        NewSymbols[Name] = {ExecutorAddr::fromPtr(P), JITSymbolFlags::Exported};
259    }
260  
261    if (NewSymbols.empty())
262      return Error::success();
263  
264    return JD.define(absoluteSymbols(std::move(NewSymbols)));
265  }
266  
267  Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
268  StaticLibraryDefinitionGenerator::Load(
269      ObjectLayer &L, const char *FileName,
270      GetObjectFileInterface GetObjFileInterface) {
271  
272    auto B = object::createBinary(FileName);
273    if (!B)
274      return createFileError(FileName, B.takeError());
275  
276    // If this is a regular archive then create an instance from it.
277    if (isa<object::Archive>(B->getBinary())) {
278      auto [Archive, ArchiveBuffer] = B->takeBinary();
279      return Create(L, std::move(ArchiveBuffer),
280                    std::unique_ptr<object::Archive>(
281                        static_cast<object::Archive *>(Archive.release())),
282                    std::move(GetObjFileInterface));
283    }
284  
285    // If this is a universal binary then search for a slice matching the given
286    // Triple.
287    if (auto *UB = cast<object::MachOUniversalBinary>(B->getBinary())) {
288  
289      const auto &TT = L.getExecutionSession().getTargetTriple();
290  
291      auto SliceRange = getSliceRangeForArch(*UB, TT);
292      if (!SliceRange)
293        return SliceRange.takeError();
294  
295      auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, SliceRange->second,
296                                                    SliceRange->first);
297      if (!SliceBuffer)
298        return make_error<StringError>(
299            Twine("Could not create buffer for ") + TT.str() + " slice of " +
300                FileName + ": [ " + formatv("{0:x}", SliceRange->first) + " .. " +
301                formatv("{0:x}", SliceRange->first + SliceRange->second) + ": " +
302                SliceBuffer.getError().message(),
303            SliceBuffer.getError());
304  
305      return Create(L, std::move(*SliceBuffer), std::move(GetObjFileInterface));
306    }
307  
308    return make_error<StringError>(Twine("Unrecognized file type for ") +
309                                       FileName,
310                                   inconvertibleErrorCode());
311  }
312  
313  Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
314  StaticLibraryDefinitionGenerator::Create(
315      ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
316      std::unique_ptr<object::Archive> Archive,
317      GetObjectFileInterface GetObjFileInterface) {
318  
319    Error Err = Error::success();
320  
321    std::unique_ptr<StaticLibraryDefinitionGenerator> ADG(
322        new StaticLibraryDefinitionGenerator(
323            L, std::move(ArchiveBuffer), std::move(Archive),
324            std::move(GetObjFileInterface), Err));
325  
326    if (Err)
327      return std::move(Err);
328  
329    return std::move(ADG);
330  }
331  
332  Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
333  StaticLibraryDefinitionGenerator::Create(
334      ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
335      GetObjectFileInterface GetObjFileInterface) {
336  
337    auto B = object::createBinary(ArchiveBuffer->getMemBufferRef());
338    if (!B)
339      return B.takeError();
340  
341    // If this is a regular archive then create an instance from it.
342    if (isa<object::Archive>(*B))
343      return Create(L, std::move(ArchiveBuffer),
344                    std::unique_ptr<object::Archive>(
345                        static_cast<object::Archive *>(B->release())),
346                    std::move(GetObjFileInterface));
347  
348    // If this is a universal binary then search for a slice matching the given
349    // Triple.
350    if (auto *UB = cast<object::MachOUniversalBinary>(B->get())) {
351  
352      const auto &TT = L.getExecutionSession().getTargetTriple();
353  
354      auto SliceRange = getSliceRangeForArch(*UB, TT);
355      if (!SliceRange)
356        return SliceRange.takeError();
357  
358      MemoryBufferRef SliceRef(
359          StringRef(ArchiveBuffer->getBufferStart() + SliceRange->first,
360                    SliceRange->second),
361          ArchiveBuffer->getBufferIdentifier());
362  
363      auto Archive = object::Archive::create(SliceRef);
364      if (!Archive)
365        return Archive.takeError();
366  
367      return Create(L, std::move(ArchiveBuffer), std::move(*Archive),
368                    std::move(GetObjFileInterface));
369    }
370  
371    return make_error<StringError>(Twine("Unrecognized file type for ") +
372                                       ArchiveBuffer->getBufferIdentifier(),
373                                   inconvertibleErrorCode());
374  }
375  
376  Error StaticLibraryDefinitionGenerator::tryToGenerate(
377      LookupState &LS, LookupKind K, JITDylib &JD,
378      JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
379    // Don't materialize symbols from static archives unless this is a static
380    // lookup.
381    if (K != LookupKind::Static)
382      return Error::success();
383  
384    // Bail out early if we've already freed the archive.
385    if (!Archive)
386      return Error::success();
387  
388    DenseSet<std::pair<StringRef, StringRef>> ChildBufferInfos;
389  
390    for (const auto &KV : Symbols) {
391      const auto &Name = KV.first;
392      if (!ObjectFilesMap.count(Name))
393        continue;
394      auto ChildBuffer = ObjectFilesMap[Name];
395      ChildBufferInfos.insert(
396          {ChildBuffer.getBuffer(), ChildBuffer.getBufferIdentifier()});
397    }
398  
399    for (auto ChildBufferInfo : ChildBufferInfos) {
400      MemoryBufferRef ChildBufferRef(ChildBufferInfo.first,
401                                     ChildBufferInfo.second);
402  
403      auto I = GetObjFileInterface(L.getExecutionSession(), ChildBufferRef);
404      if (!I)
405        return I.takeError();
406  
407      if (auto Err = L.add(JD, MemoryBuffer::getMemBuffer(ChildBufferRef, false),
408                           std::move(*I)))
409        return Err;
410    }
411  
412    return Error::success();
413  }
414  
415  Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() {
416    DenseMap<uint64_t, MemoryBufferRef> MemoryBuffers;
417    DenseSet<uint64_t> Visited;
418    DenseSet<uint64_t> Excluded;
419    for (auto &S : Archive->symbols()) {
420      StringRef SymName = S.getName();
421      auto Member = S.getMember();
422      if (!Member)
423        return Member.takeError();
424      auto DataOffset = Member->getDataOffset();
425      if (!Visited.count(DataOffset)) {
426        Visited.insert(DataOffset);
427        auto Child = Member->getAsBinary();
428        if (!Child)
429          return Child.takeError();
430        if ((*Child)->isCOFFImportFile()) {
431          ImportedDynamicLibraries.insert((*Child)->getFileName().str());
432          Excluded.insert(DataOffset);
433          continue;
434        }
435        MemoryBuffers[DataOffset] = (*Child)->getMemoryBufferRef();
436      }
437      if (!Excluded.count(DataOffset))
438        ObjectFilesMap[L.getExecutionSession().intern(SymName)] =
439            MemoryBuffers[DataOffset];
440    }
441  
442    return Error::success();
443  }
444  
445  Expected<std::pair<size_t, size_t>>
446  StaticLibraryDefinitionGenerator::getSliceRangeForArch(
447      object::MachOUniversalBinary &UB, const Triple &TT) {
448  
449    for (const auto &Obj : UB.objects()) {
450      auto ObjTT = Obj.getTriple();
451      if (ObjTT.getArch() == TT.getArch() &&
452          ObjTT.getSubArch() == TT.getSubArch() &&
453          (TT.getVendor() == Triple::UnknownVendor ||
454           ObjTT.getVendor() == TT.getVendor())) {
455        // We found a match. Return the range for the slice.
456        return std::make_pair(Obj.getOffset(), Obj.getSize());
457      }
458    }
459  
460    return make_error<StringError>(Twine("Universal binary ") + UB.getFileName() +
461                                       " does not contain a slice for " +
462                                       TT.str(),
463                                   inconvertibleErrorCode());
464  }
465  
466  StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
467      ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
468      std::unique_ptr<object::Archive> Archive,
469      GetObjectFileInterface GetObjFileInterface, Error &Err)
470      : L(L), GetObjFileInterface(std::move(GetObjFileInterface)),
471        ArchiveBuffer(std::move(ArchiveBuffer)), Archive(std::move(Archive)) {
472    ErrorAsOutParameter _(&Err);
473    if (!this->GetObjFileInterface)
474      this->GetObjFileInterface = getObjectFileInterface;
475    if (!Err)
476      Err = buildObjectFilesMap();
477  }
478  
479  std::unique_ptr<DLLImportDefinitionGenerator>
480  DLLImportDefinitionGenerator::Create(ExecutionSession &ES,
481                                       ObjectLinkingLayer &L) {
482    return std::unique_ptr<DLLImportDefinitionGenerator>(
483        new DLLImportDefinitionGenerator(ES, L));
484  }
485  
486  Error DLLImportDefinitionGenerator::tryToGenerate(
487      LookupState &LS, LookupKind K, JITDylib &JD,
488      JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
489    JITDylibSearchOrder LinkOrder;
490    JD.withLinkOrderDo([&](const JITDylibSearchOrder &LO) {
491      LinkOrder.reserve(LO.size());
492      for (auto &KV : LO) {
493        if (KV.first == &JD)
494          continue;
495        LinkOrder.push_back(KV);
496      }
497    });
498  
499    // FIXME: if regular symbol name start with __imp_ we have to issue lookup of
500    // both __imp_ and stripped name and use the lookup information to resolve the
501    // real symbol name.
502    SymbolLookupSet LookupSet;
503    DenseMap<StringRef, SymbolLookupFlags> ToLookUpSymbols;
504    for (auto &KV : Symbols) {
505      StringRef Deinterned = *KV.first;
506      if (Deinterned.startswith(getImpPrefix()))
507        Deinterned = Deinterned.drop_front(StringRef(getImpPrefix()).size());
508      // Don't degrade the required state
509      if (ToLookUpSymbols.count(Deinterned) &&
510          ToLookUpSymbols[Deinterned] == SymbolLookupFlags::RequiredSymbol)
511        continue;
512      ToLookUpSymbols[Deinterned] = KV.second;
513    }
514  
515    for (auto &KV : ToLookUpSymbols)
516      LookupSet.add(ES.intern(KV.first), KV.second);
517  
518    auto Resolved =
519        ES.lookup(LinkOrder, LookupSet, LookupKind::DLSym, SymbolState::Resolved);
520    if (!Resolved)
521      return Resolved.takeError();
522  
523    auto G = createStubsGraph(*Resolved);
524    if (!G)
525      return G.takeError();
526    return L.add(JD, std::move(*G));
527  }
528  
529  Expected<unsigned>
530  DLLImportDefinitionGenerator::getTargetPointerSize(const Triple &TT) {
531    switch (TT.getArch()) {
532    case Triple::x86_64:
533      return 8;
534    default:
535      return make_error<StringError>(
536          "architecture unsupported by DLLImportDefinitionGenerator",
537          inconvertibleErrorCode());
538    }
539  }
540  
541  Expected<support::endianness>
542  DLLImportDefinitionGenerator::getTargetEndianness(const Triple &TT) {
543    switch (TT.getArch()) {
544    case Triple::x86_64:
545      return support::endianness::little;
546    default:
547      return make_error<StringError>(
548          "architecture unsupported by DLLImportDefinitionGenerator",
549          inconvertibleErrorCode());
550    }
551  }
552  
553  Expected<std::unique_ptr<jitlink::LinkGraph>>
554  DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
555    Triple TT = ES.getTargetTriple();
556    auto PointerSize = getTargetEndianness(TT);
557    if (!PointerSize)
558      return PointerSize.takeError();
559    auto Endianness = getTargetEndianness(TT);
560    if (!Endianness)
561      return Endianness.takeError();
562  
563    auto G = std::make_unique<jitlink::LinkGraph>(
564        "<DLLIMPORT_STUBS>", TT, *PointerSize, *Endianness,
565        jitlink::getGenericEdgeKindName);
566    jitlink::Section &Sec =
567        G->createSection(getSectionName(), MemProt::Read | MemProt::Exec);
568  
569    for (auto &KV : Resolved) {
570      jitlink::Symbol &Target = G->addAbsoluteSymbol(
571          *KV.first, KV.second.getAddress(), *PointerSize,
572          jitlink::Linkage::Strong, jitlink::Scope::Local, false);
573  
574      // Create __imp_ symbol
575      jitlink::Symbol &Ptr =
576          jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target);
577      auto NameCopy = G->allocateContent(Twine(getImpPrefix()) + *KV.first);
578      StringRef NameCopyRef = StringRef(NameCopy.data(), NameCopy.size());
579      Ptr.setName(NameCopyRef);
580      Ptr.setLinkage(jitlink::Linkage::Strong);
581      Ptr.setScope(jitlink::Scope::Default);
582  
583      // Create PLT stub
584      // FIXME: check PLT stub of data symbol is not accessed
585      jitlink::Block &StubBlock =
586          jitlink::x86_64::createPointerJumpStubBlock(*G, Sec, Ptr);
587      G->addDefinedSymbol(StubBlock, 0, *KV.first, StubBlock.getSize(),
588                          jitlink::Linkage::Strong, jitlink::Scope::Default, true,
589                          false);
590    }
591  
592    return std::move(G);
593  }
594  
595  } // End namespace orc.
596  } // End namespace llvm.
597