LLVM API Documentation

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