1 //===-- ExternalFunctions.cpp - Implement External Functions --------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains both code to deal with invoking "external" functions, but
10 // also contains code that implements "exported" external functions.
12 // There are currently two mechanisms for handling external functions in the
13 // Interpreter. The first is to implement lle_* wrapper functions that are
14 // specific to well-known library functions which manually translate the
15 // arguments from GenericValues and make the call. If such a wrapper does
16 // not exist, and libffi is available, then the Interpreter will attempt to
17 // invoke the function using libffi, after finding its address.
19 //===----------------------------------------------------------------------===//
21 #include "Interpreter.h"
22 #include "llvm/ADT/APInt.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/Config/config.h" // Detect libffi
25 #include "llvm/ExecutionEngine/GenericValue.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/DerivedTypes.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/DynamicLibrary.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/Mutex.h"
34 #include "llvm/Support/raw_ostream.h"
61 typedef GenericValue (*ExFunc
)(FunctionType
*, ArrayRef
<GenericValue
>);
62 typedef void (*RawFunc
)();
66 std::map
<const Function
*, ExFunc
> ExportedFunctions
;
67 std::map
<std::string
, ExFunc
> FuncNames
;
69 std::map
<const Function
*, RawFunc
> RawFunctions
;
73 Functions
&getFunctions() {
78 } // anonymous namespace
80 static Interpreter
*TheInterpreter
;
82 static char getTypeID(Type
*Ty
) {
83 switch (Ty
->getTypeID()) {
84 case Type::VoidTyID
: return 'V';
85 case Type::IntegerTyID
:
86 switch (cast
<IntegerType
>(Ty
)->getBitWidth()) {
94 case Type::FloatTyID
: return 'F';
95 case Type::DoubleTyID
: return 'D';
96 case Type::PointerTyID
: return 'P';
97 case Type::FunctionTyID
:return 'M';
98 case Type::StructTyID
: return 'T';
99 case Type::ArrayTyID
: return 'A';
104 // Try to find address of external function given a Function object.
105 // Please note, that interpreter doesn't know how to assemble a
106 // real call in general case (this is JIT job), that's why it assumes,
107 // that all external functions has the same (and pretty "general") signature.
108 // The typical example of such functions are "lle_X_" ones.
109 static ExFunc
lookupFunction(const Function
*F
) {
110 // Function not found, look it up... start by figuring out what the
111 // composite function name should be.
112 std::string ExtName
= "lle_";
113 FunctionType
*FT
= F
->getFunctionType();
114 ExtName
+= getTypeID(FT
->getReturnType());
115 for (Type
*T
: FT
->params())
116 ExtName
+= getTypeID(T
);
117 ExtName
+= ("_" + F
->getName()).str();
119 auto &Fns
= getFunctions();
120 sys::ScopedLock
Writer(Fns
.Lock
);
121 ExFunc FnPtr
= Fns
.FuncNames
[ExtName
];
123 FnPtr
= Fns
.FuncNames
[("lle_X_" + F
->getName()).str()];
124 if (!FnPtr
) // Try calling a generic function... if it exists...
125 FnPtr
= (ExFunc
)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
126 ("lle_X_" + F
->getName()).str());
128 Fns
.ExportedFunctions
.insert(std::make_pair(F
, FnPtr
)); // Cache for later
133 static ffi_type
*ffiTypeFor(Type
*Ty
) {
134 switch (Ty
->getTypeID()) {
135 case Type::VoidTyID
: return &ffi_type_void
;
136 case Type::IntegerTyID
:
137 switch (cast
<IntegerType
>(Ty
)->getBitWidth()) {
138 case 8: return &ffi_type_sint8
;
139 case 16: return &ffi_type_sint16
;
140 case 32: return &ffi_type_sint32
;
141 case 64: return &ffi_type_sint64
;
143 llvm_unreachable("Unhandled integer type bitwidth");
144 case Type::FloatTyID
: return &ffi_type_float
;
145 case Type::DoubleTyID
: return &ffi_type_double
;
146 case Type::PointerTyID
: return &ffi_type_pointer
;
149 // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
150 report_fatal_error("Type could not be mapped for use with libffi.");
154 static void *ffiValueFor(Type
*Ty
, const GenericValue
&AV
,
156 switch (Ty
->getTypeID()) {
157 case Type::IntegerTyID
:
158 switch (cast
<IntegerType
>(Ty
)->getBitWidth()) {
160 int8_t *I8Ptr
= (int8_t *) ArgDataPtr
;
161 *I8Ptr
= (int8_t) AV
.IntVal
.getZExtValue();
165 int16_t *I16Ptr
= (int16_t *) ArgDataPtr
;
166 *I16Ptr
= (int16_t) AV
.IntVal
.getZExtValue();
170 int32_t *I32Ptr
= (int32_t *) ArgDataPtr
;
171 *I32Ptr
= (int32_t) AV
.IntVal
.getZExtValue();
175 int64_t *I64Ptr
= (int64_t *) ArgDataPtr
;
176 *I64Ptr
= (int64_t) AV
.IntVal
.getZExtValue();
180 llvm_unreachable("Unhandled integer type bitwidth");
181 case Type::FloatTyID
: {
182 float *FloatPtr
= (float *) ArgDataPtr
;
183 *FloatPtr
= AV
.FloatVal
;
186 case Type::DoubleTyID
: {
187 double *DoublePtr
= (double *) ArgDataPtr
;
188 *DoublePtr
= AV
.DoubleVal
;
191 case Type::PointerTyID
: {
192 void **PtrPtr
= (void **) ArgDataPtr
;
198 // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
199 report_fatal_error("Type value could not be mapped for use with libffi.");
203 static bool ffiInvoke(RawFunc Fn
, Function
*F
, ArrayRef
<GenericValue
> ArgVals
,
204 const DataLayout
&TD
, GenericValue
&Result
) {
206 FunctionType
*FTy
= F
->getFunctionType();
207 const unsigned NumArgs
= F
->arg_size();
209 // TODO: We don't have type information about the remaining arguments, because
210 // this information is never passed into ExecutionEngine::runFunction().
211 if (ArgVals
.size() > NumArgs
&& F
->isVarArg()) {
212 report_fatal_error("Calling external var arg function '" + F
->getName()
213 + "' is not supported by the Interpreter.");
216 unsigned ArgBytes
= 0;
218 std::vector
<ffi_type
*> args(NumArgs
);
219 for (Function::const_arg_iterator A
= F
->arg_begin(), E
= F
->arg_end();
221 const unsigned ArgNo
= A
->getArgNo();
222 Type
*ArgTy
= FTy
->getParamType(ArgNo
);
223 args
[ArgNo
] = ffiTypeFor(ArgTy
);
224 ArgBytes
+= TD
.getTypeStoreSize(ArgTy
);
227 SmallVector
<uint8_t, 128> ArgData
;
228 ArgData
.resize(ArgBytes
);
229 uint8_t *ArgDataPtr
= ArgData
.data();
230 SmallVector
<void*, 16> values(NumArgs
);
231 for (Function::const_arg_iterator A
= F
->arg_begin(), E
= F
->arg_end();
233 const unsigned ArgNo
= A
->getArgNo();
234 Type
*ArgTy
= FTy
->getParamType(ArgNo
);
235 values
[ArgNo
] = ffiValueFor(ArgTy
, ArgVals
[ArgNo
], ArgDataPtr
);
236 ArgDataPtr
+= TD
.getTypeStoreSize(ArgTy
);
239 Type
*RetTy
= FTy
->getReturnType();
240 ffi_type
*rtype
= ffiTypeFor(RetTy
);
242 if (ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, NumArgs
, rtype
, args
.data()) ==
244 SmallVector
<uint8_t, 128> ret
;
245 if (RetTy
->getTypeID() != Type::VoidTyID
)
246 ret
.resize(TD
.getTypeStoreSize(RetTy
));
247 ffi_call(&cif
, Fn
, ret
.data(), values
.data());
248 switch (RetTy
->getTypeID()) {
249 case Type::IntegerTyID
:
250 switch (cast
<IntegerType
>(RetTy
)->getBitWidth()) {
251 case 8: Result
.IntVal
= APInt(8 , *(int8_t *) ret
.data()); break;
252 case 16: Result
.IntVal
= APInt(16, *(int16_t*) ret
.data()); break;
253 case 32: Result
.IntVal
= APInt(32, *(int32_t*) ret
.data()); break;
254 case 64: Result
.IntVal
= APInt(64, *(int64_t*) ret
.data()); break;
257 case Type::FloatTyID
: Result
.FloatVal
= *(float *) ret
.data(); break;
258 case Type::DoubleTyID
: Result
.DoubleVal
= *(double*) ret
.data(); break;
259 case Type::PointerTyID
: Result
.PointerVal
= *(void **) ret
.data(); break;
269 GenericValue
Interpreter::callExternalFunction(Function
*F
,
270 ArrayRef
<GenericValue
> ArgVals
) {
271 TheInterpreter
= this;
273 auto &Fns
= getFunctions();
274 std::unique_lock
<sys::Mutex
> Guard(Fns
.Lock
);
276 // Do a lookup to see if the function is in our cache... this should just be a
277 // deferred annotation!
278 std::map
<const Function
*, ExFunc
>::iterator FI
=
279 Fns
.ExportedFunctions
.find(F
);
280 if (ExFunc Fn
= (FI
== Fns
.ExportedFunctions
.end()) ? lookupFunction(F
)
283 return Fn(F
->getFunctionType(), ArgVals
);
287 std::map
<const Function
*, RawFunc
>::iterator RF
= Fns
.RawFunctions
.find(F
);
289 if (RF
== Fns
.RawFunctions
.end()) {
290 RawFn
= (RawFunc
)(intptr_t)
291 sys::DynamicLibrary::SearchForAddressOfSymbol(std::string(F
->getName()));
293 RawFn
= (RawFunc
)(intptr_t)getPointerToGlobalIfAvailable(F
);
295 Fns
.RawFunctions
.insert(std::make_pair(F
, RawFn
)); // Cache for later
303 if (RawFn
!= 0 && ffiInvoke(RawFn
, F
, ArgVals
, getDataLayout(), Result
))
307 if (F
->getName() == "__main")
308 errs() << "Tried to execute an unknown external function: "
309 << *F
->getType() << " __main\n";
311 report_fatal_error("Tried to execute an unknown external function: " +
314 errs() << "Recompiling LLVM with --enable-libffi might help.\n";
316 return GenericValue();
319 //===----------------------------------------------------------------------===//
320 // Functions "exported" to the running application...
323 // void atexit(Function*)
324 static GenericValue
lle_X_atexit(FunctionType
*FT
,
325 ArrayRef
<GenericValue
> Args
) {
326 assert(Args
.size() == 1);
327 TheInterpreter
->addAtExitHandler((Function
*)GVTOP(Args
[0]));
334 static GenericValue
lle_X_exit(FunctionType
*FT
, ArrayRef
<GenericValue
> Args
) {
335 TheInterpreter
->exitCalled(Args
[0]);
336 return GenericValue();
340 static GenericValue
lle_X_abort(FunctionType
*FT
, ArrayRef
<GenericValue
> Args
) {
341 //FIXME: should we report or raise here?
342 //report_fatal_error("Interpreted program raised SIGABRT");
344 return GenericValue();
347 // Silence warnings about sprintf. (See also
348 // https://github.com/llvm/llvm-project/issues/58086)
349 #if defined(__clang__)
350 #pragma clang diagnostic push
351 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
353 // int sprintf(char *, const char *, ...) - a very rough implementation to make
355 static GenericValue
lle_X_sprintf(FunctionType
*FT
,
356 ArrayRef
<GenericValue
> Args
) {
357 char *OutputBuffer
= (char *)GVTOP(Args
[0]);
358 const char *FmtStr
= (const char *)GVTOP(Args
[1]);
361 // printf should return # chars printed. This is completely incorrect, but
362 // close enough for now.
364 GV
.IntVal
= APInt(32, strlen(FmtStr
));
367 case 0: return GV
; // Null terminator...
368 default: // Normal nonspecial character
369 sprintf(OutputBuffer
++, "%c", *FmtStr
++);
371 case '\\': { // Handle escape codes
372 sprintf(OutputBuffer
, "%c%c", *FmtStr
, *(FmtStr
+1));
373 FmtStr
+= 2; OutputBuffer
+= 2;
376 case '%': { // Handle format specifiers
377 char FmtBuf
[100] = "", Buffer
[1000] = "";
380 char Last
= *FB
++ = *FmtStr
++;
381 unsigned HowLong
= 0;
382 while (Last
!= 'c' && Last
!= 'd' && Last
!= 'i' && Last
!= 'u' &&
383 Last
!= 'o' && Last
!= 'x' && Last
!= 'X' && Last
!= 'e' &&
384 Last
!= 'E' && Last
!= 'g' && Last
!= 'G' && Last
!= 'f' &&
385 Last
!= 'p' && Last
!= 's' && Last
!= '%') {
386 if (Last
== 'l' || Last
== 'L') HowLong
++; // Keep track of l's
387 Last
= *FB
++ = *FmtStr
++;
393 memcpy(Buffer
, "%", 2); break;
395 sprintf(Buffer
, FmtBuf
, uint32_t(Args
[ArgNo
++].IntVal
.getZExtValue()));
402 TheInterpreter
->getDataLayout().getPointerSizeInBits() == 64 &&
403 sizeof(long) < sizeof(int64_t)) {
404 // Make sure we use %lld with a 64 bit argument because we might be
405 // compiling LLI on a 32 bit compiler.
406 unsigned Size
= strlen(FmtBuf
);
407 FmtBuf
[Size
] = FmtBuf
[Size
-1];
409 FmtBuf
[Size
-1] = 'l';
411 sprintf(Buffer
, FmtBuf
, Args
[ArgNo
++].IntVal
.getZExtValue());
413 sprintf(Buffer
, FmtBuf
,uint32_t(Args
[ArgNo
++].IntVal
.getZExtValue()));
415 case 'e': case 'E': case 'g': case 'G': case 'f':
416 sprintf(Buffer
, FmtBuf
, Args
[ArgNo
++].DoubleVal
); break;
418 sprintf(Buffer
, FmtBuf
, (void*)GVTOP(Args
[ArgNo
++])); break;
420 sprintf(Buffer
, FmtBuf
, (char*)GVTOP(Args
[ArgNo
++])); break;
422 errs() << "<unknown printf code '" << *FmtStr
<< "'!>";
425 size_t Len
= strlen(Buffer
);
426 memcpy(OutputBuffer
, Buffer
, Len
+ 1);
434 #if defined(__clang__)
435 #pragma clang diagnostic pop
438 // int printf(const char *, ...) - a very rough implementation to make output
440 static GenericValue
lle_X_printf(FunctionType
*FT
,
441 ArrayRef
<GenericValue
> Args
) {
443 std::vector
<GenericValue
> NewArgs
;
444 NewArgs
.push_back(PTOGV((void*)&Buffer
[0]));
445 llvm::append_range(NewArgs
, Args
);
446 GenericValue GV
= lle_X_sprintf(FT
, NewArgs
);
451 // int sscanf(const char *format, ...);
452 static GenericValue
lle_X_sscanf(FunctionType
*FT
,
453 ArrayRef
<GenericValue
> args
) {
454 assert(args
.size() < 10 && "Only handle up to 10 args to sscanf right now!");
457 for (unsigned i
= 0; i
< args
.size(); ++i
)
458 Args
[i
] = (char*)GVTOP(args
[i
]);
461 GV
.IntVal
= APInt(32, sscanf(Args
[0], Args
[1], Args
[2], Args
[3], Args
[4],
462 Args
[5], Args
[6], Args
[7], Args
[8], Args
[9]));
466 // int scanf(const char *format, ...);
467 static GenericValue
lle_X_scanf(FunctionType
*FT
, ArrayRef
<GenericValue
> args
) {
468 assert(args
.size() < 10 && "Only handle up to 10 args to scanf right now!");
471 for (unsigned i
= 0; i
< args
.size(); ++i
)
472 Args
[i
] = (char*)GVTOP(args
[i
]);
475 GV
.IntVal
= APInt(32, scanf( Args
[0], Args
[1], Args
[2], Args
[3], Args
[4],
476 Args
[5], Args
[6], Args
[7], Args
[8], Args
[9]));
480 // int fprintf(FILE *, const char *, ...) - a very rough implementation to make
482 static GenericValue
lle_X_fprintf(FunctionType
*FT
,
483 ArrayRef
<GenericValue
> Args
) {
484 assert(Args
.size() >= 2);
486 std::vector
<GenericValue
> NewArgs
;
487 NewArgs
.push_back(PTOGV(Buffer
));
488 NewArgs
.insert(NewArgs
.end(), Args
.begin()+1, Args
.end());
489 GenericValue GV
= lle_X_sprintf(FT
, NewArgs
);
491 fputs(Buffer
, (FILE *) GVTOP(Args
[0]));
495 static GenericValue
lle_X_memset(FunctionType
*FT
,
496 ArrayRef
<GenericValue
> Args
) {
497 int val
= (int)Args
[1].IntVal
.getSExtValue();
498 size_t len
= (size_t)Args
[2].IntVal
.getZExtValue();
499 memset((void *)GVTOP(Args
[0]), val
, len
);
500 // llvm.memset.* returns void, lle_X_* returns GenericValue,
501 // so here we return GenericValue with IntVal set to zero
507 static GenericValue
lle_X_memcpy(FunctionType
*FT
,
508 ArrayRef
<GenericValue
> Args
) {
509 memcpy(GVTOP(Args
[0]), GVTOP(Args
[1]),
510 (size_t)(Args
[2].IntVal
.getLimitedValue()));
512 // llvm.memcpy* returns void, lle_X_* returns GenericValue,
513 // so here we return GenericValue with IntVal set to zero
519 void Interpreter::initializeExternalFunctions() {
520 auto &Fns
= getFunctions();
521 sys::ScopedLock
Writer(Fns
.Lock
);
522 Fns
.FuncNames
["lle_X_atexit"] = lle_X_atexit
;
523 Fns
.FuncNames
["lle_X_exit"] = lle_X_exit
;
524 Fns
.FuncNames
["lle_X_abort"] = lle_X_abort
;
526 Fns
.FuncNames
["lle_X_printf"] = lle_X_printf
;
527 Fns
.FuncNames
["lle_X_sprintf"] = lle_X_sprintf
;
528 Fns
.FuncNames
["lle_X_sscanf"] = lle_X_sscanf
;
529 Fns
.FuncNames
["lle_X_scanf"] = lle_X_scanf
;
530 Fns
.FuncNames
["lle_X_fprintf"] = lle_X_fprintf
;
531 Fns
.FuncNames
["lle_X_memset"] = lle_X_memset
;
532 Fns
.FuncNames
["lle_X_memcpy"] = lle_X_memcpy
;