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