Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
35266 views
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
616