Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
35266 views
1
//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
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 "MCJIT.h"
10
#include "llvm/ADT/STLExtras.h"
11
#include "llvm/ExecutionEngine/GenericValue.h"
12
#include "llvm/ExecutionEngine/JITEventListener.h"
13
#include "llvm/ExecutionEngine/MCJIT.h"
14
#include "llvm/ExecutionEngine/ObjectCache.h"
15
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
16
#include "llvm/IR/DataLayout.h"
17
#include "llvm/IR/DerivedTypes.h"
18
#include "llvm/IR/Function.h"
19
#include "llvm/IR/LegacyPassManager.h"
20
#include "llvm/IR/Mangler.h"
21
#include "llvm/IR/Module.h"
22
#include "llvm/MC/MCContext.h"
23
#include "llvm/Object/Archive.h"
24
#include "llvm/Object/ObjectFile.h"
25
#include "llvm/Support/DynamicLibrary.h"
26
#include "llvm/Support/ErrorHandling.h"
27
#include "llvm/Support/MemoryBuffer.h"
28
#include "llvm/Support/SmallVectorMemoryBuffer.h"
29
#include <mutex>
30
31
using namespace llvm;
32
33
namespace {
34
35
static struct RegisterJIT {
36
RegisterJIT() { MCJIT::Register(); }
37
} JITRegistrator;
38
39
}
40
41
extern "C" void LLVMLinkInMCJIT() {
42
}
43
44
ExecutionEngine *
45
MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
46
std::shared_ptr<MCJITMemoryManager> MemMgr,
47
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
48
std::unique_ptr<TargetMachine> TM) {
49
// Try to register the program as a source of symbols to resolve against.
50
//
51
// FIXME: Don't do this here.
52
sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
53
54
if (!MemMgr || !Resolver) {
55
auto RTDyldMM = std::make_shared<SectionMemoryManager>();
56
if (!MemMgr)
57
MemMgr = RTDyldMM;
58
if (!Resolver)
59
Resolver = RTDyldMM;
60
}
61
62
return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
63
std::move(Resolver));
64
}
65
66
MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
67
std::shared_ptr<MCJITMemoryManager> MemMgr,
68
std::shared_ptr<LegacyJITSymbolResolver> Resolver)
69
: ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
70
Ctx(nullptr), MemMgr(std::move(MemMgr)),
71
Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),
72
ObjCache(nullptr) {
73
// FIXME: We are managing our modules, so we do not want the base class
74
// ExecutionEngine to manage them as well. To avoid double destruction
75
// of the first (and only) module added in ExecutionEngine constructor
76
// we remove it from EE and will destruct it ourselves.
77
//
78
// It may make sense to move our module manager (based on SmallStPtr) back
79
// into EE if the JIT and Interpreter can live with it.
80
// If so, additional functions: addModule, removeModule, FindFunctionNamed,
81
// runStaticConstructorsDestructors could be moved back to EE as well.
82
//
83
std::unique_ptr<Module> First = std::move(Modules[0]);
84
Modules.clear();
85
86
if (First->getDataLayout().isDefault())
87
First->setDataLayout(getDataLayout());
88
89
OwnedModules.addModule(std::move(First));
90
RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
91
}
92
93
MCJIT::~MCJIT() {
94
std::lock_guard<sys::Mutex> locked(lock);
95
96
Dyld.deregisterEHFrames();
97
98
for (auto &Obj : LoadedObjects)
99
if (Obj)
100
notifyFreeingObject(*Obj);
101
102
Archives.clear();
103
}
104
105
void MCJIT::addModule(std::unique_ptr<Module> M) {
106
std::lock_guard<sys::Mutex> locked(lock);
107
108
if (M->getDataLayout().isDefault())
109
M->setDataLayout(getDataLayout());
110
111
OwnedModules.addModule(std::move(M));
112
}
113
114
bool MCJIT::removeModule(Module *M) {
115
std::lock_guard<sys::Mutex> locked(lock);
116
return OwnedModules.removeModule(M);
117
}
118
119
void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
120
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
121
if (Dyld.hasError())
122
report_fatal_error(Dyld.getErrorString());
123
124
notifyObjectLoaded(*Obj, *L);
125
126
LoadedObjects.push_back(std::move(Obj));
127
}
128
129
void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
130
std::unique_ptr<object::ObjectFile> ObjFile;
131
std::unique_ptr<MemoryBuffer> MemBuf;
132
std::tie(ObjFile, MemBuf) = Obj.takeBinary();
133
addObjectFile(std::move(ObjFile));
134
Buffers.push_back(std::move(MemBuf));
135
}
136
137
void MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
138
Archives.push_back(std::move(A));
139
}
140
141
void MCJIT::setObjectCache(ObjectCache* NewCache) {
142
std::lock_guard<sys::Mutex> locked(lock);
143
ObjCache = NewCache;
144
}
145
146
std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
147
assert(M && "Can not emit a null module");
148
149
std::lock_guard<sys::Mutex> locked(lock);
150
151
// Materialize all globals in the module if they have not been
152
// materialized already.
153
cantFail(M->materializeAll());
154
155
// This must be a module which has already been added but not loaded to this
156
// MCJIT instance, since these conditions are tested by our caller,
157
// generateCodeForModule.
158
159
legacy::PassManager PM;
160
161
// The RuntimeDyld will take ownership of this shortly
162
SmallVector<char, 4096> ObjBufferSV;
163
raw_svector_ostream ObjStream(ObjBufferSV);
164
165
// Turn the machine code intermediate representation into bytes in memory
166
// that may be executed.
167
if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
168
report_fatal_error("Target does not support MC emission!");
169
170
// Initialize passes.
171
PM.run(*M);
172
// Flush the output buffer to get the generated code into memory
173
174
auto CompiledObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
175
std::move(ObjBufferSV), /*RequiresNullTerminator=*/false);
176
177
// If we have an object cache, tell it about the new object.
178
// Note that we're using the compiled image, not the loaded image (as below).
179
if (ObjCache) {
180
// MemoryBuffer is a thin wrapper around the actual memory, so it's OK
181
// to create a temporary object here and delete it after the call.
182
MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
183
ObjCache->notifyObjectCompiled(M, MB);
184
}
185
186
return CompiledObjBuffer;
187
}
188
189
void MCJIT::generateCodeForModule(Module *M) {
190
// Get a thread lock to make sure we aren't trying to load multiple times
191
std::lock_guard<sys::Mutex> locked(lock);
192
193
// This must be a module which has already been added to this MCJIT instance.
194
assert(OwnedModules.ownsModule(M) &&
195
"MCJIT::generateCodeForModule: Unknown module.");
196
197
// Re-compilation is not supported
198
if (OwnedModules.hasModuleBeenLoaded(M))
199
return;
200
201
std::unique_ptr<MemoryBuffer> ObjectToLoad;
202
// Try to load the pre-compiled object from cache if possible
203
if (ObjCache)
204
ObjectToLoad = ObjCache->getObject(M);
205
206
assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
207
208
// If the cache did not contain a suitable object, compile the object
209
if (!ObjectToLoad) {
210
ObjectToLoad = emitObject(M);
211
assert(ObjectToLoad && "Compilation did not produce an object.");
212
}
213
214
// Load the object into the dynamic linker.
215
// MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
216
Expected<std::unique_ptr<object::ObjectFile>> LoadedObject =
217
object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
218
if (!LoadedObject) {
219
std::string Buf;
220
raw_string_ostream OS(Buf);
221
logAllUnhandledErrors(LoadedObject.takeError(), OS);
222
report_fatal_error(Twine(OS.str()));
223
}
224
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
225
Dyld.loadObject(*LoadedObject.get());
226
227
if (Dyld.hasError())
228
report_fatal_error(Dyld.getErrorString());
229
230
notifyObjectLoaded(*LoadedObject.get(), *L);
231
232
Buffers.push_back(std::move(ObjectToLoad));
233
LoadedObjects.push_back(std::move(*LoadedObject));
234
235
OwnedModules.markModuleAsLoaded(M);
236
}
237
238
void MCJIT::finalizeLoadedModules() {
239
std::lock_guard<sys::Mutex> locked(lock);
240
241
// Resolve any outstanding relocations.
242
Dyld.resolveRelocations();
243
244
// Check for Dyld error.
245
if (Dyld.hasError())
246
ErrMsg = Dyld.getErrorString().str();
247
248
OwnedModules.markAllLoadedModulesAsFinalized();
249
250
// Register EH frame data for any module we own which has been loaded
251
Dyld.registerEHFrames();
252
253
// Set page permissions.
254
MemMgr->finalizeMemory();
255
}
256
257
// FIXME: Rename this.
258
void MCJIT::finalizeObject() {
259
std::lock_guard<sys::Mutex> locked(lock);
260
261
// Generate code for module is going to move objects out of the 'added' list,
262
// so we need to copy that out before using it:
263
SmallVector<Module*, 16> ModsToAdd;
264
for (auto *M : OwnedModules.added())
265
ModsToAdd.push_back(M);
266
267
for (auto *M : ModsToAdd)
268
generateCodeForModule(M);
269
270
finalizeLoadedModules();
271
}
272
273
void MCJIT::finalizeModule(Module *M) {
274
std::lock_guard<sys::Mutex> locked(lock);
275
276
// This must be a module which has already been added to this MCJIT instance.
277
assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
278
279
// If the module hasn't been compiled, just do that.
280
if (!OwnedModules.hasModuleBeenLoaded(M))
281
generateCodeForModule(M);
282
283
finalizeLoadedModules();
284
}
285
286
JITSymbol MCJIT::findExistingSymbol(const std::string &Name) {
287
if (void *Addr = getPointerToGlobalIfAvailable(Name))
288
return JITSymbol(static_cast<uint64_t>(
289
reinterpret_cast<uintptr_t>(Addr)),
290
JITSymbolFlags::Exported);
291
292
return Dyld.getSymbol(Name);
293
}
294
295
Module *MCJIT::findModuleForSymbol(const std::string &Name,
296
bool CheckFunctionsOnly) {
297
StringRef DemangledName = Name;
298
if (DemangledName[0] == getDataLayout().getGlobalPrefix())
299
DemangledName = DemangledName.substr(1);
300
301
std::lock_guard<sys::Mutex> locked(lock);
302
303
// If it hasn't already been generated, see if it's in one of our modules.
304
for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
305
E = OwnedModules.end_added();
306
I != E; ++I) {
307
Module *M = *I;
308
Function *F = M->getFunction(DemangledName);
309
if (F && !F->isDeclaration())
310
return M;
311
if (!CheckFunctionsOnly) {
312
GlobalVariable *G = M->getGlobalVariable(DemangledName);
313
if (G && !G->isDeclaration())
314
return M;
315
// FIXME: Do we need to worry about global aliases?
316
}
317
}
318
// We didn't find the symbol in any of our modules.
319
return nullptr;
320
}
321
322
uint64_t MCJIT::getSymbolAddress(const std::string &Name,
323
bool CheckFunctionsOnly) {
324
std::string MangledName;
325
{
326
raw_string_ostream MangledNameStream(MangledName);
327
Mangler::getNameWithPrefix(MangledNameStream, Name, getDataLayout());
328
}
329
if (auto Sym = findSymbol(MangledName, CheckFunctionsOnly)) {
330
if (auto AddrOrErr = Sym.getAddress())
331
return *AddrOrErr;
332
else
333
report_fatal_error(AddrOrErr.takeError());
334
} else if (auto Err = Sym.takeError())
335
report_fatal_error(Sym.takeError());
336
return 0;
337
}
338
339
JITSymbol MCJIT::findSymbol(const std::string &Name,
340
bool CheckFunctionsOnly) {
341
std::lock_guard<sys::Mutex> locked(lock);
342
343
// First, check to see if we already have this symbol.
344
if (auto Sym = findExistingSymbol(Name))
345
return Sym;
346
347
for (object::OwningBinary<object::Archive> &OB : Archives) {
348
object::Archive *A = OB.getBinary();
349
// Look for our symbols in each Archive
350
auto OptionalChildOrErr = A->findSym(Name);
351
if (!OptionalChildOrErr)
352
report_fatal_error(OptionalChildOrErr.takeError());
353
auto &OptionalChild = *OptionalChildOrErr;
354
if (OptionalChild) {
355
// FIXME: Support nested archives?
356
Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
357
OptionalChild->getAsBinary();
358
if (!ChildBinOrErr) {
359
// TODO: Actually report errors helpfully.
360
consumeError(ChildBinOrErr.takeError());
361
continue;
362
}
363
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
364
if (ChildBin->isObject()) {
365
std::unique_ptr<object::ObjectFile> OF(
366
static_cast<object::ObjectFile *>(ChildBin.release()));
367
// This causes the object file to be loaded.
368
addObjectFile(std::move(OF));
369
// The address should be here now.
370
if (auto Sym = findExistingSymbol(Name))
371
return Sym;
372
}
373
}
374
}
375
376
// If it hasn't already been generated, see if it's in one of our modules.
377
Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
378
if (M) {
379
generateCodeForModule(M);
380
381
// Check the RuntimeDyld table again, it should be there now.
382
return findExistingSymbol(Name);
383
}
384
385
// If a LazyFunctionCreator is installed, use it to get/create the function.
386
// FIXME: Should we instead have a LazySymbolCreator callback?
387
if (LazyFunctionCreator) {
388
auto Addr = static_cast<uint64_t>(
389
reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
390
return JITSymbol(Addr, JITSymbolFlags::Exported);
391
}
392
393
return nullptr;
394
}
395
396
uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
397
std::lock_guard<sys::Mutex> locked(lock);
398
uint64_t Result = getSymbolAddress(Name, false);
399
if (Result != 0)
400
finalizeLoadedModules();
401
return Result;
402
}
403
404
uint64_t MCJIT::getFunctionAddress(const std::string &Name) {
405
std::lock_guard<sys::Mutex> locked(lock);
406
uint64_t Result = getSymbolAddress(Name, true);
407
if (Result != 0)
408
finalizeLoadedModules();
409
return Result;
410
}
411
412
// Deprecated. Use getFunctionAddress instead.
413
void *MCJIT::getPointerToFunction(Function *F) {
414
std::lock_guard<sys::Mutex> locked(lock);
415
416
Mangler Mang;
417
SmallString<128> Name;
418
TM->getNameWithPrefix(Name, F, Mang);
419
420
if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
421
bool AbortOnFailure = !F->hasExternalWeakLinkage();
422
void *Addr = getPointerToNamedFunction(Name, AbortOnFailure);
423
updateGlobalMapping(F, Addr);
424
return Addr;
425
}
426
427
Module *M = F->getParent();
428
bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
429
430
// Make sure the relevant module has been compiled and loaded.
431
if (HasBeenAddedButNotLoaded)
432
generateCodeForModule(M);
433
else if (!OwnedModules.hasModuleBeenLoaded(M)) {
434
// If this function doesn't belong to one of our modules, we're done.
435
// FIXME: Asking for the pointer to a function that hasn't been registered,
436
// and isn't a declaration (which is handled above) should probably
437
// be an assertion.
438
return nullptr;
439
}
440
441
// FIXME: Should the Dyld be retaining module information? Probably not.
442
//
443
// This is the accessor for the target address, so make sure to check the
444
// load address of the symbol, not the local address.
445
return (void*)Dyld.getSymbol(Name).getAddress();
446
}
447
448
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
449
bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
450
for (; I != E; ++I) {
451
ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
452
}
453
}
454
455
void MCJIT::runStaticConstructorsDestructors(bool isDtors) {
456
// Execute global ctors/dtors for each module in the program.
457
runStaticConstructorsDestructorsInModulePtrSet(
458
isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
459
runStaticConstructorsDestructorsInModulePtrSet(
460
isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
461
runStaticConstructorsDestructorsInModulePtrSet(
462
isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
463
}
464
465
Function *MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName,
466
ModulePtrSet::iterator I,
467
ModulePtrSet::iterator E) {
468
for (; I != E; ++I) {
469
Function *F = (*I)->getFunction(FnName);
470
if (F && !F->isDeclaration())
471
return F;
472
}
473
return nullptr;
474
}
475
476
GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(StringRef Name,
477
bool AllowInternal,
478
ModulePtrSet::iterator I,
479
ModulePtrSet::iterator E) {
480
for (; I != E; ++I) {
481
GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
482
if (GV && !GV->isDeclaration())
483
return GV;
484
}
485
return nullptr;
486
}
487
488
489
Function *MCJIT::FindFunctionNamed(StringRef FnName) {
490
Function *F = FindFunctionNamedInModulePtrSet(
491
FnName, OwnedModules.begin_added(), OwnedModules.end_added());
492
if (!F)
493
F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
494
OwnedModules.end_loaded());
495
if (!F)
496
F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
497
OwnedModules.end_finalized());
498
return F;
499
}
500
501
GlobalVariable *MCJIT::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) {
502
GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
503
Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
504
if (!GV)
505
GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
506
OwnedModules.end_loaded());
507
if (!GV)
508
GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
509
OwnedModules.end_finalized());
510
return GV;
511
}
512
513
GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
514
assert(F && "Function *F was null at entry to run()");
515
516
void *FPtr = getPointerToFunction(F);
517
finalizeModule(F->getParent());
518
assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
519
FunctionType *FTy = F->getFunctionType();
520
Type *RetTy = FTy->getReturnType();
521
522
assert((FTy->getNumParams() == ArgValues.size() ||
523
(FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
524
"Wrong number of arguments passed into function!");
525
assert(FTy->getNumParams() == ArgValues.size() &&
526
"This doesn't support passing arguments through varargs (yet)!");
527
528
// Handle some common cases first. These cases correspond to common `main'
529
// prototypes.
530
if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
531
switch (ArgValues.size()) {
532
case 3:
533
if (FTy->getParamType(0)->isIntegerTy(32) &&
534
FTy->getParamType(1)->isPointerTy() &&
535
FTy->getParamType(2)->isPointerTy()) {
536
int (*PF)(int, char **, const char **) =
537
(int(*)(int, char **, const char **))(intptr_t)FPtr;
538
539
// Call the function.
540
GenericValue rv;
541
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
542
(char **)GVTOP(ArgValues[1]),
543
(const char **)GVTOP(ArgValues[2])));
544
return rv;
545
}
546
break;
547
case 2:
548
if (FTy->getParamType(0)->isIntegerTy(32) &&
549
FTy->getParamType(1)->isPointerTy()) {
550
int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
551
552
// Call the function.
553
GenericValue rv;
554
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
555
(char **)GVTOP(ArgValues[1])));
556
return rv;
557
}
558
break;
559
case 1:
560
if (FTy->getNumParams() == 1 &&
561
FTy->getParamType(0)->isIntegerTy(32)) {
562
GenericValue rv;
563
int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
564
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
565
return rv;
566
}
567
break;
568
}
569
}
570
571
// Handle cases where no arguments are passed first.
572
if (ArgValues.empty()) {
573
GenericValue rv;
574
switch (RetTy->getTypeID()) {
575
default: llvm_unreachable("Unknown return type for function call!");
576
case Type::IntegerTyID: {
577
unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
578
if (BitWidth == 1)
579
rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
580
else if (BitWidth <= 8)
581
rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
582
else if (BitWidth <= 16)
583
rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
584
else if (BitWidth <= 32)
585
rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
586
else if (BitWidth <= 64)
587
rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
588
else
589
llvm_unreachable("Integer types > 64 bits not supported");
590
return rv;
591
}
592
case Type::VoidTyID:
593
rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
594
return rv;
595
case Type::FloatTyID:
596
rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
597
return rv;
598
case Type::DoubleTyID:
599
rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
600
return rv;
601
case Type::X86_FP80TyID:
602
case Type::FP128TyID:
603
case Type::PPC_FP128TyID:
604
llvm_unreachable("long double not supported yet");
605
case Type::PointerTyID:
606
return PTOGV(((void*(*)())(intptr_t)FPtr)());
607
}
608
}
609
610
report_fatal_error("MCJIT::runFunction does not support full-featured "
611
"argument passing. Please use "
612
"ExecutionEngine::getFunctionAddress and cast the result "
613
"to the desired function pointer type.");
614
}
615
616
void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
617
if (!isSymbolSearchingDisabled()) {
618
if (auto Sym = Resolver.findSymbol(std::string(Name))) {
619
if (auto AddrOrErr = Sym.getAddress())
620
return reinterpret_cast<void*>(
621
static_cast<uintptr_t>(*AddrOrErr));
622
} else if (auto Err = Sym.takeError())
623
report_fatal_error(std::move(Err));
624
}
625
626
/// If a LazyFunctionCreator is installed, use it to get/create the function.
627
if (LazyFunctionCreator)
628
if (void *RP = LazyFunctionCreator(std::string(Name)))
629
return RP;
630
631
if (AbortOnFailure) {
632
report_fatal_error("Program used external function '"+Name+
633
"' which could not be resolved!");
634
}
635
return nullptr;
636
}
637
638
void MCJIT::RegisterJITEventListener(JITEventListener *L) {
639
if (!L)
640
return;
641
std::lock_guard<sys::Mutex> locked(lock);
642
EventListeners.push_back(L);
643
}
644
645
void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
646
if (!L)
647
return;
648
std::lock_guard<sys::Mutex> locked(lock);
649
auto I = find(reverse(EventListeners), L);
650
if (I != EventListeners.rend()) {
651
std::swap(*I, EventListeners.back());
652
EventListeners.pop_back();
653
}
654
}
655
656
void MCJIT::notifyObjectLoaded(const object::ObjectFile &Obj,
657
const RuntimeDyld::LoadedObjectInfo &L) {
658
uint64_t Key =
659
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
660
std::lock_guard<sys::Mutex> locked(lock);
661
MemMgr->notifyObjectLoaded(this, Obj);
662
for (JITEventListener *EL : EventListeners)
663
EL->notifyObjectLoaded(Key, Obj, L);
664
}
665
666
void MCJIT::notifyFreeingObject(const object::ObjectFile &Obj) {
667
uint64_t Key =
668
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
669
std::lock_guard<sys::Mutex> locked(lock);
670
for (JITEventListener *L : EventListeners)
671
L->notifyFreeingObject(Key);
672
}
673
674
JITSymbol
675
LinkingSymbolResolver::findSymbol(const std::string &Name) {
676
auto Result = ParentEngine.findSymbol(Name, false);
677
if (Result)
678
return Result;
679
if (ParentEngine.isSymbolSearchingDisabled())
680
return nullptr;
681
return ClientResolver->findSymbol(Name);
682
}
683
684
void LinkingSymbolResolver::anchor() {}
685
686