ExternalFunctions.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. //===-- ExternalFunctions.cpp - Implement External Functions --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file contains both code to deal with invoking "external" functions, but
  11. // also contains code that implements "exported" external functions.
  12. //
  13. // External functions in the interpreter are implemented by
  14. // using the system's dynamic loader to look up the address of the function
  15. // we want to invoke. If a function is found, then one of the
  16. // many lle_* wrapper functions in this file will translate its arguments from
  17. // GenericValues to the types the function is actually expecting, before the
  18. // function is called.
  19. //
  20. //===----------------------------------------------------------------------===//
  21. #include "Interpreter.h"
  22. #include "llvm/DerivedTypes.h"
  23. #include "llvm/Module.h"
  24. #include "llvm/Support/Streams.h"
  25. #include "llvm/System/DynamicLibrary.h"
  26. #include "llvm/Target/TargetData.h"
  27. #include "llvm/Support/ManagedStatic.h"
  28. #include <csignal>
  29. #include <map>
  30. #include <cmath>
  31. #include <cstring>
  32. #ifdef __linux__
  33. #include <cxxabi.h>
  34. #endif
  35. using std::vector;
  36. using namespace llvm;
  37. typedef GenericValue (*ExFunc)(FunctionType *, const vector<GenericValue> &);
  38. static ManagedStatic<std::map<const Function *, ExFunc> > Functions;
  39. static std::map<std::string, ExFunc> FuncNames;
  40. static Interpreter *TheInterpreter;
  41. static char getTypeID(const Type *Ty) {
  42. switch (Ty->getTypeID()) {
  43. case Type::VoidTyID: return 'V';
  44. case Type::IntegerTyID:
  45. switch (cast<IntegerType>(Ty)->getBitWidth()) {
  46. case 1: return 'o';
  47. case 8: return 'B';
  48. case 16: return 'S';
  49. case 32: return 'I';
  50. case 64: return 'L';
  51. default: return 'N';
  52. }
  53. case Type::FloatTyID: return 'F';
  54. case Type::DoubleTyID: return 'D';
  55. case Type::PointerTyID: return 'P';
  56. case Type::FunctionTyID:return 'M';
  57. case Type::StructTyID: return 'T';
  58. case Type::ArrayTyID: return 'A';
  59. case Type::OpaqueTyID: return 'O';
  60. default: return 'U';
  61. }
  62. }
  63. // Try to find address of external function given a Function object.
  64. // Please note, that interpreter doesn't know how to assemble a
  65. // real call in general case (this is JIT job), that's why it assumes,
  66. // that all external functions has the same (and pretty "general") signature.
  67. // The typical example of such functions are "lle_X_" ones.
  68. static ExFunc lookupFunction(const Function *F) {
  69. // Function not found, look it up... start by figuring out what the
  70. // composite function name should be.
  71. std::string ExtName = "lle_";
  72. const FunctionType *FT = F->getFunctionType();
  73. for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i)
  74. ExtName += getTypeID(FT->getContainedType(i));
  75. ExtName += "_" + F->getName();
  76. ExFunc FnPtr = FuncNames[ExtName];
  77. if (FnPtr == 0)
  78. FnPtr = FuncNames["lle_X_"+F->getName()];
  79. if (FnPtr == 0) // Try calling a generic function... if it exists...
  80. FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
  81. ("lle_X_"+F->getName()).c_str());
  82. if (FnPtr == 0)
  83. FnPtr = (ExFunc)(intptr_t)
  84. sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName());
  85. if (FnPtr != 0)
  86. Functions->insert(std::make_pair(F, FnPtr)); // Cache for later
  87. return FnPtr;
  88. }
  89. GenericValue Interpreter::callExternalFunction(Function *F,
  90. const std::vector<GenericValue> &ArgVals) {
  91. TheInterpreter = this;
  92. // Do a lookup to see if the function is in our cache... this should just be a
  93. // deferred annotation!
  94. std::map<const Function *, ExFunc>::iterator FI = Functions->find(F);
  95. ExFunc Fn = (FI == Functions->end()) ? lookupFunction(F) : FI->second;
  96. if (Fn == 0) {
  97. cerr << "Tried to execute an unknown external function: "
  98. << F->getType()->getDescription() << " " << F->getName() << "\n";
  99. if (F->getName() == "__main")
  100. return GenericValue();
  101. abort();
  102. }
  103. // TODO: FIXME when types are not const!
  104. GenericValue Result = Fn(const_cast<FunctionType*>(F->getFunctionType()),
  105. ArgVals);
  106. return Result;
  107. }
  108. //===----------------------------------------------------------------------===//
  109. // Functions "exported" to the running application...
  110. //
  111. extern "C" { // Don't add C++ manglings to llvm mangling :)
  112. // void putchar(ubyte)
  113. GenericValue lle_X_putchar(FunctionType *FT, const vector<GenericValue> &Args){
  114. cout << ((char)Args[0].IntVal.getZExtValue()) << std::flush;
  115. return Args[0];
  116. }
  117. // void _IO_putc(int c, FILE* fp)
  118. GenericValue lle_X__IO_putc(FunctionType *FT, const vector<GenericValue> &Args){
  119. #ifdef __linux__
  120. _IO_putc((char)Args[0].IntVal.getZExtValue(), (FILE*) Args[1].PointerVal);
  121. #else
  122. assert(0 && "Can't call _IO_putc on this platform");
  123. #endif
  124. return Args[0];
  125. }
  126. // void atexit(Function*)
  127. GenericValue lle_X_atexit(FunctionType *FT, const vector<GenericValue> &Args) {
  128. assert(Args.size() == 1);
  129. TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
  130. GenericValue GV;
  131. GV.IntVal = 0;
  132. return GV;
  133. }
  134. // void exit(int)
  135. GenericValue lle_X_exit(FunctionType *FT, const vector<GenericValue> &Args) {
  136. TheInterpreter->exitCalled(Args[0]);
  137. return GenericValue();
  138. }
  139. // void abort(void)
  140. GenericValue lle_X_abort(FunctionType *FT, const vector<GenericValue> &Args) {
  141. raise (SIGABRT);
  142. return GenericValue();
  143. }
  144. // void *malloc(uint)
  145. GenericValue lle_X_malloc(FunctionType *FT, const vector<GenericValue> &Args) {
  146. assert(Args.size() == 1 && "Malloc expects one argument!");
  147. assert(isa<PointerType>(FT->getReturnType()) && "malloc must return pointer");
  148. return PTOGV(malloc(Args[0].IntVal.getZExtValue()));
  149. }
  150. // void *calloc(uint, uint)
  151. GenericValue lle_X_calloc(FunctionType *FT, const vector<GenericValue> &Args) {
  152. assert(Args.size() == 2 && "calloc expects two arguments!");
  153. assert(isa<PointerType>(FT->getReturnType()) && "calloc must return pointer");
  154. return PTOGV(calloc(Args[0].IntVal.getZExtValue(),
  155. Args[1].IntVal.getZExtValue()));
  156. }
  157. // void *calloc(uint, uint)
  158. GenericValue lle_X_realloc(FunctionType *FT, const vector<GenericValue> &Args) {
  159. assert(Args.size() == 2 && "calloc expects two arguments!");
  160. assert(isa<PointerType>(FT->getReturnType()) &&"realloc must return pointer");
  161. return PTOGV(realloc(GVTOP(Args[0]), Args[1].IntVal.getZExtValue()));
  162. }
  163. // void free(void *)
  164. GenericValue lle_X_free(FunctionType *FT, const vector<GenericValue> &Args) {
  165. assert(Args.size() == 1);
  166. free(GVTOP(Args[0]));
  167. return GenericValue();
  168. }
  169. // int atoi(char *)
  170. GenericValue lle_X_atoi(FunctionType *FT, const vector<GenericValue> &Args) {
  171. assert(Args.size() == 1);
  172. GenericValue GV;
  173. GV.IntVal = APInt(32, atoi((char*)GVTOP(Args[0])));
  174. return GV;
  175. }
  176. // double pow(double, double)
  177. GenericValue lle_X_pow(FunctionType *FT, const vector<GenericValue> &Args) {
  178. assert(Args.size() == 2);
  179. GenericValue GV;
  180. GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal);
  181. return GV;
  182. }
  183. // double sin(double)
  184. GenericValue lle_X_sin(FunctionType *FT, const vector<GenericValue> &Args) {
  185. assert(Args.size() == 1);
  186. GenericValue GV;
  187. GV.DoubleVal = sin(Args[0].DoubleVal);
  188. return GV;
  189. }
  190. // double cos(double)
  191. GenericValue lle_X_cos(FunctionType *FT, const vector<GenericValue> &Args) {
  192. assert(Args.size() == 1);
  193. GenericValue GV;
  194. GV.DoubleVal = cos(Args[0].DoubleVal);
  195. return GV;
  196. }
  197. // double exp(double)
  198. GenericValue lle_X_exp(FunctionType *FT, const vector<GenericValue> &Args) {
  199. assert(Args.size() == 1);
  200. GenericValue GV;
  201. GV.DoubleVal = exp(Args[0].DoubleVal);
  202. return GV;
  203. }
  204. // double sqrt(double)
  205. GenericValue lle_X_sqrt(FunctionType *FT, const vector<GenericValue> &Args) {
  206. assert(Args.size() == 1);
  207. GenericValue GV;
  208. GV.DoubleVal = sqrt(Args[0].DoubleVal);
  209. return GV;
  210. }
  211. // double log(double)
  212. GenericValue lle_X_log(FunctionType *FT, const vector<GenericValue> &Args) {
  213. assert(Args.size() == 1);
  214. GenericValue GV;
  215. GV.DoubleVal = log(Args[0].DoubleVal);
  216. return GV;
  217. }
  218. // double floor(double)
  219. GenericValue lle_X_floor(FunctionType *FT, const vector<GenericValue> &Args) {
  220. assert(Args.size() == 1);
  221. GenericValue GV;
  222. GV.DoubleVal = floor(Args[0].DoubleVal);
  223. return GV;
  224. }
  225. #ifdef HAVE_RAND48
  226. // double drand48()
  227. GenericValue lle_X_drand48(FunctionType *FT, const vector<GenericValue> &Args) {
  228. assert(Args.empty());
  229. GenericValue GV;
  230. GV.DoubleVal = drand48();
  231. return GV;
  232. }
  233. // long lrand48()
  234. GenericValue lle_X_lrand48(FunctionType *FT, const vector<GenericValue> &Args) {
  235. assert(Args.empty());
  236. GenericValue GV;
  237. GV.IntVal = APInt(32, lrand48());
  238. return GV;
  239. }
  240. // void srand48(long)
  241. GenericValue lle_X_srand48(FunctionType *FT, const vector<GenericValue> &Args) {
  242. assert(Args.size() == 1);
  243. srand48(Args[0].IntVal.getZExtValue());
  244. return GenericValue();
  245. }
  246. #endif
  247. // int rand()
  248. GenericValue lle_X_rand(FunctionType *FT, const vector<GenericValue> &Args) {
  249. assert(Args.empty());
  250. GenericValue GV;
  251. GV.IntVal = APInt(32, rand());
  252. return GV;
  253. }
  254. // void srand(uint)
  255. GenericValue lle_X_srand(FunctionType *FT, const vector<GenericValue> &Args) {
  256. assert(Args.size() == 1);
  257. srand(Args[0].IntVal.getZExtValue());
  258. return GenericValue();
  259. }
  260. // int puts(const char*)
  261. GenericValue lle_X_puts(FunctionType *FT, const vector<GenericValue> &Args) {
  262. assert(Args.size() == 1);
  263. GenericValue GV;
  264. GV.IntVal = APInt(32, puts((char*)GVTOP(Args[0])));
  265. return GV;
  266. }
  267. // int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make
  268. // output useful.
  269. GenericValue lle_X_sprintf(FunctionType *FT, const vector<GenericValue> &Args) {
  270. char *OutputBuffer = (char *)GVTOP(Args[0]);
  271. const char *FmtStr = (const char *)GVTOP(Args[1]);
  272. unsigned ArgNo = 2;
  273. // printf should return # chars printed. This is completely incorrect, but
  274. // close enough for now.
  275. GenericValue GV;
  276. GV.IntVal = APInt(32, strlen(FmtStr));
  277. while (1) {
  278. switch (*FmtStr) {
  279. case 0: return GV; // Null terminator...
  280. default: // Normal nonspecial character
  281. sprintf(OutputBuffer++, "%c", *FmtStr++);
  282. break;
  283. case '\\': { // Handle escape codes
  284. sprintf(OutputBuffer, "%c%c", *FmtStr, *(FmtStr+1));
  285. FmtStr += 2; OutputBuffer += 2;
  286. break;
  287. }
  288. case '%': { // Handle format specifiers
  289. char FmtBuf[100] = "", Buffer[1000] = "";
  290. char *FB = FmtBuf;
  291. *FB++ = *FmtStr++;
  292. char Last = *FB++ = *FmtStr++;
  293. unsigned HowLong = 0;
  294. while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
  295. Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
  296. Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
  297. Last != 'p' && Last != 's' && Last != '%') {
  298. if (Last == 'l' || Last == 'L') HowLong++; // Keep track of l's
  299. Last = *FB++ = *FmtStr++;
  300. }
  301. *FB = 0;
  302. switch (Last) {
  303. case '%':
  304. sprintf(Buffer, FmtBuf); break;
  305. case 'c':
  306. sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
  307. break;
  308. case 'd': case 'i':
  309. case 'u': case 'o':
  310. case 'x': case 'X':
  311. if (HowLong >= 1) {
  312. if (HowLong == 1 &&
  313. TheInterpreter->getTargetData()->getPointerSizeInBits() == 64 &&
  314. sizeof(long) < sizeof(int64_t)) {
  315. // Make sure we use %lld with a 64 bit argument because we might be
  316. // compiling LLI on a 32 bit compiler.
  317. unsigned Size = strlen(FmtBuf);
  318. FmtBuf[Size] = FmtBuf[Size-1];
  319. FmtBuf[Size+1] = 0;
  320. FmtBuf[Size-1] = 'l';
  321. }
  322. sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal.getZExtValue());
  323. } else
  324. sprintf(Buffer, FmtBuf,uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
  325. break;
  326. case 'e': case 'E': case 'g': case 'G': case 'f':
  327. sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
  328. case 'p':
  329. sprintf(Buffer, FmtBuf, (void*)GVTOP(Args[ArgNo++])); break;
  330. case 's':
  331. sprintf(Buffer, FmtBuf, (char*)GVTOP(Args[ArgNo++])); break;
  332. default: cerr << "<unknown printf code '" << *FmtStr << "'!>";
  333. ArgNo++; break;
  334. }
  335. strcpy(OutputBuffer, Buffer);
  336. OutputBuffer += strlen(Buffer);
  337. }
  338. break;
  339. }
  340. }
  341. return GV;
  342. }
  343. // int printf(sbyte *, ...) - a very rough implementation to make output useful.
  344. GenericValue lle_X_printf(FunctionType *FT, const vector<GenericValue> &Args) {
  345. char Buffer[10000];
  346. vector<GenericValue> NewArgs;
  347. NewArgs.push_back(PTOGV((void*)&Buffer[0]));
  348. NewArgs.insert(NewArgs.end(), Args.begin(), Args.end());
  349. GenericValue GV = lle_X_sprintf(FT, NewArgs);
  350. cout << Buffer;
  351. return GV;
  352. }
  353. static void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1,
  354. void *Arg2, void *Arg3, void *Arg4, void *Arg5,
  355. void *Arg6, void *Arg7, void *Arg8) {
  356. void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 };
  357. // Loop over the format string, munging read values as appropriate (performs
  358. // byteswaps as necessary).
  359. unsigned ArgNo = 0;
  360. while (*Fmt) {
  361. if (*Fmt++ == '%') {
  362. // Read any flag characters that may be present...
  363. bool Suppress = false;
  364. bool Half = false;
  365. bool Long = false;
  366. bool LongLong = false; // long long or long double
  367. while (1) {
  368. switch (*Fmt++) {
  369. case '*': Suppress = true; break;
  370. case 'a': /*Allocate = true;*/ break; // We don't need to track this
  371. case 'h': Half = true; break;
  372. case 'l': Long = true; break;
  373. case 'q':
  374. case 'L': LongLong = true; break;
  375. default:
  376. if (Fmt[-1] > '9' || Fmt[-1] < '0') // Ignore field width specs
  377. goto Out;
  378. }
  379. }
  380. Out:
  381. // Read the conversion character
  382. if (!Suppress && Fmt[-1] != '%') { // Nothing to do?
  383. unsigned Size = 0;
  384. const Type *Ty = 0;
  385. switch (Fmt[-1]) {
  386. case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p':
  387. case 'd':
  388. if (Long || LongLong) {
  389. Size = 8; Ty = Type::Int64Ty;
  390. } else if (Half) {
  391. Size = 4; Ty = Type::Int16Ty;
  392. } else {
  393. Size = 4; Ty = Type::Int32Ty;
  394. }
  395. break;
  396. case 'e': case 'g': case 'E':
  397. case 'f':
  398. if (Long || LongLong) {
  399. Size = 8; Ty = Type::DoubleTy;
  400. } else {
  401. Size = 4; Ty = Type::FloatTy;
  402. }
  403. break;
  404. case 's': case 'c': case '[': // No byteswap needed
  405. Size = 1;
  406. Ty = Type::Int8Ty;
  407. break;
  408. default: break;
  409. }
  410. if (Size) {
  411. GenericValue GV;
  412. void *Arg = Args[ArgNo++];
  413. memcpy(&GV, Arg, Size);
  414. TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty);
  415. }
  416. }
  417. }
  418. }
  419. }
  420. // int sscanf(const char *format, ...);
  421. GenericValue lle_X_sscanf(FunctionType *FT, const vector<GenericValue> &args) {
  422. assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");
  423. char *Args[10];
  424. for (unsigned i = 0; i < args.size(); ++i)
  425. Args[i] = (char*)GVTOP(args[i]);
  426. GenericValue GV;
  427. GV.IntVal = APInt(32, sscanf(Args[0], Args[1], Args[2], Args[3], Args[4],
  428. Args[5], Args[6], Args[7], Args[8], Args[9]));
  429. ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4],
  430. Args[5], Args[6], Args[7], Args[8], Args[9], 0);
  431. return GV;
  432. }
  433. // int scanf(const char *format, ...);
  434. GenericValue lle_X_scanf(FunctionType *FT, const vector<GenericValue> &args) {
  435. assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");
  436. char *Args[10];
  437. for (unsigned i = 0; i < args.size(); ++i)
  438. Args[i] = (char*)GVTOP(args[i]);
  439. GenericValue GV;
  440. GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4],
  441. Args[5], Args[6], Args[7], Args[8], Args[9]));
  442. ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4],
  443. Args[5], Args[6], Args[7], Args[8], Args[9]);
  444. return GV;
  445. }
  446. // int clock(void) - Profiling implementation
  447. GenericValue lle_i_clock(FunctionType *FT, const vector<GenericValue> &Args) {
  448. extern unsigned int clock(void);
  449. GenericValue GV;
  450. GV.IntVal = APInt(32, clock());
  451. return GV;
  452. }
  453. //===----------------------------------------------------------------------===//
  454. // String Functions...
  455. //===----------------------------------------------------------------------===//
  456. // int strcmp(const char *S1, const char *S2);
  457. GenericValue lle_X_strcmp(FunctionType *FT, const vector<GenericValue> &Args) {
  458. assert(Args.size() == 2);
  459. GenericValue Ret;
  460. Ret.IntVal = APInt(32, strcmp((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
  461. return Ret;
  462. }
  463. // char *strcat(char *Dest, const char *src);
  464. GenericValue lle_X_strcat(FunctionType *FT, const vector<GenericValue> &Args) {
  465. assert(Args.size() == 2);
  466. assert(isa<PointerType>(FT->getReturnType()) &&"strcat must return pointer");
  467. return PTOGV(strcat((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
  468. }
  469. // char *strcpy(char *Dest, const char *src);
  470. GenericValue lle_X_strcpy(FunctionType *FT, const vector<GenericValue> &Args) {
  471. assert(Args.size() == 2);
  472. assert(isa<PointerType>(FT->getReturnType()) &&"strcpy must return pointer");
  473. return PTOGV(strcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1])));
  474. }
  475. static GenericValue size_t_to_GV (size_t n) {
  476. GenericValue Ret;
  477. if (sizeof (size_t) == sizeof (uint64_t)) {
  478. Ret.IntVal = APInt(64, n);
  479. } else {
  480. assert (sizeof (size_t) == sizeof (unsigned int));
  481. Ret.IntVal = APInt(32, n);
  482. }
  483. return Ret;
  484. }
  485. static size_t GV_to_size_t (GenericValue GV) {
  486. size_t count;
  487. if (sizeof (size_t) == sizeof (uint64_t)) {
  488. count = (size_t)GV.IntVal.getZExtValue();
  489. } else {
  490. assert (sizeof (size_t) == sizeof (unsigned int));
  491. count = (size_t)GV.IntVal.getZExtValue();
  492. }
  493. return count;
  494. }
  495. // size_t strlen(const char *src);
  496. GenericValue lle_X_strlen(FunctionType *FT, const vector<GenericValue> &Args) {
  497. assert(Args.size() == 1);
  498. size_t strlenResult = strlen ((char *) GVTOP (Args[0]));
  499. return size_t_to_GV (strlenResult);
  500. }
  501. // char *strdup(const char *src);
  502. GenericValue lle_X_strdup(FunctionType *FT, const vector<GenericValue> &Args) {
  503. assert(Args.size() == 1);
  504. assert(isa<PointerType>(FT->getReturnType()) && "strdup must return pointer");
  505. return PTOGV(strdup((char*)GVTOP(Args[0])));
  506. }
  507. // char *__strdup(const char *src);
  508. GenericValue lle_X___strdup(FunctionType *FT, const vector<GenericValue> &Args) {
  509. assert(Args.size() == 1);
  510. assert(isa<PointerType>(FT->getReturnType()) &&"_strdup must return pointer");
  511. return PTOGV(strdup((char*)GVTOP(Args[0])));
  512. }
  513. // void *memset(void *S, int C, size_t N)
  514. GenericValue lle_X_memset(FunctionType *FT, const vector<GenericValue> &Args) {
  515. assert(Args.size() == 3);
  516. size_t count = GV_to_size_t (Args[2]);
  517. assert(isa<PointerType>(FT->getReturnType()) && "memset must return pointer");
  518. return PTOGV(memset(GVTOP(Args[0]), uint32_t(Args[1].IntVal.getZExtValue()),
  519. count));
  520. }
  521. // void *memcpy(void *Dest, void *src, size_t Size);
  522. GenericValue lle_X_memcpy(FunctionType *FT, const vector<GenericValue> &Args) {
  523. assert(Args.size() == 3);
  524. assert(isa<PointerType>(FT->getReturnType()) && "memcpy must return pointer");
  525. size_t count = GV_to_size_t (Args[2]);
  526. return PTOGV(memcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count));
  527. }
  528. // void *memcpy(void *Dest, void *src, size_t Size);
  529. GenericValue lle_X_memmove(FunctionType *FT, const vector<GenericValue> &Args) {
  530. assert(Args.size() == 3);
  531. assert(isa<PointerType>(FT->getReturnType()) && "memmove must return pointer");
  532. size_t count = GV_to_size_t (Args[2]);
  533. return PTOGV(memmove((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count));
  534. }
  535. //===----------------------------------------------------------------------===//
  536. // IO Functions...
  537. //===----------------------------------------------------------------------===//
  538. // getFILE - Turn a pointer in the host address space into a legit pointer in
  539. // the interpreter address space. This is an identity transformation.
  540. #define getFILE(ptr) ((FILE*)ptr)
  541. // FILE *fopen(const char *filename, const char *mode);
  542. GenericValue lle_X_fopen(FunctionType *FT, const vector<GenericValue> &Args) {
  543. assert(Args.size() == 2);
  544. assert(isa<PointerType>(FT->getReturnType()) && "fopen must return pointer");
  545. return PTOGV(fopen((const char *)GVTOP(Args[0]),
  546. (const char *)GVTOP(Args[1])));
  547. }
  548. // int fclose(FILE *F);
  549. GenericValue lle_X_fclose(FunctionType *FT, const vector<GenericValue> &Args) {
  550. assert(Args.size() == 1);
  551. GenericValue GV;
  552. GV.IntVal = APInt(32, fclose(getFILE(GVTOP(Args[0]))));
  553. return GV;
  554. }
  555. // int feof(FILE *stream);
  556. GenericValue lle_X_feof(FunctionType *FT, const vector<GenericValue> &Args) {
  557. assert(Args.size() == 1);
  558. GenericValue GV;
  559. GV.IntVal = APInt(32, feof(getFILE(GVTOP(Args[0]))));
  560. return GV;
  561. }
  562. // size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
  563. GenericValue lle_X_fread(FunctionType *FT, const vector<GenericValue> &Args) {
  564. assert(Args.size() == 4);
  565. size_t result;
  566. result = fread((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
  567. GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
  568. return size_t_to_GV (result);
  569. }
  570. // size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
  571. GenericValue lle_X_fwrite(FunctionType *FT, const vector<GenericValue> &Args) {
  572. assert(Args.size() == 4);
  573. size_t result;
  574. result = fwrite((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]),
  575. GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3])));
  576. return size_t_to_GV (result);
  577. }
  578. // char *fgets(char *s, int n, FILE *stream);
  579. GenericValue lle_X_fgets(FunctionType *FT, const vector<GenericValue> &Args) {
  580. assert(Args.size() == 3);
  581. return PTOGV(fgets((char*)GVTOP(Args[0]), Args[1].IntVal.getZExtValue(),
  582. getFILE(GVTOP(Args[2]))));
  583. }
  584. // FILE *freopen(const char *path, const char *mode, FILE *stream);
  585. GenericValue lle_X_freopen(FunctionType *FT, const vector<GenericValue> &Args) {
  586. assert(Args.size() == 3);
  587. assert(isa<PointerType>(FT->getReturnType()) &&"freopen must return pointer");
  588. return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]),
  589. getFILE(GVTOP(Args[2]))));
  590. }
  591. // int fflush(FILE *stream);
  592. GenericValue lle_X_fflush(FunctionType *FT, const vector<GenericValue> &Args) {
  593. assert(Args.size() == 1);
  594. GenericValue GV;
  595. GV.IntVal = APInt(32, fflush(getFILE(GVTOP(Args[0]))));
  596. return GV;
  597. }
  598. // int getc(FILE *stream);
  599. GenericValue lle_X_getc(FunctionType *FT, const vector<GenericValue> &Args) {
  600. assert(Args.size() == 1);
  601. GenericValue GV;
  602. GV.IntVal = APInt(32, getc(getFILE(GVTOP(Args[0]))));
  603. return GV;
  604. }
  605. // int _IO_getc(FILE *stream);
  606. GenericValue lle_X__IO_getc(FunctionType *F, const vector<GenericValue> &Args) {
  607. return lle_X_getc(F, Args);
  608. }
  609. // int fputc(int C, FILE *stream);
  610. GenericValue lle_X_fputc(FunctionType *FT, const vector<GenericValue> &Args) {
  611. assert(Args.size() == 2);
  612. GenericValue GV;
  613. GV.IntVal = APInt(32, fputc(Args[0].IntVal.getZExtValue(),
  614. getFILE(GVTOP(Args[1]))));
  615. return GV;
  616. }
  617. // int ungetc(int C, FILE *stream);
  618. GenericValue lle_X_ungetc(FunctionType *FT, const vector<GenericValue> &Args) {
  619. assert(Args.size() == 2);
  620. GenericValue GV;
  621. GV.IntVal = APInt(32, ungetc(Args[0].IntVal.getZExtValue(),
  622. getFILE(GVTOP(Args[1]))));
  623. return GV;
  624. }
  625. // int ferror (FILE *stream);
  626. GenericValue lle_X_ferror(FunctionType *FT, const vector<GenericValue> &Args) {
  627. assert(Args.size() == 1);
  628. GenericValue GV;
  629. GV.IntVal = APInt(32, ferror (getFILE(GVTOP(Args[0]))));
  630. return GV;
  631. }
  632. // int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output
  633. // useful.
  634. GenericValue lle_X_fprintf(FunctionType *FT, const vector<GenericValue> &Args) {
  635. assert(Args.size() >= 2);
  636. char Buffer[10000];
  637. vector<GenericValue> NewArgs;
  638. NewArgs.push_back(PTOGV(Buffer));
  639. NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end());
  640. GenericValue GV = lle_X_sprintf(FT, NewArgs);
  641. fputs(Buffer, getFILE(GVTOP(Args[0])));
  642. return GV;
  643. }
  644. // int __cxa_guard_acquire (__guard *g);
  645. GenericValue lle_X___cxa_guard_acquire(FunctionType *FT,
  646. const vector<GenericValue> &Args) {
  647. assert(Args.size() == 1);
  648. GenericValue GV;
  649. #ifdef __linux__
  650. GV.IntVal = APInt(32, __cxxabiv1::__cxa_guard_acquire (
  651. (__cxxabiv1::__guard*)GVTOP(Args[0])));
  652. #else
  653. assert(0 && "Can't call __cxa_guard_acquire on this platform");
  654. #endif
  655. return GV;
  656. }
  657. // void __cxa_guard_release (__guard *g);
  658. GenericValue lle_X___cxa_guard_release(FunctionType *FT,
  659. const vector<GenericValue> &Args) {
  660. assert(Args.size() == 1);
  661. #ifdef __linux__
  662. __cxxabiv1::__cxa_guard_release ((__cxxabiv1::__guard*)GVTOP(Args[0]));
  663. #else
  664. assert(0 && "Can't call __cxa_guard_release on this platform");
  665. #endif
  666. return GenericValue();
  667. }
  668. } // End extern "C"
  669. void Interpreter::initializeExternalFunctions() {
  670. FuncNames["lle_X_putchar"] = lle_X_putchar;
  671. FuncNames["lle_X__IO_putc"] = lle_X__IO_putc;
  672. FuncNames["lle_X_exit"] = lle_X_exit;
  673. FuncNames["lle_X_abort"] = lle_X_abort;
  674. FuncNames["lle_X_malloc"] = lle_X_malloc;
  675. FuncNames["lle_X_calloc"] = lle_X_calloc;
  676. FuncNames["lle_X_realloc"] = lle_X_realloc;
  677. FuncNames["lle_X_free"] = lle_X_free;
  678. FuncNames["lle_X_atoi"] = lle_X_atoi;
  679. FuncNames["lle_X_pow"] = lle_X_pow;
  680. FuncNames["lle_X_sin"] = lle_X_sin;
  681. FuncNames["lle_X_cos"] = lle_X_cos;
  682. FuncNames["lle_X_exp"] = lle_X_exp;
  683. FuncNames["lle_X_log"] = lle_X_log;
  684. FuncNames["lle_X_floor"] = lle_X_floor;
  685. FuncNames["lle_X_srand"] = lle_X_srand;
  686. FuncNames["lle_X_rand"] = lle_X_rand;
  687. #ifdef HAVE_RAND48
  688. FuncNames["lle_X_drand48"] = lle_X_drand48;
  689. FuncNames["lle_X_srand48"] = lle_X_srand48;
  690. FuncNames["lle_X_lrand48"] = lle_X_lrand48;
  691. #endif
  692. FuncNames["lle_X_sqrt"] = lle_X_sqrt;
  693. FuncNames["lle_X_puts"] = lle_X_puts;
  694. FuncNames["lle_X_printf"] = lle_X_printf;
  695. FuncNames["lle_X_sprintf"] = lle_X_sprintf;
  696. FuncNames["lle_X_sscanf"] = lle_X_sscanf;
  697. FuncNames["lle_X_scanf"] = lle_X_scanf;
  698. FuncNames["lle_i_clock"] = lle_i_clock;
  699. FuncNames["lle_X_strcmp"] = lle_X_strcmp;
  700. FuncNames["lle_X_strcat"] = lle_X_strcat;
  701. FuncNames["lle_X_strcpy"] = lle_X_strcpy;
  702. FuncNames["lle_X_strlen"] = lle_X_strlen;
  703. FuncNames["lle_X___strdup"] = lle_X___strdup;
  704. FuncNames["lle_X_memset"] = lle_X_memset;
  705. FuncNames["lle_X_memcpy"] = lle_X_memcpy;
  706. FuncNames["lle_X_memmove"] = lle_X_memmove;
  707. FuncNames["lle_X_fopen"] = lle_X_fopen;
  708. FuncNames["lle_X_fclose"] = lle_X_fclose;
  709. FuncNames["lle_X_feof"] = lle_X_feof;
  710. FuncNames["lle_X_fread"] = lle_X_fread;
  711. FuncNames["lle_X_fwrite"] = lle_X_fwrite;
  712. FuncNames["lle_X_fgets"] = lle_X_fgets;
  713. FuncNames["lle_X_fflush"] = lle_X_fflush;
  714. FuncNames["lle_X_fgetc"] = lle_X_getc;
  715. FuncNames["lle_X_getc"] = lle_X_getc;
  716. FuncNames["lle_X__IO_getc"] = lle_X__IO_getc;
  717. FuncNames["lle_X_fputc"] = lle_X_fputc;
  718. FuncNames["lle_X_ungetc"] = lle_X_ungetc;
  719. FuncNames["lle_X_fprintf"] = lle_X_fprintf;
  720. FuncNames["lle_X_freopen"] = lle_X_freopen;
  721. FuncNames["lle_X___cxa_guard_acquire"] = lle_X___cxa_guard_acquire;
  722. FuncNames["lle_X____cxa_guard_release"] = lle_X___cxa_guard_release;
  723. }