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