ExternalFunctions.cpp revision 7d696d80409aad20bb5da0fc4eccab941dd371d4
12fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner//===-- ExternalFunctions.cpp - Implement External Functions --------------===// 2d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman// 102fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// This file contains both code to deal with invoking "external" functions, but 112fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner// also contains code that implements "exported" external functions. 127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 13f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// There are currently two mechanisms for handling external functions in the 14f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// Interpreter. The first is to implement lle_* wrapper functions that are 15f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// specific to well-known library functions which manually translate the 16f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// arguments from GenericValues and make the call. If such a wrapper does 17f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// not exist, and libffi is available, then the Interpreter will attempt to 18f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// invoke the function using libffi, after finding its address. 197720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 207720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 217720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 227720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "Interpreter.h" 237720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner#include "llvm/DerivedTypes.h" 24b8d15b2ad0a2266b275a00f07410e6c9d9ca6695Misha Brukman#include "llvm/Module.h" 25f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#include "llvm/Config/config.h" // Detect libffi 267d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h" 27480f093dc2b6aff9b501cc56cf5728513e55be81Bill Wendling#include "llvm/Support/Streams.h" 28df5a37efc997288da520ff4889443e3560d95387Reid Spencer#include "llvm/System/DynamicLibrary.h" 29005cbce20e55077d7e02255812e5df068188d302Chris Lattner#include "llvm/Target/TargetData.h" 30936baaa5aeddb78ff41b1f655101b4d88c47473bChuck Rose III#include "llvm/Support/ManagedStatic.h" 31c226570bdedff961d9c470951f477373cdb86437Owen Anderson#include "llvm/System/Mutex.h" 32b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke#include <csignal> 334520dd2b7b20af07d5a3e4d06d964a532044eb10Duncan Sands#include <cstdio> 34b8d15b2ad0a2266b275a00f07410e6c9d9ca6695Misha Brukman#include <map> 3597af751deb9b26fd42fbcee082da9ccc4ded5b45Jeff Cohen#include <cmath> 36ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 37621deadee8967ab3a56c5478bb810b7200c48edbZhou Sheng 3893f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#ifdef HAVE_FFI_CALL 39f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#ifdef HAVE_FFI_H 40f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#include <ffi.h> 4193f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#define USE_LIBFFI 42f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#elif HAVE_FFI_FFI_H 43f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#include <ffi/ffi.h> 4493f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#define USE_LIBFFI 45f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#endif 46621deadee8967ab3a56c5478bb810b7200c48edbZhou Sheng#endif 4732aaee684d3fd24a7fb6e385877f113f2bd41ed6Tanya Lattner 48f7a743d7ed6e96af4c836e512c9cd59812c8186eChris Lattnerusing namespace llvm; 49d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 50c226570bdedff961d9c470951f477373cdb86437Owen Andersonstatic ManagedStatic<sys::Mutex> FunctionsLock; 51c226570bdedff961d9c470951f477373cdb86437Owen Anderson 52f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckytypedef GenericValue (*ExFunc)(const FunctionType *, 53f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &); 54f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckystatic ManagedStatic<std::map<const Function *, ExFunc> > ExportedFunctions; 55697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstatic std::map<std::string, ExFunc> FuncNames; 567720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 5793f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#ifdef USE_LIBFFI 58f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckytypedef void (*RawFunc)(void); 59f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckystatic ManagedStatic<std::map<const Function *, RawFunc> > RawFunctions; 60f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky#endif 61f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 62e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattnerstatic Interpreter *TheInterpreter; 63e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 647720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerstatic char getTypeID(const Type *Ty) { 65f70c22b019494723d0e706f93d6542dfaa6e73a5Chris Lattner switch (Ty->getTypeID()) { 667720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::VoidTyID: return 'V'; 67a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case Type::IntegerTyID: 68a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer switch (cast<IntegerType>(Ty)->getBitWidth()) { 69a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 1: return 'o'; 70a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 8: return 'B'; 71a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 16: return 'S'; 72a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 32: return 'I'; 73a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case 64: return 'L'; 74a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer default: return 'N'; 75a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer } 767720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::FloatTyID: return 'F'; 777720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::DoubleTyID: return 'D'; 787720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::PointerTyID: return 'P'; 79e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer case Type::FunctionTyID:return 'M'; 807720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::StructTyID: return 'T'; 817720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::ArrayTyID: return 'A'; 827720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner case Type::OpaqueTyID: return 'O'; 837720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner default: return 'U'; 847720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 857720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 867720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 8742346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// Try to find address of external function given a Function object. 8842346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// Please note, that interpreter doesn't know how to assemble a 8942346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// real call in general case (this is JIT job), that's why it assumes, 9042346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// that all external functions has the same (and pretty "general") signature. 9142346f58d810204606ea5ec3d2e583b0a6da2531Anton Korobeynikov// The typical example of such functions are "lle_X_" ones. 9258a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaekestatic ExFunc lookupFunction(const Function *F) { 937720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // Function not found, look it up... start by figuring out what the 947720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner // composite function name should be. 95697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string ExtName = "lle_"; 9658a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke const FunctionType *FT = F->getFunctionType(); 9758a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i) 9858a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke ExtName += getTypeID(FT->getContainedType(i)); 9958a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke ExtName += "_" + F->getName(); 1007720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 101a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::ScopedLock Writer(*FunctionsLock); 1024721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner ExFunc FnPtr = FuncNames[ExtName]; 1034721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner if (FnPtr == 0) 10458a6faac65d2e5f60a650c6f99bb6c615ad9fbc6Brian Gaeke FnPtr = FuncNames["lle_X_"+F->getName()]; 1057720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr == 0) // Try calling a generic function... if it exists... 10626e6e109d559fb644b59231c14346997290dc9d6Chris Lattner FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol( 107df5a37efc997288da520ff4889443e3560d95387Reid Spencer ("lle_X_"+F->getName()).c_str()); 1087720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner if (FnPtr != 0) 109f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later 1107720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner return FnPtr; 1117720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 1127720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 11393f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#ifdef USE_LIBFFI 114f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckystatic ffi_type *ffiTypeFor(const Type *Ty) { 115f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (Ty->getTypeID()) { 116f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::VoidTyID: return &ffi_type_void; 117f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::IntegerTyID: 118f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (cast<IntegerType>(Ty)->getBitWidth()) { 119f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 8: return &ffi_type_sint8; 120f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 16: return &ffi_type_sint16; 121f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 32: return &ffi_type_sint32; 122f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 64: return &ffi_type_sint64; 123f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 124f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::FloatTyID: return &ffi_type_float; 125f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::DoubleTyID: return &ffi_type_double; 126f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::PointerTyID: return &ffi_type_pointer; 127f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky default: break; 128f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 129f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc. 1307d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Type could not be mapped for use with libffi."); 131f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return NULL; 132f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky} 133f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 134f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckystatic void *ffiValueFor(const Type *Ty, const GenericValue &AV, 135f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky void *ArgDataPtr) { 136f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (Ty->getTypeID()) { 137f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::IntegerTyID: 138f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (cast<IntegerType>(Ty)->getBitWidth()) { 139f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 8: { 140f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky int8_t *I8Ptr = (int8_t *) ArgDataPtr; 141f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *I8Ptr = (int8_t) AV.IntVal.getZExtValue(); 142f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 143f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 144f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 16: { 145f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky int16_t *I16Ptr = (int16_t *) ArgDataPtr; 146f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *I16Ptr = (int16_t) AV.IntVal.getZExtValue(); 147f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 148f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 149f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 32: { 150f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky int32_t *I32Ptr = (int32_t *) ArgDataPtr; 151f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *I32Ptr = (int32_t) AV.IntVal.getZExtValue(); 152f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 153f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 154f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 64: { 155f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky int64_t *I64Ptr = (int64_t *) ArgDataPtr; 156f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *I64Ptr = (int64_t) AV.IntVal.getZExtValue(); 157f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 158f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 159f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 160f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::FloatTyID: { 161f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky float *FloatPtr = (float *) ArgDataPtr; 162f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *FloatPtr = AV.DoubleVal; 163f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 164f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 165f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::DoubleTyID: { 166f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky double *DoublePtr = (double *) ArgDataPtr; 167f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *DoublePtr = AV.DoubleVal; 168f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 169f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 170f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::PointerTyID: { 171f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky void **PtrPtr = (void **) ArgDataPtr; 172f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky *PtrPtr = GVTOP(AV); 173f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return ArgDataPtr; 174f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 175f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky default: break; 176f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 177f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc. 1787d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Type value could not be mapped for use with libffi."); 179f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return NULL; 180f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky} 181f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 182f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewyckystatic bool ffiInvoke(RawFunc Fn, Function *F, 183f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &ArgVals, 184f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const TargetData *TD, GenericValue &Result) { 185f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ffi_cif cif; 186f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const FunctionType *FTy = F->getFunctionType(); 187f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const unsigned NumArgs = F->arg_size(); 188f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 189f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky // TODO: We don't have type information about the remaining arguments, because 190f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky // this information is never passed into ExecutionEngine::runFunction(). 191f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (ArgVals.size() > NumArgs && F->isVarArg()) { 1927d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Calling external var arg function '" + F->getName() 1937d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + "' is not supported by the Interpreter."); 194f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 195f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 196f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky unsigned ArgBytes = 0; 197f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 198f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::vector<ffi_type*> args(NumArgs); 199f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); 200f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky A != E; ++A) { 201f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const unsigned ArgNo = A->getArgNo(); 202f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const Type *ArgTy = FTy->getParamType(ArgNo); 203f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky args[ArgNo] = ffiTypeFor(ArgTy); 204f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ArgBytes += TD->getTypeStoreSize(ArgTy); 205f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 206f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 207f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky uint8_t *ArgData = (uint8_t*) alloca(ArgBytes); 208f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky uint8_t *ArgDataPtr = ArgData; 209f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::vector<void*> values(NumArgs); 210f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); 211f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky A != E; ++A) { 212f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const unsigned ArgNo = A->getArgNo(); 213f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const Type *ArgTy = FTy->getParamType(ArgNo); 214f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky values[ArgNo] = ffiValueFor(ArgTy, ArgVals[ArgNo], ArgDataPtr); 215f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ArgDataPtr += TD->getTypeStoreSize(ArgTy); 216f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 217f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 218f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const Type *RetTy = FTy->getReturnType(); 219f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ffi_type *rtype = ffiTypeFor(RetTy); 220f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 221f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NumArgs, rtype, &args[0]) == FFI_OK) { 222f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky void *ret = NULL; 223f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (RetTy->getTypeID() != Type::VoidTyID) 224f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ret = alloca(TD->getTypeStoreSize(RetTy)); 225f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky ffi_call(&cif, Fn, ret, &values[0]); 226f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (RetTy->getTypeID()) { 227f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::IntegerTyID: 228f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky switch (cast<IntegerType>(RetTy)->getBitWidth()) { 229f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 8: Result.IntVal = APInt(8 , *(int8_t *) ret); break; 230f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 16: Result.IntVal = APInt(16, *(int16_t*) ret); break; 231f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 32: Result.IntVal = APInt(32, *(int32_t*) ret); break; 232f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case 64: Result.IntVal = APInt(64, *(int64_t*) ret); break; 233f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 234f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky break; 235f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::FloatTyID: Result.FloatVal = *(float *) ret; break; 236f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::DoubleTyID: Result.DoubleVal = *(double*) ret; break; 237f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky case Type::PointerTyID: Result.PointerVal = *(void **) ret; break; 238f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky default: break; 239f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 240f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return true; 241f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } 242f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 243f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return false; 244f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky} 24593f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#endif // USE_LIBFFI 246f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 2474e7dd8f7c4c0dc930ca64343316625cf464fb2d7Chris LattnerGenericValue Interpreter::callExternalFunction(Function *F, 24844edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner const std::vector<GenericValue> &ArgVals) { 249e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter = this; 250e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 251c226570bdedff961d9c470951f477373cdb86437Owen Anderson FunctionsLock->acquire(); 252c226570bdedff961d9c470951f477373cdb86437Owen Anderson 2532fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // Do a lookup to see if the function is in our cache... this should just be a 254d5d96b9fcd779806555cf5db602f80d5a308a471Misha Brukman // deferred annotation! 255f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::map<const Function *, ExFunc>::iterator FI = ExportedFunctions->find(F); 256f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F) 257c226570bdedff961d9c470951f477373cdb86437Owen Anderson : FI->second) { 258c226570bdedff961d9c470951f477373cdb86437Owen Anderson FunctionsLock->release(); 259f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return Fn(F->getFunctionType(), ArgVals); 260c226570bdedff961d9c470951f477373cdb86437Owen Anderson } 261f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 26293f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#ifdef USE_LIBFFI 263f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::map<const Function *, RawFunc>::iterator RF = RawFunctions->find(F); 264f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky RawFunc RawFn; 265f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (RF == RawFunctions->end()) { 266f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky RawFn = (RawFunc)(intptr_t) 267f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName()); 268f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (RawFn != 0) 269f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky RawFunctions->insert(std::make_pair(F, RawFn)); // Cache for later 270f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky } else { 271f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky RawFn = RF->second; 2727720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner } 273c226570bdedff961d9c470951f477373cdb86437Owen Anderson 274c226570bdedff961d9c470951f477373cdb86437Owen Anderson FunctionsLock->release(); 2757720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 276f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky GenericValue Result; 277f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getTargetData(), Result)) 278f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return Result; 27993f70fc291c56287bff7aefd924d171f005fdcc7Nick Lewycky#endif // USE_LIBFFI 280f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 2817d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin if (F->getName() == "__main") 2827d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin cerr << "Tried to execute an unknown external function: " 2837d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin << F->getType()->getDescription() << " __main\n"; 2847d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin else 2857d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin llvm_report_error("Tried to execute an unknown external function: " + 2867d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin F->getType()->getDescription() + " " +F->getName()); 287f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky return GenericValue(); 2887720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} 2897720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 2907720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 2917720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner//===----------------------------------------------------------------------===// 292b408b1255646f31895dcbf099184e087bfa1ca39Chris Lattner// Functions "exported" to the running application... 2937720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner// 2947720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattnerextern "C" { // Don't add C++ manglings to llvm mangling :) 2957720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner 29644edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner// void atexit(Function*) 297f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_atexit(const FunctionType *FT, 298f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 29944edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner assert(Args.size() == 1); 30044edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0])); 30144edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner GenericValue GV; 302bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = 0; 30344edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner return GV; 304f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner} 305f8f2afb8cc5f080b291faad678e0a256ea44d15fChris Lattner 306005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void exit(int) 307f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_exit(const FunctionType *FT, 308f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 309e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner TheInterpreter->exitCalled(Args[0]); 310e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner return GenericValue(); 311e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner} 312e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 313005cbce20e55077d7e02255812e5df068188d302Chris Lattner// void abort(void) 314f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_abort(const FunctionType *FT, 315f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 3167d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin //FIXME: should we report or raise here? 3177d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin //llvm_report_error("Interpreted program raised SIGABRT"); 318b56a6bc96a483b47da71b24efaa4380d463bbe17Brian Gaeke raise (SIGABRT); 3191ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner return GenericValue(); 3201ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner} 3211ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner 322f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// int sprintf(char *, const char *, ...) - a very rough implementation to make 323e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner// output useful. 324f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_sprintf(const FunctionType *FT, 325f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 326b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner char *OutputBuffer = (char *)GVTOP(Args[0]); 327b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner const char *FmtStr = (const char *)GVTOP(Args[1]); 328e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner unsigned ArgNo = 2; 32908845a242c574d695566cbc61e46da1c86c810acChris Lattner 33008845a242c574d695566cbc61e46da1c86c810acChris Lattner // printf should return # chars printed. This is completely incorrect, but 33108845a242c574d695566cbc61e46da1c86c810acChris Lattner // close enough for now. 332bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GenericValue GV; 333bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, strlen(FmtStr)); 33408845a242c574d695566cbc61e46da1c86c810acChris Lattner while (1) { 33508845a242c574d695566cbc61e46da1c86c810acChris Lattner switch (*FmtStr) { 33608845a242c574d695566cbc61e46da1c86c810acChris Lattner case 0: return GV; // Null terminator... 33708845a242c574d695566cbc61e46da1c86c810acChris Lattner default: // Normal nonspecial character 338e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer++, "%c", *FmtStr++); 33908845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 34008845a242c574d695566cbc61e46da1c86c810acChris Lattner case '\\': { // Handle escape codes 341e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1)); 342e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FmtStr += 2; OutputBuffer += 2; 34308845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 34408845a242c574d695566cbc61e46da1c86c810acChris Lattner } 34508845a242c574d695566cbc61e46da1c86c810acChris Lattner case '%': { // Handle format specifiers 346ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char FmtBuf[100] = "", Buffer[1000] = ""; 347ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char *FB = FmtBuf; 348ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB++ = *FmtStr++; 349ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner char Last = *FB++ = *FmtStr++; 350ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner unsigned HowLong = 0; 351ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' && 352ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' && 353ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' && 354ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last != 'p' && Last != 's' && Last != '%') { 355ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner if (Last == 'l' || Last == 'L') HowLong++; // Keep track of l's 356ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner Last = *FB++ = *FmtStr++; 35708845a242c574d695566cbc61e46da1c86c810acChris Lattner } 358ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner *FB = 0; 359d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman 360ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner switch (Last) { 361ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case '%': 3621eac4e0844439219208e94a17796b8232de41a5cDan Gohman strcpy(Buffer, "%"); break; 363ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'c': 364bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue())); 365bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer break; 366ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'd': case 'i': 367ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'u': case 'o': 368ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'x': case 'X': 36969ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner if (HowLong >= 1) { 3701543e40cea50d244979f0667f453cf3466a6106cChris Lattner if (HowLong == 1 && 371fe854034677f59baca1e38075e71f6efca247a03Chris Lattner TheInterpreter->getTargetData()->getPointerSizeInBits() == 64 && 37219b7e0e0cabfa6dfc559c64e3d6ed053832c4047Reid Spencer sizeof(long) < sizeof(int64_t)) { 37369ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // Make sure we use %lld with a 64 bit argument because we might be 37469ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner // compiling LLI on a 32 bit compiler. 37569ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner unsigned Size = strlen(FmtBuf); 37669ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size] = FmtBuf[Size-1]; 37769ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size+1] = 0; 37869ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner FmtBuf[Size-1] = 'l'; 37969ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } 380bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal.getZExtValue()); 38169ab7a8ac6c52465f7b886fb11e390330e8cf10fChris Lattner } else 382bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer sprintf(Buffer, FmtBuf,uint32_t(Args[ArgNo++].IntVal.getZExtValue())); 383bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer break; 384ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'e': case 'E': case 'g': case 'G': case 'f': 385ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break; 386ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner case 'p': 387b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break; 388d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman case 's': 389b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break; 390e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling default: cerr << "<unknown printf code '" << *FmtStr << "'!>"; 391ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner ArgNo++; break; 392ea38c0e85c29783fdaf3b6c25fe7e3aa43688521Chris Lattner } 393e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner strcpy(OutputBuffer, Buffer); 394e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner OutputBuffer += strlen(Buffer); 39508845a242c574d695566cbc61e46da1c86c810acChris Lattner } 39608845a242c574d695566cbc61e46da1c86c810acChris Lattner break; 39708845a242c574d695566cbc61e46da1c86c810acChris Lattner } 39808845a242c574d695566cbc61e46da1c86c810acChris Lattner } 399b3b0727032e58c8b8f3017c2b3f560616c6905afReid Spencer return GV; 40008845a242c574d695566cbc61e46da1c86c810acChris Lattner} 40108845a242c574d695566cbc61e46da1c86c810acChris Lattner 402f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// int printf(const char *, ...) - a very rough implementation to make output 403f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// useful. 404f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_printf(const FunctionType *FT, 405f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 406e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner char Buffer[10000]; 407f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::vector<GenericValue> NewArgs; 408b3b0727032e58c8b8f3017c2b3f560616c6905afReid Spencer NewArgs.push_back(PTOGV((void*)&Buffer[0])); 409e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin(), Args.end()); 41097e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer GenericValue GV = lle_X_sprintf(FT, NewArgs); 411e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cout << Buffer; 412e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner return GV; 413e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner} 414e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner 415f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattnerstatic void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1, 416f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg2, void *Arg3, void *Arg4, void *Arg5, 417f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg6, void *Arg7, void *Arg8) { 418f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 }; 419f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 420f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Loop over the format string, munging read values as appropriate (performs 4215560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman // byteswaps as necessary). 422f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned ArgNo = 0; 423f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (*Fmt) { 424f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (*Fmt++ == '%') { 425f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read any flag characters that may be present... 426f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Suppress = false; 427f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Half = false; 428f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool Long = false; 429f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner bool LongLong = false; // long long or long double 430f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 431f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner while (1) { 432f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (*Fmt++) { 433f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case '*': Suppress = true; break; 434f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'a': /*Allocate = true;*/ break; // We don't need to track this 435f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'h': Half = true; break; 436f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'l': Long = true; break; 437f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'q': 438f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'L': LongLong = true; break; 439f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: 440f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Fmt[-1] > '9' || Fmt[-1] < '0') // Ignore field width specs 441f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner goto Out; 442f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 443f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 444f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Out: 445f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 446f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner // Read the conversion character 447f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (!Suppress && Fmt[-1] != '%') { // Nothing to do? 448f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner unsigned Size = 0; 449f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner const Type *Ty = 0; 450f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 451f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner switch (Fmt[-1]) { 452f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p': 453f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'd': 454f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 455e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 8; Ty = Type::Int64Ty; 456f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else if (Half) { 457e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 4; Ty = Type::Int16Ty; 458f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 459e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Size = 4; Ty = Type::Int32Ty; 460f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 461f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 462f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 463f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'e': case 'g': case 'E': 464f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 'f': 465f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Long || LongLong) { 466f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 8; Ty = Type::DoubleTy; 467f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } else { 468f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 4; Ty = Type::FloatTy; 469f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 470f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 471f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 472f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner case 's': case 'c': case '[': // No byteswap needed 473f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Size = 1; 474e49661bdf5b7a913d4e368cf511381e524ae403aReid Spencer Ty = Type::Int8Ty; 475f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner break; 476f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 477f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner default: break; 478f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 479f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 480f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner if (Size) { 481f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 482f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner void *Arg = Args[ArgNo++]; 483f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner memcpy(&GV, Arg, Size); 484f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty); 485f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 486f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 487f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 488f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner } 489f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 490f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 491665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner// int sscanf(const char *format, ...); 492f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_sscanf(const FunctionType *FT, 493f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &args) { 494665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); 495665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 496f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 497665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 498f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 499665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 500665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner GenericValue GV; 501bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, sscanf(Args[0], Args[1], Args[2], Args[3], Args[4], 502bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Args[5], Args[6], Args[7], Args[8], Args[9])); 503f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4], 504f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9], 0); 505f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner return GV; 506f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner} 507f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 508f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner// int scanf(const char *format, ...); 509f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_scanf(const FunctionType *FT, 510f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &args) { 511f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); 512f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 513f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner char *Args[10]; 514f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner for (unsigned i = 0; i < args.size(); ++i) 515f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[i] = (char*)GVTOP(args[i]); 516f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner 517f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner GenericValue GV; 518bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4], 519bfcd5992d8ae20812e61fe3b017b79254236a8baReid Spencer Args[5], Args[6], Args[7], Args[8], Args[9])); 520f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4], 521f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner Args[5], Args[6], Args[7], Args[8], Args[9]); 522665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner return GV; 523665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner} 524665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner 525f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// int fprintf(FILE *, const char *, ...) - a very rough implementation to make 526f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky// output useful. 527f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick LewyckyGenericValue lle_X_fprintf(const FunctionType *FT, 528f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky const std::vector<GenericValue> &Args) { 5299dbf6dddcec7a627fabfc722e124311321de8fa0Chris Lattner assert(Args.size() >= 2); 530cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner char Buffer[10000]; 531f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky std::vector<GenericValue> NewArgs; 532b111874b386f5e3d807a8f78edb010b40d507115Chris Lattner NewArgs.push_back(PTOGV(Buffer)); 533cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end()); 53497e0c22330f1856a7e026d162040aafdb2a70d0eReid Spencer GenericValue GV = lle_X_sprintf(FT, NewArgs); 535cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 536f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky fputs(Buffer, (FILE *) GVTOP(Args[0])); 537cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner return GV; 538cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner} 539cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner 5407720c8e1a7a252e983e3f3e7f841d7901dfea80cChris Lattner} // End extern "C" 5414721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 5424721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner 543da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattnervoid Interpreter::initializeExternalFunctions() { 544a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::ScopedLock Writer(*FunctionsLock); 545f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky FuncNames["lle_X_atexit"] = lle_X_atexit; 5460f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_exit"] = lle_X_exit; 5471ee34a5a5ba52557697e7eb607e8bd5d4ce0d492Chris Lattner FuncNames["lle_X_abort"] = lle_X_abort; 548f9c5c5c7a25a3c549cbbc523bf2c8f4e895c20b6Nick Lewycky 5490f279b245dc5f84a6b7c89900fd0d48e324452e7Chris Lattner FuncNames["lle_X_printf"] = lle_X_printf; 550e7c6f726c8d18ff8803d9b3dc3a8443496002044Chris Lattner FuncNames["lle_X_sprintf"] = lle_X_sprintf; 551665ee88504ae8e4440fd1609f3d88c3481cebe12Chris Lattner FuncNames["lle_X_sscanf"] = lle_X_sscanf; 552f9a88b684d8ca368ad51695c61a3580f4700da52Chris Lattner FuncNames["lle_X_scanf"] = lle_X_scanf; 553cf9b4f0f41242d8a7d4079ab9e6b163f54b621f1Chris Lattner FuncNames["lle_X_fprintf"] = lle_X_fprintf; 5544721f1304f3d49e44c78c9eed882a34ad7388be0Chris Lattner} 555d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 556