1 //===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===//
3 // This file implements a replacement execve() to spawn off LLVM programs to run
4 // transparently, without needing to be (JIT-)compiled manually by the user.
6 //===----------------------------------------------------------------------===//
8 #include "OSInterface.h"
10 #include "Config/errno.h"
11 #include "Config/stdlib.h"
12 #include "Config/unistd.h"
18 * This is the expected header for all valid LLVM bytecode files.
19 * The first four characters must be exactly this.
21 static const char llvmHeader[] = "llvm";
24 * This replacement execve() function first checks the file to be executed
25 * to see if it is a valid LLVM bytecode file, and then either invokes our
26 * execution environment or passes it on to the system execve() call.
28 int execve(const char *filename, char *const argv[], char *const envp[])
30 /* Open the file, test to see if first four characters are "llvm" */
31 size_t headerSize = strlen(llvmHeader);
32 char header[headerSize];
33 char* realFilename = 0;
35 * If the program is specified with a relative or absolute path,
36 * then just use the path and filename as is, otherwise search for it.
38 if (filename[0] != '.' && filename[0] != '/')
39 realFilename = FindExecutable(filename);
41 realFilename = (char*) filename;
43 fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
47 int file = open(realFilename, O_RDONLY);
48 /* Check validity of `file' */
49 if (errno) return EIO;
50 /* Read the header from the file */
51 ssize_t bytesRead = read(file, header, headerSize);
53 if (bytesRead != (ssize_t)headerSize) return EIO;
54 if (!memcmp(llvmHeader, header, headerSize)) {
56 * Check if we have a cached translation on disk
59 llvmStat(realFilename, &buf);
60 if (isExecutable(&buf)) {
62 void *fileAddr = llvmReadFile(realFilename, &size);
63 fprintf(stderr, "Found in cache: '%s'\n", realFilename);
67 llvmExecve(realFilename, argv, envp);
70 * Not in cache: save translation
72 //llvmSaveFile(realFilename, addr, len);
73 //fprintf(stderr, "Cached: '%s'\n", realFilename);
77 * This is a bytecode file, so execute the JIT with the program and
80 unsigned argvSize, idx;
81 for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
83 char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
84 char *LLIpath = FindExecutable("lli");
86 fprintf(stderr, "Cannot find path to `lli', exiting.\n");
90 LLIargs[1] = realFilename;
91 for (idx = 1; idx != argvSize; ++idx)
92 LLIargs[idx+1] = argv[idx];
93 LLIargs[argvSize + 1] = '\0';
94 return executeProgram(LLIpath, LLIargs, envp);
96 return executeProgram(filename, argv, envp);