LLVM API Documentation

ExternalFunctions.cpp

Go to the documentation of this file.
00001 //===-- ExternalFunctions.cpp - Implement External Functions --------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file contains both code to deal with invoking "external" functions, but
00011 //  also contains code that implements "exported" external functions.
00012 //
00013 //  External functions in the interpreter are implemented by
00014 //  using the system's dynamic loader to look up the address of the function
00015 //  we want to invoke.  If a function is found, then one of the
00016 //  many lle_* wrapper functions in this file will translate its arguments from
00017 //  GenericValues to the types the function is actually expecting, before the
00018 //  function is called.
00019 //
00020 //===----------------------------------------------------------------------===//
00021 
00022 #include "Interpreter.h"
00023 #include "llvm/DerivedTypes.h"
00024 #include "llvm/Module.h"
00025 #include "llvm/Support/Streams.h"
00026 #include "llvm/System/DynamicLibrary.h"
00027 #include "llvm/Target/TargetData.h"
00028 #include "llvm/Support/ManagedStatic.h"
00029 #include <csignal>
00030 #include <cstdio>
00031 #include <map>
00032 #include <cmath>
00033 #include <cstring>
00034 
00035 #ifdef __linux__
00036 #include <cxxabi.h>
00037 #endif
00038 
00039 using std::vector;
00040 
00041 using namespace llvm;
00042 
00043 typedef GenericValue (*ExFunc)(FunctionType *, const vector<GenericValue> &);
00044 static ManagedStatic<std::map<const Function *, ExFunc> > Functions;
00045 static std::map<std::string, ExFunc> FuncNames;
00046 
00047 static Interpreter *TheInterpreter;
00048 
00049 static char getTypeID(const Type *Ty) {
00050   switch (Ty->getTypeID()) {
00051   case Type::VoidTyID:    return 'V';
00052   case Type::IntegerTyID:
00053     switch (cast<IntegerType>(Ty)->getBitWidth()) {
00054       case 1:  return 'o';
00055       case 8:  return 'B';
00056       case 16: return 'S';
00057       case 32: return 'I';
00058       case 64: return 'L';
00059       default: return 'N';
00060     }
00061   case Type::FloatTyID:   return 'F';
00062   case Type::DoubleTyID:  return 'D';
00063   case Type::PointerTyID: return 'P';
00064   case Type::FunctionTyID:return 'M';
00065   case Type::StructTyID:  return 'T';
00066   case Type::ArrayTyID:   return 'A';
00067   case Type::OpaqueTyID:  return 'O';
00068   default: return 'U';
00069   }
00070 }
00071 
00072 // Try to find address of external function given a Function object.
00073 // Please note, that interpreter doesn't know how to assemble a
00074 // real call in general case (this is JIT job), that's why it assumes,
00075 // that all external functions has the same (and pretty "general") signature.
00076 // The typical example of such functions are "lle_X_" ones.
00077 static ExFunc lookupFunction(const Function *F) {
00078   // Function not found, look it up... start by figuring out what the
00079   // composite function name should be.
00080   std::string ExtName = "lle_";
00081   const FunctionType *FT = F->getFunctionType();
00082   for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i)
00083     ExtName += getTypeID(FT->getContainedType(i));
00084   ExtName += "_" + F->getName();
00085 
00086   ExFunc FnPtr = FuncNames[ExtName];
00087   if (FnPtr == 0)
00088     FnPtr = FuncNames["lle_X_"+F->getName()];
00089   if (FnPtr == 0)  // Try calling a generic function... if it exists...
00090     FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
00091             ("lle_X_"+F->getName()).c_str());
00092   if (FnPtr == 0)
00093     FnPtr = (ExFunc)(intptr_t)
00094       sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName());
00095   if (FnPtr != 0)
00096     Functions->insert(std::make_pair(F, FnPtr));  // Cache for later
00097   return FnPtr;
00098 }
00099 
00100 GenericValue Interpreter::callExternalFunction(Function *F,
00101                                      const std::vector<GenericValue> &ArgVals) {
00102   TheInterpreter = this;
00103 
00104   // Do a lookup to see if the function is in our cache... this should just be a
00105   // deferred annotation!
00106   std::map<const Function *, ExFunc>::iterator FI = Functions->find(F);
00107   ExFunc Fn = (FI == Functions->end()) ? lookupFunction(F) : FI->second;
00108   if (Fn == 0) {
00109     cerr << "Tried to execute an unknown external function: "
00110          << F->getType()->getDescription() << " " << F->getName() << "\n";
00111     if (F->getName() == "__main")
00112       return GenericValue();
00113     abort();
00114   }
00115 
00116   // TODO: FIXME when types are not const!
00117   GenericValue Result = Fn(const_cast<FunctionType*>(F->getFunctionType()),
00118                            ArgVals);
00119   return Result;
00120 }
00121 
00122 
00123 //===----------------------------------------------------------------------===//
00124 //  Functions "exported" to the running application...
00125 //
00126 extern "C" {  // Don't add C++ manglings to llvm mangling :)
00127 
00128 // void putchar(ubyte)
00129 GenericValue lle_X_putchar(FunctionType *FT, const vector<GenericValue> &Args){
00130   cout << ((char)Args[0].IntVal.getZExtValue()) << std::flush;
00131   return Args[0];
00132 }
00133 
00134 // void _IO_putc(int c, FILE* fp)
00135 GenericValue lle_X__IO_putc(FunctionType *FT, const vector<GenericValue> &Args){
00136 #ifdef __linux__
00137   _IO_putc((char)Args[0].IntVal.getZExtValue(), (FILE*) Args[1].PointerVal);
00138 #else
00139   assert(0 && "Can't call _IO_putc on this platform");
00140 #endif
00141   return Args[0];
00142 }
00143 
00144 // void atexit(Function*)
00145 GenericValue lle_X_atexit(FunctionType *FT, const vector<GenericValue> &Args) {
00146   assert(Args.size() == 1);
00147   TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
00148   GenericValue GV;
00149   GV.IntVal = 0;
00150   return GV;
00151 }
00152 
00153 // void exit(int)
00154 GenericValue lle_X_exit(FunctionType *FT, const vector<GenericValue> &Args) {
00155   TheInterpreter->exitCalled(Args[0]);
00156   return GenericValue();
00157 }
00158 
00159 // void abort(void)
00160 GenericValue lle_X_abort(FunctionType *FT, const vector<GenericValue> &Args) {
00161   raise (SIGABRT);
00162   return GenericValue();
00163 }
00164 
00165 // void *malloc(uint)
00166 GenericValue lle_X_malloc(FunctionType *FT, const vector<GenericValue> &Args) {
00167   assert(Args.size() == 1 && "Malloc expects one argument!");
00168   assert(isa<PointerType>(FT->getReturnType()) && "malloc must return pointer");
00169   return PTOGV(malloc(Args[0].IntVal.getZExtValue()));
00170 }
00171 
00172 // void *calloc(uint, uint)
00173 GenericValue lle_X_calloc(FunctionType *FT, const vector<GenericValue> &Args) {
00174   assert(Args.size() == 2 && "calloc expects two arguments!");
00175   assert(isa<PointerType>(FT->getReturnType()) && "calloc must return pointer");
00176   return PTOGV(calloc(Args[0].IntVal.getZExtValue(), 
00177                       Args[1].IntVal.getZExtValue()));
00178 }
00179 
00180 // void *calloc(uint, uint)
00181 GenericValue lle_X_realloc(FunctionType *FT, const vector<GenericValue> &Args) {
00182   assert(Args.size() == 2 && "calloc expects two arguments!");
00183   assert(isa<PointerType>(FT->getReturnType()) &&"realloc must return pointer");
00184   return PTOGV(realloc(GVTOP(Args[0]), Args[1].IntVal.getZExtValue()));
00185 }
00186 
00187 // void free(void *)
00188 GenericValue lle_X_free(FunctionType *FT, const vector<GenericValue> &Args) {
00189   assert(Args.size() == 1);
00190   free(GVTOP(Args[0]));
00191   return GenericValue();
00192 }
00193 
00194 // int atoi(char *)
00195 GenericValue lle_X_atoi(FunctionType *FT, const vector<GenericValue> &Args) {
00196   assert(Args.size() == 1);
00197   GenericValue GV;
00198   GV.IntVal = APInt(32, atoi((char*)GVTOP(Args[0])));
00199   return GV;
00200 }
00201 
00202 // double pow(double, double)
00203 GenericValue lle_X_pow(FunctionType *FT, const vector<GenericValue> &Args) {
00204   assert(Args.size() == 2);
00205   GenericValue GV;
00206   GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal);
00207   return GV;
00208 }
00209 
00210 // double sin(double)
00211 GenericValue lle_X_sin(FunctionType *FT, const vector<GenericValue> &Args) {
00212   assert(Args.size() == 1);
00213   GenericValue GV;
00214   GV.DoubleVal = sin(Args[0].DoubleVal);
00215   return GV;
00216 }
00217 
00218 // double cos(double)
00219 GenericValue lle_X_cos(FunctionType *FT, const vector<GenericValue> &Args) {
00220   assert(Args.size() == 1);
00221   GenericValue GV;
00222   GV.DoubleVal = cos(Args[0].DoubleVal);
00223   return GV;
00224 }
00225 
00226 // double exp(double)
00227 GenericValue lle_X_exp(FunctionType *FT, const vector<GenericValue> &Args) {
00228   assert(Args.size() == 1);
00229   GenericValue GV;
00230   GV.DoubleVal = exp(Args[0].DoubleVal);
00231   return GV;
00232 }
00233 
00234 // double sqrt(double)
00235 GenericValue lle_X_sqrt(FunctionType *FT, const vector<GenericValue> &Args) {
00236   assert(Args.size() == 1);
00237   GenericValue GV;
00238   GV.DoubleVal = sqrt(Args[0].DoubleVal);
00239   return GV;
00240 }
00241 
00242 // double log(double)
00243 GenericValue lle_X_log(FunctionType *FT, const vector<GenericValue> &Args) {
00244   assert(Args.size() == 1);
00245   GenericValue GV;
00246   GV.DoubleVal = log(Args[0].DoubleVal);
00247   return GV;
00248 }
00249 
00250 // double floor(double)
00251 GenericValue lle_X_floor(FunctionType *FT, const vector<GenericValue> &Args) {
00252   assert(Args.size() == 1);
00253   GenericValue GV;
00254   GV.DoubleVal = floor(Args[0].DoubleVal);
00255   return GV;
00256 }
00257 
00258 #ifdef HAVE_RAND48
00259 
00260 // double drand48()
00261 GenericValue lle_X_drand48(FunctionType *FT, const vector<GenericValue> &Args) {
00262   assert(Args.empty());
00263   GenericValue GV;
00264   GV.DoubleVal = drand48();
00265   return GV;
00266 }
00267 
00268 // long lrand48()
00269 GenericValue lle_X_lrand48(FunctionType *FT, const vector<GenericValue> &Args) {
00270   assert(Args.empty());
00271   GenericValue GV;
00272   GV.IntVal = APInt(32, lrand48());
00273   return GV;
00274 }
00275 
00276 // void srand48(long)
00277 GenericValue lle_X_srand48(FunctionType *FT, const vector<GenericValue> &Args) {
00278   assert(Args.size() == 1);
00279   srand48(Args[0].IntVal.getZExtValue());
00280   return GenericValue();
00281 }
00282 
00283 #endif
00284 
00285 // int rand()
00286 GenericValue lle_X_rand(FunctionType *FT, const vector<GenericValue> &Args) {
00287   assert(Args.empty());
00288   GenericValue GV;
00289   GV.IntVal = APInt(32, rand());
00290   return GV;
00291 }
00292 
00293 // void srand(uint)
00294 GenericValue lle_X_srand(FunctionType *FT, const vector<GenericValue> &Args) {
00295   assert(Args.size() == 1);
00296   srand(Args[0].IntVal.getZExtValue());
00297   return GenericValue();
00298 }
00299 
00300 // int puts(const char*)
00301 GenericValue lle_X_puts(FunctionType *FT, const vector<GenericValue> &Args) {
00302   assert(Args.size() == 1);
00303   GenericValue GV;
00304   GV.IntVal = APInt(32, puts((char*)GVTOP(Args[0])));
00305   return GV;
00306 }
00307 
00308 // int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make
00309 // output useful.
00310 GenericValue lle_X_sprintf(FunctionType *FT, const vector<GenericValue> &Args) {
00311   char *OutputBuffer = (char *)GVTOP(Args[0]);
00312   const char *FmtStr = (const char *)GVTOP(Args[1]);
00313   unsigned ArgNo = 2;
00314 
00315   // printf should return # chars printed.  This is completely incorrect, but
00316   // close enough for now.
00317   GenericValue GV; 
00318   GV.IntVal = APInt(32, strlen(FmtStr));
00319   while (1) {
00320     switch (*FmtStr) {
00321     case 0: return GV;             // Null terminator...
00322     default:                       // Normal nonspecial character
00323       sprintf(OutputBuffer++, "%c", *FmtStr++);
00324       break;
00325     case '\\': {                   // Handle escape codes
00326       sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1));
00327       FmtStr += 2; OutputBuffer += 2;
00328       break;
00329     }
00330     case '%': {                    // Handle format specifiers
00331       char FmtBuf[100] = "", Buffer[1000] = "";
00332       char *FB = FmtBuf;
00333       *FB++ = *FmtStr++;
00334       char Last = *FB++ = *FmtStr++;
00335       unsigned HowLong = 0;
00336       while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
00337              Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
00338              Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
00339              Last != 'p' && Last != 's' && Last != '%') {
00340         if (Last == 'l' || Last == 'L') HowLong++;  // Keep track of l's
00341         Last = *FB++ = *FmtStr++;
00342       }
00343       *FB = 0;
00344 
00345       switch (Last) {
00346       case '%':
00347         strcpy(Buffer, "%"); break;
00348       case 'c':
00349         sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
00350         break;
00351       case 'd': case 'i':
00352       case 'u': case 'o':
00353       case 'x': case 'X':
00354         if (HowLong >= 1) {
00355           if (HowLong == 1 &&
00356               TheInterpreter->getTargetData()->getPointerSizeInBits() == 64 &&
00357               sizeof(long) < sizeof(int64_t)) {
00358             // Make sure we use %lld with a 64 bit argument because we might be
00359             // compiling LLI on a 32 bit compiler.
00360             unsigned Size = strlen(FmtBuf);
00361             FmtBuf[Size] = FmtBuf[Size-1];
00362             FmtBuf[Size+1] = 0;
00363             FmtBuf[Size-1] = 'l';
00364           }
00365           sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal.getZExtValue());
00366         } else
00367           sprintf(Buffer, FmtBuf,uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
00368         break;
00369       case 'e': case 'E': case 'g': case 'G': case 'f':
00370         sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
00371       case 'p':
00372         sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break;
00373       case 's':
00374         sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break;
00375       default:  cerr << "<unknown printf code '" << *FmtStr << "'!>";
00376         ArgNo++; break;
00377       }
00378       strcpy(OutputBuffer, Buffer);
00379       OutputBuffer += strlen(Buffer);
00380       }
00381       break;
00382     }
00383   }
00384   return GV;
00385 }
00386 
00387 // int printf(sbyte *, ...) - a very rough implementation to make output useful.
00388 GenericValue lle_X_printf(FunctionType *FT, const vector<GenericValue> &Args) {
00389   char Buffer[10000];
00390   vector<GenericValue> NewArgs;
00391   NewArgs.push_back(PTOGV((void*)&Buffer[0]));
00392   NewArgs.insert(NewArgs.end(), Args.begin(), Args.end());
00393   GenericValue GV = lle_X_sprintf(FT, NewArgs);
00394   cout << Buffer;
00395   return GV;
00396 }
00397 
00398 static void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1,
00399                                  void *Arg2, void *Arg3, void *Arg4, void *Arg5,
00400                                  void *Arg6, void *Arg7, void *Arg8) {
00401   void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 };
00402 
00403   // Loop over the format string, munging read values as appropriate (performs
00404   // byteswaps as necessary).
00405   unsigned ArgNo = 0;
00406   while (*Fmt) {
00407     if (*Fmt++ == '%') {
00408       // Read any flag characters that may be present...
00409       bool Suppress = false;
00410       bool Half = false;
00411       bool Long = false;
00412       bool LongLong = false;  // long long or long double
00413 
00414       while (1) {
00415         switch (*Fmt++) {
00416         case '*': Suppress = true; break;
00417         case 'a': /*Allocate = true;*/ break;  // We don't need to track this
00418         case 'h': Half = true; break;
00419         case 'l': Long = true; break;
00420         case 'q':
00421         case 'L': LongLong = true; break;
00422         default:
00423           if (Fmt[-1] > '9' || Fmt[-1] < '0')   // Ignore field width specs
00424             goto Out;
00425         }
00426       }
00427     Out:
00428 
00429       // Read the conversion character
00430       if (!Suppress && Fmt[-1] != '%') { // Nothing to do?
00431         unsigned Size = 0;
00432         const Type *Ty = 0;
00433 
00434         switch (Fmt[-1]) {
00435         case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p':
00436         case 'd':
00437           if (Long || LongLong) {
00438             Size = 8; Ty = Type::Int64Ty;
00439           } else if (Half) {
00440             Size = 4; Ty = Type::Int16Ty;
00441           } else {
00442             Size = 4; Ty = Type::Int32Ty;
00443           }
00444           break;
00445 
00446         case 'e': case 'g': case 'E':
00447         case 'f':
00448           if (Long || LongLong) {
00449             Size = 8; Ty = Type::DoubleTy;
00450           } else {
00451             Size = 4; Ty = Type::FloatTy;
00452           }
00453           break;
00454 
00455         case 's': case 'c': case '[':  // No byteswap needed
00456           Size = 1;
00457           Ty = Type::Int8Ty;
00458           break;
00459 
00460         default: break;
00461         }
00462 
00463         if (Size) {
00464           GenericValue GV;
00465           void *Arg = Args[ArgNo++];
00466           memcpy(&GV, Arg, Size);
00467           TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty);
00468         }
00469       }
00470     }
00471   }
00472 }
00473 
00474 // int sscanf(const char *format, ...);
00475 GenericValue lle_X_sscanf(FunctionType *FT, const vector<GenericValue> &args) {
00476   assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");
00477 
00478   char *Args[10];
00479   for (unsigned i = 0; i < args.size(); ++i)
00480     Args[i] = (char*)GVTOP(args[i]);
00481 
00482   GenericValue GV;
00483   GV.IntVal = APInt(32, sscanf(Args[0], Args[1], Args[2], Args[3], Args[4],
00484                         Args[5], Args[6], Args[7], Args[8], Args[9]));
00485   ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4],
00486                        Args[5], Args[6], Args[7], Args[8], Args[9], 0);
00487   return GV;
00488 }
00489 
00490 // int scanf(const char *format, ...);
00491 GenericValue lle_X_scanf(FunctionType *FT, const vector<GenericValue> &args) {
00492   assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");
00493 
00494   char *Args[10];
00495   for (unsigned i = 0; i < args.size(); ++i)
00496     Args[i] = (char*)GVTOP(args[i]);
00497 
00498   GenericValue GV;
00499   GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4],
00500                         Args[5], Args[6], Args[7], Args[8], Args[9]));
00501   ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4],
00502                        Args[5], Args[6], Args[7], Args[8], Args[9]);
00503   return GV;
00504 }
00505 
00506 
00507 // int clock(void) - Profiling implementation
00508 GenericValue lle_i_clock(FunctionType *FT, const vector<GenericValue> &Args) {
00509   extern unsigned int clock(void);
00510   GenericValue GV; 
00511   GV.IntVal = APInt(32, clock());
00512   return GV;
00513 }
00514 
00515 
00516 //===----------------------------------------------------------------------===//
00517 // String Functions...
00518 //===----------------------------------------------------------------------===//
00519 
00520 // int strcmp(const char *S1, const char *S2);
00521 GenericValue lle_X_strcmp(FunctionType *FT, const vector<GenericValue> &Args) {
00522   assert(Args.size() == 2);
00523   GenericValue Ret;
00524   Ret.IntVal = APInt(32, strcmp((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
00525   return Ret;
00526 }
00527 
00528 // char *strcat(char *Dest, const char *src);
00529 GenericValue lle_X_strcat(FunctionType *FT, const vector<GenericValue> &Args) {
00530   assert(Args.size() == 2);
00531   assert(isa<PointerType>(FT->getReturnType()) &&"strcat must return pointer");
00532   return PTOGV(strcat((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
00533 }
00534 
00535 // char *strcpy(char *Dest, const char *src);
00536 GenericValue lle_X_strcpy(FunctionType *FT, const vector<GenericValue> &Args) {
00537   assert(Args.size() == 2);
00538   assert(isa<PointerType>(FT->getReturnType()) &&"strcpy must return pointer");
00539   return PTOGV(strcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
00540 }
00541 
00542 static GenericValue size_t_to_GV (size_t n) {
00543   GenericValue Ret;
00544   if (sizeof (size_t) == sizeof (uint64_t)) {
00545     Ret.IntVal = APInt(64, n);
00546   } else {
00547     assert (sizeof (size_t) == sizeof (unsigned int));
00548     Ret.IntVal = APInt(32, n);
00549   }
00550   return Ret;
00551 }
00552 
00553 static size_t GV_to_size_t (GenericValue GV) {
00554   size_t count;
00555   if (sizeof (size_t) == sizeof (uint64_t)) {
00556     count = (size_t)GV.IntVal.getZExtValue();
00557   } else {
00558     assert (sizeof (size_t) == sizeof (unsigned int));
00559     count = (size_t)GV.IntVal.getZExtValue();
00560   }
00561   return count;
00562 }
00563 
00564 // size_t strlen(const char *src);
00565 GenericValue lle_X_strlen(FunctionType *FT, const vector<GenericValue> &Args) {
00566   assert(Args.size() == 1);
00567   size_t strlenResult = strlen ((char *) GVTOP (Args[0]));
00568   return size_t_to_GV (strlenResult);
00569 }
00570 
00571 // char *strdup(const char *src);
00572 GenericValue lle_X_strdup(FunctionType *FT, const vector<GenericValue> &Args) {
00573   assert(Args.size() == 1);
00574   assert(isa<PointerType>(FT->getReturnType()) && "strdup must return pointer");
00575   return PTOGV(strdup((char*)GVTOP(Args[0])));
00576 }
00577 
00578 // char *__strdup(const char *src);
00579 GenericValue lle_X___strdup(FunctionType *FT, const vector<GenericValue> &Args) {
00580   assert(Args.size() == 1);
00581   assert(isa<PointerType>(FT->getReturnType()) &&"_strdup must return pointer");
00582   return PTOGV(strdup((char*)GVTOP(Args[0])));
00583 }
00584 
00585 // void *memset(void *S, int C, size_t N)
00586 GenericValue lle_X_memset(FunctionType *FT, const vector<GenericValue> &Args) {
00587   assert(Args.size() == 3);
00588   size_t count = GV_to_size_t (Args[2]);
00589   assert(isa<PointerType>(FT->getReturnType()) && "memset must return pointer");
00590   return PTOGV(memset(GVTOP(Args[0]), uint32_t(Args[1].IntVal.getZExtValue()), 
00591                       count));
00592 }
00593 
00594 // void *memcpy(void *Dest, void *src, size_t Size);
00595 GenericValue lle_X_memcpy(FunctionType *FT, const vector<GenericValue> &Args) {
00596   assert(Args.size() == 3);
00597   assert(isa<PointerType>(FT->getReturnType()) && "memcpy must return pointer");
00598   size_t count = GV_to_size_t (Args[2]);
00599   return PTOGV(memcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count));
00600 }
00601 
00602 // void *memcpy(void *Dest, void *src, size_t Size);
00603 GenericValue lle_X_memmove(FunctionType *FT, const vector<GenericValue> &Args) {
00604   assert(Args.size() == 3);
00605   assert(isa<PointerType>(FT->getReturnType()) && "memmove must return pointer");
00606   size_t count = GV_to_size_t (Args[2]);
00607   return PTOGV(memmove((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count));
00608 }
00609 
00610 //===----------------------------------------------------------------------===//
00611 // IO Functions...
00612 //===----------------------------------------------------------------------===//
00613 
00614 // getFILE - Turn a pointer in the host address space into a legit pointer in
00615 // the interpreter address space.  This is an identity transformation.
00616 #define getFILE(ptr) ((FILE*)ptr)
00617 
00618 // FILE *fopen(const char *filename, const char *mode);
00619 GenericValue lle_X_fopen(FunctionType *FT, const vector<GenericValue> &Args) {
00620   assert(Args.size() == 2);
00621   assert(isa<PointerType>(FT->getReturnType()) && "fopen must return pointer");
00622   return PTOGV(fopen((const char *)GVTOP(Args[0]),
00623                      (const char *)GVTOP(Args[1])));
00624 }
00625 
00626 // int fclose(FILE *F);
00627 GenericValue lle_X_fclose(FunctionType *FT, const vector<GenericValue> &Args) {
00628   assert(Args.size() == 1);
00629   GenericValue GV;
00630   GV.IntVal = APInt(32, fclose(getFILE(GVTOP(Args[0]))));
00631   return GV;
00632 }
00633 
00634 // int feof(FILE *stream);
00635 GenericValue lle_X_feof(FunctionType *FT, const vector<GenericValue> &Args) {
00636   assert(Args.size() == 1);
00637   GenericValue GV;
00638 
00639   GV.IntVal = APInt(32, feof(getFILE(GVTOP(Args[0]))));
00640   return GV;
00641 }
00642 
00643 // size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
00644 GenericValue lle_X_fread(FunctionType *FT, const vector<GenericValue> &Args) {
00645   assert(Args.size() == 4);
00646   size_t result;
00647 
00648   result = fread((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
00649                  GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
00650   return size_t_to_GV (result);
00651 }
00652 
00653 // size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
00654 GenericValue lle_X_fwrite(FunctionType *FT, const vector<GenericValue> &Args) {
00655   assert(Args.size() == 4);
00656   size_t result;
00657 
00658   result = fwrite((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
00659                   GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
00660   return size_t_to_GV (result);
00661 }
00662 
00663 // char *fgets(char *s, int n, FILE *stream);
00664 GenericValue lle_X_fgets(FunctionType *FT, const vector<GenericValue> &Args) {
00665   assert(Args.size() == 3);
00666   return PTOGV(fgets((char*)GVTOP(Args[0]), Args[1].IntVal.getZExtValue(),
00667                      getFILE(GVTOP(Args[2]))));
00668 }
00669 
00670 // FILE *freopen(const char *path, const char *mode, FILE *stream);
00671 GenericValue lle_X_freopen(FunctionType *FT, const vector<GenericValue> &Args) {
00672   assert(Args.size() == 3);
00673   assert(isa<PointerType>(FT->getReturnType()) &&"freopen must return pointer");
00674   return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]),
00675                        getFILE(GVTOP(Args[2]))));
00676 }
00677 
00678 // int fflush(FILE *stream);
00679 GenericValue lle_X_fflush(FunctionType *FT, const vector<GenericValue> &Args) {
00680   assert(Args.size() == 1);
00681   GenericValue GV;
00682   GV.IntVal = APInt(32, fflush(getFILE(GVTOP(Args[0]))));
00683   return GV;
00684 }
00685 
00686 // int getc(FILE *stream);
00687 GenericValue lle_X_getc(FunctionType *FT, const vector<GenericValue> &Args) {
00688   assert(Args.size() == 1);
00689   GenericValue GV;
00690   GV.IntVal = APInt(32, getc(getFILE(GVTOP(Args[0]))));
00691   return GV;
00692 }
00693 
00694 // int _IO_getc(FILE *stream);
00695 GenericValue lle_X__IO_getc(FunctionType *F, const vector<GenericValue> &Args) {
00696   return lle_X_getc(F, Args);
00697 }
00698 
00699 // int fputc(int C, FILE *stream);
00700 GenericValue lle_X_fputc(FunctionType *FT, const vector<GenericValue> &Args) {
00701   assert(Args.size() == 2);
00702   GenericValue GV;
00703   GV.IntVal = APInt(32, fputc(Args[0].IntVal.getZExtValue(), 
00704                               getFILE(GVTOP(Args[1]))));
00705   return GV;
00706 }
00707 
00708 // int ungetc(int C, FILE *stream);
00709 GenericValue lle_X_ungetc(FunctionType *FT, const vector<GenericValue> &Args) {
00710   assert(Args.size() == 2);
00711   GenericValue GV;
00712   GV.IntVal = APInt(32, ungetc(Args[0].IntVal.getZExtValue(), 
00713                                getFILE(GVTOP(Args[1]))));
00714   return GV;
00715 }
00716 
00717 // int ferror (FILE *stream);
00718 GenericValue lle_X_ferror(FunctionType *FT, const vector<GenericValue> &Args) {
00719   assert(Args.size() == 1);
00720   GenericValue GV;
00721   GV.IntVal = APInt(32, ferror (getFILE(GVTOP(Args[0]))));
00722   return GV;
00723 }
00724 
00725 // int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output
00726 // useful.
00727 GenericValue lle_X_fprintf(FunctionType *FT, const vector<GenericValue> &Args) {
00728   assert(Args.size() >= 2);
00729   char Buffer[10000];
00730   vector<GenericValue> NewArgs;
00731   NewArgs.push_back(PTOGV(Buffer));
00732   NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end());
00733   GenericValue GV = lle_X_sprintf(FT, NewArgs);
00734 
00735   fputs(Buffer, getFILE(GVTOP(Args[0])));
00736   return GV;
00737 }
00738 
00739 // int __cxa_guard_acquire (__guard *g);
00740 GenericValue lle_X___cxa_guard_acquire(FunctionType *FT, 
00741                                        const vector<GenericValue> &Args) {
00742   assert(Args.size() == 1);
00743   GenericValue GV;
00744 #ifdef __linux__
00745   GV.IntVal = APInt(32, __cxxabiv1::__cxa_guard_acquire (
00746                           (__cxxabiv1::__guard*)GVTOP(Args[0])));
00747 #else
00748   assert(0 && "Can't call __cxa_guard_acquire on this platform");
00749 #endif
00750   return GV;
00751 }
00752 
00753 // void __cxa_guard_release (__guard *g);
00754 GenericValue lle_X___cxa_guard_release(FunctionType *FT, 
00755                                        const vector<GenericValue> &Args) {
00756   assert(Args.size() == 1);
00757 #ifdef __linux__
00758   __cxxabiv1::__cxa_guard_release ((__cxxabiv1::__guard*)GVTOP(Args[0]));
00759 #else
00760   assert(0 && "Can't call __cxa_guard_release on this platform");
00761 #endif
00762   return GenericValue();
00763 }
00764 
00765 } // End extern "C"
00766 
00767 
00768 void Interpreter::initializeExternalFunctions() {
00769   FuncNames["lle_X_putchar"]      = lle_X_putchar;
00770   FuncNames["lle_X__IO_putc"]     = lle_X__IO_putc;
00771   FuncNames["lle_X_exit"]         = lle_X_exit;
00772   FuncNames["lle_X_abort"]        = lle_X_abort;
00773   FuncNames["lle_X_malloc"]       = lle_X_malloc;
00774   FuncNames["lle_X_calloc"]       = lle_X_calloc;
00775   FuncNames["lle_X_realloc"]      = lle_X_realloc;
00776   FuncNames["lle_X_free"]         = lle_X_free;
00777   FuncNames["lle_X_atoi"]         = lle_X_atoi;
00778   FuncNames["lle_X_pow"]          = lle_X_pow;
00779   FuncNames["lle_X_sin"]          = lle_X_sin;
00780   FuncNames["lle_X_cos"]          = lle_X_cos;
00781   FuncNames["lle_X_exp"]          = lle_X_exp;
00782   FuncNames["lle_X_log"]          = lle_X_log;
00783   FuncNames["lle_X_floor"]        = lle_X_floor;
00784   FuncNames["lle_X_srand"]        = lle_X_srand;
00785   FuncNames["lle_X_rand"]         = lle_X_rand;
00786 #ifdef HAVE_RAND48
00787   FuncNames["lle_X_drand48"]      = lle_X_drand48;
00788   FuncNames["lle_X_srand48"]      = lle_X_srand48;
00789   FuncNames["lle_X_lrand48"]      = lle_X_lrand48;
00790 #endif
00791   FuncNames["lle_X_sqrt"]         = lle_X_sqrt;
00792   FuncNames["lle_X_puts"]         = lle_X_puts;
00793   FuncNames["lle_X_printf"]       = lle_X_printf;
00794   FuncNames["lle_X_sprintf"]      = lle_X_sprintf;
00795   FuncNames["lle_X_sscanf"]       = lle_X_sscanf;
00796   FuncNames["lle_X_scanf"]        = lle_X_scanf;
00797   FuncNames["lle_i_clock"]        = lle_i_clock;
00798 
00799   FuncNames["lle_X_strcmp"]       = lle_X_strcmp;
00800   FuncNames["lle_X_strcat"]       = lle_X_strcat;
00801   FuncNames["lle_X_strcpy"]       = lle_X_strcpy;
00802   FuncNames["lle_X_strlen"]       = lle_X_strlen;
00803   FuncNames["lle_X___strdup"]     = lle_X___strdup;
00804   FuncNames["lle_X_memset"]       = lle_X_memset;
00805   FuncNames["lle_X_memcpy"]       = lle_X_memcpy;
00806   FuncNames["lle_X_memmove"]      = lle_X_memmove;
00807 
00808   FuncNames["lle_X_fopen"]        = lle_X_fopen;
00809   FuncNames["lle_X_fclose"]       = lle_X_fclose;
00810   FuncNames["lle_X_feof"]         = lle_X_feof;
00811   FuncNames["lle_X_fread"]        = lle_X_fread;
00812   FuncNames["lle_X_fwrite"]       = lle_X_fwrite;
00813   FuncNames["lle_X_fgets"]        = lle_X_fgets;
00814   FuncNames["lle_X_fflush"]       = lle_X_fflush;
00815   FuncNames["lle_X_fgetc"]        = lle_X_getc;
00816   FuncNames["lle_X_getc"]         = lle_X_getc;
00817   FuncNames["lle_X__IO_getc"]     = lle_X__IO_getc;
00818   FuncNames["lle_X_fputc"]        = lle_X_fputc;
00819   FuncNames["lle_X_ungetc"]       = lle_X_ungetc;
00820   FuncNames["lle_X_fprintf"]      = lle_X_fprintf;
00821   FuncNames["lle_X_freopen"]      = lle_X_freopen;
00822 
00823   FuncNames["lle_X___cxa_guard_acquire"] = lle_X___cxa_guard_acquire;
00824   FuncNames["lle_X____cxa_guard_release"] = lle_X___cxa_guard_release;
00825 }
00826