1 //===-- ExternalFunctions.cpp - Implement External Functions --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains both code to deal with invoking "external" functions, but
11 // also contains code that implements "exported" external functions.
12 //
13 // There are currently two mechanisms for handling external functions in the
14 // Interpreter. The first is to implement lle_* wrapper functions that are
15 // specific to well-known library functions which manually translate the
16 // arguments from GenericValues and make the call. If such a wrapper does
17 // not exist, and libffi is available, then the Interpreter will attempt to
18 // invoke the function using libffi, after finding its address.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #include "Interpreter.h"
23 #include "llvm/ADT/APInt.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/Config/config.h" // Detect libffi
26 #include "llvm/ExecutionEngine/GenericValue.h"
27 #include "llvm/IR/DataLayout.h"
28 #include "llvm/IR/DerivedTypes.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/DynamicLibrary.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/ManagedStatic.h"
35 #include "llvm/Support/Mutex.h"
36 #include "llvm/Support/UniqueLock.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include <cassert>
39 #include <cmath>
40 #include <csignal>
41 #include <cstdint>
42 #include <cstdio>
43 #include <cstring>
44 #include <map>
45 #include <string>
46 #include <utility>
47 #include <vector>
48
49 #ifdef HAVE_FFI_CALL
50 #ifdef HAVE_FFI_H
51 #include <ffi.h>
52 #define USE_LIBFFI
53 #elif HAVE_FFI_FFI_H
54 #include <ffi/ffi.h>
55 #define USE_LIBFFI
56 #endif
57 #endif
58
59 using namespace llvm;
60
61 static ManagedStatic<sys::Mutex> FunctionsLock;
62
63 typedef GenericValue (*ExFunc)(FunctionType *, ArrayRef<GenericValue>);
64 static ManagedStatic<std::map<const Function *, ExFunc> > ExportedFunctions;
65 static ManagedStatic<std::map<std::string, ExFunc> > FuncNames;
66
67 #ifdef USE_LIBFFI
68 typedef void (*RawFunc)();
69 static ManagedStatic<std::map<const Function *, RawFunc> > RawFunctions;
70 #endif
71
72 static Interpreter *TheInterpreter;
73
getTypeID(Type * Ty)74 static char getTypeID(Type *Ty) {
75 switch (Ty->getTypeID()) {
76 case Type::VoidTyID: return 'V';
77 case Type::IntegerTyID:
78 switch (cast<IntegerType>(Ty)->getBitWidth()) {
79 case 1: return 'o';
80 case 8: return 'B';
81 case 16: return 'S';
82 case 32: return 'I';
83 case 64: return 'L';
84 default: return 'N';
85 }
86 case Type::FloatTyID: return 'F';
87 case Type::DoubleTyID: return 'D';
88 case Type::PointerTyID: return 'P';
89 case Type::FunctionTyID:return 'M';
90 case Type::StructTyID: return 'T';
91 case Type::ArrayTyID: return 'A';
92 default: return 'U';
93 }
94 }
95
96 // Try to find address of external function given a Function object.
97 // Please note, that interpreter doesn't know how to assemble a
98 // real call in general case (this is JIT job), that's why it assumes,
99 // that all external functions has the same (and pretty "general") signature.
100 // The typical example of such functions are "lle_X_" ones.
lookupFunction(const Function * F)101 static ExFunc lookupFunction(const Function *F) {
102 // Function not found, look it up... start by figuring out what the
103 // composite function name should be.
104 std::string ExtName = "lle_";
105 FunctionType *FT = F->getFunctionType();
106 ExtName += getTypeID(FT->getReturnType());
107 for (Type *T : FT->params())
108 ExtName += getTypeID(T);
109 ExtName += ("_" + F->getName()).str();
110
111 sys::ScopedLock Writer(*FunctionsLock);
112 ExFunc FnPtr = (*FuncNames)[ExtName];
113 if (!FnPtr)
114 FnPtr = (*FuncNames)[("lle_X_" + F->getName()).str()];
115 if (!FnPtr) // Try calling a generic function... if it exists...
116 FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
117 ("lle_X_" + F->getName()).str());
118 if (FnPtr)
119 ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later
120 return FnPtr;
121 }
122
123 #ifdef USE_LIBFFI
ffiTypeFor(Type * Ty)124 static ffi_type *ffiTypeFor(Type *Ty) {
125 switch (Ty->getTypeID()) {
126 case Type::VoidTyID: return &ffi_type_void;
127 case Type::IntegerTyID:
128 switch (cast<IntegerType>(Ty)->getBitWidth()) {
129 case 8: return &ffi_type_sint8;
130 case 16: return &ffi_type_sint16;
131 case 32: return &ffi_type_sint32;
132 case 64: return &ffi_type_sint64;
133 }
134 case Type::FloatTyID: return &ffi_type_float;
135 case Type::DoubleTyID: return &ffi_type_double;
136 case Type::PointerTyID: return &ffi_type_pointer;
137 default: break;
138 }
139 // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
140 report_fatal_error("Type could not be mapped for use with libffi.");
141 return NULL;
142 }
143
ffiValueFor(Type * Ty,const GenericValue & AV,void * ArgDataPtr)144 static void *ffiValueFor(Type *Ty, const GenericValue &AV,
145 void *ArgDataPtr) {
146 switch (Ty->getTypeID()) {
147 case Type::IntegerTyID:
148 switch (cast<IntegerType>(Ty)->getBitWidth()) {
149 case 8: {
150 int8_t *I8Ptr = (int8_t *) ArgDataPtr;
151 *I8Ptr = (int8_t) AV.IntVal.getZExtValue();
152 return ArgDataPtr;
153 }
154 case 16: {
155 int16_t *I16Ptr = (int16_t *) ArgDataPtr;
156 *I16Ptr = (int16_t) AV.IntVal.getZExtValue();
157 return ArgDataPtr;
158 }
159 case 32: {
160 int32_t *I32Ptr = (int32_t *) ArgDataPtr;
161 *I32Ptr = (int32_t) AV.IntVal.getZExtValue();
162 return ArgDataPtr;
163 }
164 case 64: {
165 int64_t *I64Ptr = (int64_t *) ArgDataPtr;
166 *I64Ptr = (int64_t) AV.IntVal.getZExtValue();
167 return ArgDataPtr;
168 }
169 }
170 case Type::FloatTyID: {
171 float *FloatPtr = (float *) ArgDataPtr;
172 *FloatPtr = AV.FloatVal;
173 return ArgDataPtr;
174 }
175 case Type::DoubleTyID: {
176 double *DoublePtr = (double *) ArgDataPtr;
177 *DoublePtr = AV.DoubleVal;
178 return ArgDataPtr;
179 }
180 case Type::PointerTyID: {
181 void **PtrPtr = (void **) ArgDataPtr;
182 *PtrPtr = GVTOP(AV);
183 return ArgDataPtr;
184 }
185 default: break;
186 }
187 // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
188 report_fatal_error("Type value could not be mapped for use with libffi.");
189 return NULL;
190 }
191
ffiInvoke(RawFunc Fn,Function * F,ArrayRef<GenericValue> ArgVals,const DataLayout & TD,GenericValue & Result)192 static bool ffiInvoke(RawFunc Fn, Function *F, ArrayRef<GenericValue> ArgVals,
193 const DataLayout &TD, GenericValue &Result) {
194 ffi_cif cif;
195 FunctionType *FTy = F->getFunctionType();
196 const unsigned NumArgs = F->arg_size();
197
198 // TODO: We don't have type information about the remaining arguments, because
199 // this information is never passed into ExecutionEngine::runFunction().
200 if (ArgVals.size() > NumArgs && F->isVarArg()) {
201 report_fatal_error("Calling external var arg function '" + F->getName()
202 + "' is not supported by the Interpreter.");
203 }
204
205 unsigned ArgBytes = 0;
206
207 std::vector<ffi_type*> args(NumArgs);
208 for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end();
209 A != E; ++A) {
210 const unsigned ArgNo = A->getArgNo();
211 Type *ArgTy = FTy->getParamType(ArgNo);
212 args[ArgNo] = ffiTypeFor(ArgTy);
213 ArgBytes += TD.getTypeStoreSize(ArgTy);
214 }
215
216 SmallVector<uint8_t, 128> ArgData;
217 ArgData.resize(ArgBytes);
218 uint8_t *ArgDataPtr = ArgData.data();
219 SmallVector<void*, 16> values(NumArgs);
220 for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end();
221 A != E; ++A) {
222 const unsigned ArgNo = A->getArgNo();
223 Type *ArgTy = FTy->getParamType(ArgNo);
224 values[ArgNo] = ffiValueFor(ArgTy, ArgVals[ArgNo], ArgDataPtr);
225 ArgDataPtr += TD.getTypeStoreSize(ArgTy);
226 }
227
228 Type *RetTy = FTy->getReturnType();
229 ffi_type *rtype = ffiTypeFor(RetTy);
230
231 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NumArgs, rtype, args.data()) ==
232 FFI_OK) {
233 SmallVector<uint8_t, 128> ret;
234 if (RetTy->getTypeID() != Type::VoidTyID)
235 ret.resize(TD.getTypeStoreSize(RetTy));
236 ffi_call(&cif, Fn, ret.data(), values.data());
237 switch (RetTy->getTypeID()) {
238 case Type::IntegerTyID:
239 switch (cast<IntegerType>(RetTy)->getBitWidth()) {
240 case 8: Result.IntVal = APInt(8 , *(int8_t *) ret.data()); break;
241 case 16: Result.IntVal = APInt(16, *(int16_t*) ret.data()); break;
242 case 32: Result.IntVal = APInt(32, *(int32_t*) ret.data()); break;
243 case 64: Result.IntVal = APInt(64, *(int64_t*) ret.data()); break;
244 }
245 break;
246 case Type::FloatTyID: Result.FloatVal = *(float *) ret.data(); break;
247 case Type::DoubleTyID: Result.DoubleVal = *(double*) ret.data(); break;
248 case Type::PointerTyID: Result.PointerVal = *(void **) ret.data(); break;
249 default: break;
250 }
251 return true;
252 }
253
254 return false;
255 }
256 #endif // USE_LIBFFI
257
callExternalFunction(Function * F,ArrayRef<GenericValue> ArgVals)258 GenericValue Interpreter::callExternalFunction(Function *F,
259 ArrayRef<GenericValue> ArgVals) {
260 TheInterpreter = this;
261
262 unique_lock<sys::Mutex> Guard(*FunctionsLock);
263
264 // Do a lookup to see if the function is in our cache... this should just be a
265 // deferred annotation!
266 std::map<const Function *, ExFunc>::iterator FI = ExportedFunctions->find(F);
267 if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F)
268 : FI->second) {
269 Guard.unlock();
270 return Fn(F->getFunctionType(), ArgVals);
271 }
272
273 #ifdef USE_LIBFFI
274 std::map<const Function *, RawFunc>::iterator RF = RawFunctions->find(F);
275 RawFunc RawFn;
276 if (RF == RawFunctions->end()) {
277 RawFn = (RawFunc)(intptr_t)
278 sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName());
279 if (!RawFn)
280 RawFn = (RawFunc)(intptr_t)getPointerToGlobalIfAvailable(F);
281 if (RawFn != 0)
282 RawFunctions->insert(std::make_pair(F, RawFn)); // Cache for later
283 } else {
284 RawFn = RF->second;
285 }
286
287 Guard.unlock();
288
289 GenericValue Result;
290 if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getDataLayout(), Result))
291 return Result;
292 #endif // USE_LIBFFI
293
294 if (F->getName() == "__main")
295 errs() << "Tried to execute an unknown external function: "
296 << *F->getType() << " __main\n";
297 else
298 report_fatal_error("Tried to execute an unknown external function: " +
299 F->getName());
300 #ifndef USE_LIBFFI
301 errs() << "Recompiling LLVM with --enable-libffi might help.\n";
302 #endif
303 return GenericValue();
304 }
305
306 //===----------------------------------------------------------------------===//
307 // Functions "exported" to the running application...
308 //
309
310 // void atexit(Function*)
lle_X_atexit(FunctionType * FT,ArrayRef<GenericValue> Args)311 static GenericValue lle_X_atexit(FunctionType *FT,
312 ArrayRef<GenericValue> Args) {
313 assert(Args.size() == 1);
314 TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
315 GenericValue GV;
316 GV.IntVal = 0;
317 return GV;
318 }
319
320 // void exit(int)
lle_X_exit(FunctionType * FT,ArrayRef<GenericValue> Args)321 static GenericValue lle_X_exit(FunctionType *FT, ArrayRef<GenericValue> Args) {
322 TheInterpreter->exitCalled(Args[0]);
323 return GenericValue();
324 }
325
326 // void abort(void)
lle_X_abort(FunctionType * FT,ArrayRef<GenericValue> Args)327 static GenericValue lle_X_abort(FunctionType *FT, ArrayRef<GenericValue> Args) {
328 //FIXME: should we report or raise here?
329 //report_fatal_error("Interpreted program raised SIGABRT");
330 raise (SIGABRT);
331 return GenericValue();
332 }
333
334 // int sprintf(char *, const char *, ...) - a very rough implementation to make
335 // output useful.
lle_X_sprintf(FunctionType * FT,ArrayRef<GenericValue> Args)336 static GenericValue lle_X_sprintf(FunctionType *FT,
337 ArrayRef<GenericValue> Args) {
338 char *OutputBuffer = (char *)GVTOP(Args[0]);
339 const char *FmtStr = (const char *)GVTOP(Args[1]);
340 unsigned ArgNo = 2;
341
342 // printf should return # chars printed. This is completely incorrect, but
343 // close enough for now.
344 GenericValue GV;
345 GV.IntVal = APInt(32, strlen(FmtStr));
346 while (true) {
347 switch (*FmtStr) {
348 case 0: return GV; // Null terminator...
349 default: // Normal nonspecial character
350 sprintf(OutputBuffer++, "%c", *FmtStr++);
351 break;
352 case '\\': { // Handle escape codes
353 sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1));
354 FmtStr += 2; OutputBuffer += 2;
355 break;
356 }
357 case '%': { // Handle format specifiers
358 char FmtBuf[100] = "", Buffer[1000] = "";
359 char *FB = FmtBuf;
360 *FB++ = *FmtStr++;
361 char Last = *FB++ = *FmtStr++;
362 unsigned HowLong = 0;
363 while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
364 Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
365 Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
366 Last != 'p' && Last != 's' && Last != '%') {
367 if (Last == 'l' || Last == 'L') HowLong++; // Keep track of l's
368 Last = *FB++ = *FmtStr++;
369 }
370 *FB = 0;
371
372 switch (Last) {
373 case '%':
374 memcpy(Buffer, "%", 2); break;
375 case 'c':
376 sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
377 break;
378 case 'd': case 'i':
379 case 'u': case 'o':
380 case 'x': case 'X':
381 if (HowLong >= 1) {
382 if (HowLong == 1 &&
383 TheInterpreter->getDataLayout().getPointerSizeInBits() == 64 &&
384 sizeof(long) < sizeof(int64_t)) {
385 // Make sure we use %lld with a 64 bit argument because we might be
386 // compiling LLI on a 32 bit compiler.
387 unsigned Size = strlen(FmtBuf);
388 FmtBuf[Size] = FmtBuf[Size-1];
389 FmtBuf[Size+1] = 0;
390 FmtBuf[Size-1] = 'l';
391 }
392 sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal.getZExtValue());
393 } else
394 sprintf(Buffer, FmtBuf,uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
395 break;
396 case 'e': case 'E': case 'g': case 'G': case 'f':
397 sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
398 case 'p':
399 sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break;
400 case 's':
401 sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break;
402 default:
403 errs() << "<unknown printf code '" << *FmtStr << "'!>";
404 ArgNo++; break;
405 }
406 size_t Len = strlen(Buffer);
407 memcpy(OutputBuffer, Buffer, Len + 1);
408 OutputBuffer += Len;
409 }
410 break;
411 }
412 }
413 return GV;
414 }
415
416 // int printf(const char *, ...) - a very rough implementation to make output
417 // useful.
lle_X_printf(FunctionType * FT,ArrayRef<GenericValue> Args)418 static GenericValue lle_X_printf(FunctionType *FT,
419 ArrayRef<GenericValue> Args) {
420 char Buffer[10000];
421 std::vector<GenericValue> NewArgs;
422 NewArgs.push_back(PTOGV((void*)&Buffer[0]));
423 NewArgs.insert(NewArgs.end(), Args.begin(), Args.end());
424 GenericValue GV = lle_X_sprintf(FT, NewArgs);
425 outs() << Buffer;
426 return GV;
427 }
428
429 // int sscanf(const char *format, ...);
lle_X_sscanf(FunctionType * FT,ArrayRef<GenericValue> args)430 static GenericValue lle_X_sscanf(FunctionType *FT,
431 ArrayRef<GenericValue> args) {
432 assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");
433
434 char *Args[10];
435 for (unsigned i = 0; i < args.size(); ++i)
436 Args[i] = (char*)GVTOP(args[i]);
437
438 GenericValue GV;
439 GV.IntVal = APInt(32, sscanf(Args[0], Args[1], Args[2], Args[3], Args[4],
440 Args[5], Args[6], Args[7], Args[8], Args[9]));
441 return GV;
442 }
443
444 // int scanf(const char *format, ...);
lle_X_scanf(FunctionType * FT,ArrayRef<GenericValue> args)445 static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef<GenericValue> args) {
446 assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");
447
448 char *Args[10];
449 for (unsigned i = 0; i < args.size(); ++i)
450 Args[i] = (char*)GVTOP(args[i]);
451
452 GenericValue GV;
453 GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4],
454 Args[5], Args[6], Args[7], Args[8], Args[9]));
455 return GV;
456 }
457
458 // int fprintf(FILE *, const char *, ...) - a very rough implementation to make
459 // output useful.
lle_X_fprintf(FunctionType * FT,ArrayRef<GenericValue> Args)460 static GenericValue lle_X_fprintf(FunctionType *FT,
461 ArrayRef<GenericValue> Args) {
462 assert(Args.size() >= 2);
463 char Buffer[10000];
464 std::vector<GenericValue> NewArgs;
465 NewArgs.push_back(PTOGV(Buffer));
466 NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end());
467 GenericValue GV = lle_X_sprintf(FT, NewArgs);
468
469 fputs(Buffer, (FILE *) GVTOP(Args[0]));
470 return GV;
471 }
472
lle_X_memset(FunctionType * FT,ArrayRef<GenericValue> Args)473 static GenericValue lle_X_memset(FunctionType *FT,
474 ArrayRef<GenericValue> Args) {
475 int val = (int)Args[1].IntVal.getSExtValue();
476 size_t len = (size_t)Args[2].IntVal.getZExtValue();
477 memset((void *)GVTOP(Args[0]), val, len);
478 // llvm.memset.* returns void, lle_X_* returns GenericValue,
479 // so here we return GenericValue with IntVal set to zero
480 GenericValue GV;
481 GV.IntVal = 0;
482 return GV;
483 }
484
lle_X_memcpy(FunctionType * FT,ArrayRef<GenericValue> Args)485 static GenericValue lle_X_memcpy(FunctionType *FT,
486 ArrayRef<GenericValue> Args) {
487 memcpy(GVTOP(Args[0]), GVTOP(Args[1]),
488 (size_t)(Args[2].IntVal.getLimitedValue()));
489
490 // llvm.memcpy* returns void, lle_X_* returns GenericValue,
491 // so here we return GenericValue with IntVal set to zero
492 GenericValue GV;
493 GV.IntVal = 0;
494 return GV;
495 }
496
initializeExternalFunctions()497 void Interpreter::initializeExternalFunctions() {
498 sys::ScopedLock Writer(*FunctionsLock);
499 (*FuncNames)["lle_X_atexit"] = lle_X_atexit;
500 (*FuncNames)["lle_X_exit"] = lle_X_exit;
501 (*FuncNames)["lle_X_abort"] = lle_X_abort;
502
503 (*FuncNames)["lle_X_printf"] = lle_X_printf;
504 (*FuncNames)["lle_X_sprintf"] = lle_X_sprintf;
505 (*FuncNames)["lle_X_sscanf"] = lle_X_sscanf;
506 (*FuncNames)["lle_X_scanf"] = lle_X_scanf;
507 (*FuncNames)["lle_X_fprintf"] = lle_X_fprintf;
508 (*FuncNames)["lle_X_memset"] = lle_X_memset;
509 (*FuncNames)["lle_X_memcpy"] = lle_X_memcpy;
510 }
511