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 //===----------------------------------------------------------------------===//
9 #include "Config/errno.h"
10 #include "Config/stdlib.h"
11 #include "Config/unistd.h"
17 * This is the expected header for all valid LLVM bytecode files.
18 * The first four characters must be exactly this.
20 static const char llvmHeader[] = "llvm";
23 * This replacement execve() function first checks the file to be executed
24 * to see if it is a valid LLVM bytecode file, and then either invokes our
25 * execution environment or passes it on to the system execve() call.
27 int execve(const char *filename, char *const argv[], char *const envp[])
29 /* Open the file, test to see if first four characters are "llvm" */
30 size_t headerSize = strlen(llvmHeader);
31 char header[headerSize];
32 char* realFilename = 0;
34 * If the program is specified with a relative or absolute path,
35 * then just use the path and filename as is, otherwise search for it.
37 if (filename[0] != '.' && filename[0] != '/')
38 realFilename = FindExecutable(filename);
40 realFilename = (char*) filename;
42 fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
46 int file = open(realFilename, O_RDONLY);
47 /* Check validity of `file' */
48 if (errno) return EIO;
49 /* Read the header from the file */
50 ssize_t bytesRead = read(file, header, headerSize);
52 if (bytesRead != (ssize_t)headerSize) return EIO;
53 if (!memcmp(llvmHeader, header, headerSize)) {
55 * This is a bytecode file, so execute the JIT with the program and
58 unsigned argvSize, idx;
59 for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
61 char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
62 char *LLIpath = FindExecutable("lli");
64 fprintf(stderr, "Cannot find path to `lli', exiting.\n");
68 LLIargs[1] = realFilename;
69 for (idx = 1; idx != argvSize; ++idx)
70 LLIargs[idx+1] = argv[idx];
71 LLIargs[argvSize + 1] = '\0';
72 return executeProgram(LLIpath, LLIargs, envp);
74 return executeProgram(filename, argv, envp);