diff --git a/tools/llee/ExecveHandler.c b/tools/llee/ExecveHandler.c index 947b2fcdbd0..91f909225b1 100644 --- a/tools/llee/ExecveHandler.c +++ b/tools/llee/ExecveHandler.c @@ -6,9 +6,11 @@ //===----------------------------------------------------------------------===// #include "SysUtils.h" -#include -#include -#include +#include "Config/dlfcn.h" +#include "Config/errno.h" +#include "Config/stdlib.h" +#include "Config/unistd.h" +#include #include #include @@ -52,18 +54,17 @@ int executeProgram(const char *filename, char *const argv[], char *const envp[]) int execve(const char *filename, char *const argv[], char *const envp[]) { /* Open the file, test to see if first four characters are "llvm" */ - char header[4]; - FILE *file = fopen(filename, "r"); + size_t headerSize = strlen(llvmHeader); + char header[headerSize]; + errno = 0; + int file = open(filename, O_RDONLY); /* Check validity of `file' */ - if (errno) { return errno; } + if (errno) return EIO; /* Read the header from the file */ - size_t headerSize = strlen(llvmHeader) - 1; // ignore the NULL terminator - size_t bytesRead = fread(header, sizeof(char), headerSize, file); - fclose(file); - if (bytesRead != headerSize) { - return EIO; - } - if (!strncmp(llvmHeader, header, headerSize)) { + ssize_t bytesRead = read(file, header, headerSize); + close(file); + if (bytesRead != headerSize) return EIO; + if (!memcmp(llvmHeader, header, headerSize)) { /* * This is a bytecode file, so execute the JIT with the program and * parameters. @@ -72,21 +73,30 @@ int execve(const char *filename, char *const argv[], char *const envp[]) for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx) ++argvSize; char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2)); + char *BCpath; + /* + * If the program is specified with a relative or absolute path, + * then just use the path and filename as is, otherwise search for it. + */ + if (filename[0] != '.' && filename[0] != '/') + BCpath = FindExecutable(filename); + else + BCpath = (char*) filename; + if (!BCpath) { + fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename); + return -1; + } char *LLIpath = FindExecutable("lli"); if (!LLIpath) { fprintf(stderr, "Cannot find path to `lli', exiting.\n"); return -1; } LLIargs[0] = LLIpath; - for (idx = 0; idx != argvSize; ++idx) + LLIargs[1] = BCpath; + for (idx = 1; idx != argvSize; ++idx) LLIargs[idx+1] = argv[idx]; LLIargs[argvSize + 1] = '\0'; - /* - for (idx = 0; idx != argvSize+2; ++idx) - printf("LLI args[%d] = \"%s\"\n", idx, LLIargs[idx]); - */ return executeProgram(LLIpath, LLIargs, envp); } - executeProgram(filename, argv, envp); - return 0; + return executeProgram(filename, argv, envp); } diff --git a/tools/llee/README.txt b/tools/llee/README.txt new file mode 100644 index 00000000000..ac9b01bbfb1 --- /dev/null +++ b/tools/llee/README.txt @@ -0,0 +1,12 @@ + LLEE: (LL)VM (E)xecution (E)nvironment + +This tool presents a virtual execution environment for LLVM programs. By +preloading a shared object which defines a custom execve() functions, we can +execute bytecode files with the JIT directly, without the user ever thinking +about it. + +Thus, a user can freely run any program, native or LLVM bytecode, transparently, +and without even being aware of it. + +To use LLEE, run `./llee ', a good choice is a shell. Anything +started within that program will be affected by the execve() replacement. diff --git a/tools/llee/SysUtils.c b/tools/llee/SysUtils.c index 1c3aa85e5c6..90d6bb12901 100644 --- a/tools/llee/SysUtils.c +++ b/tools/llee/SysUtils.c @@ -15,16 +15,17 @@ #include #include -/// isExecutableFile - This function returns true if the filename specified -/// exists and is executable. -/// -bool isExecutableFile(const char *ExeFileName) { +/* + * isExecutableFile - This function returns true if the filename specified + * exists and is executable. + */ +unsigned isExecutableFile(const char *ExeFileName) { struct stat Buf; if (stat(ExeFileName, &Buf)) - return false; // Must not be executable! + return 0; // Must not be executable! if (!(Buf.st_mode & S_IFREG)) - return false; // Not a regular file? + return 0; // Not a regular file? if (Buf.st_uid == getuid()) // Owner of file? return Buf.st_mode & S_IXUSR; @@ -34,15 +35,16 @@ bool isExecutableFile(const char *ExeFileName) { return Buf.st_mode & S_IXOTH; } -/// FindExecutable - Find a named executable in the directories listed in $PATH. -/// If the executable cannot be found, returns NULL. -/// +/* + * FindExecutable - Find a named executable in the directories listed in $PATH. + * If the executable cannot be found, returns NULL. + */ char *FindExecutable(const char *ExeName) { /* Try to find the executable in the path */ const char *PathStr = getenv("PATH"); if (PathStr == 0) return ""; - // Now we have a colon separated list of directories to search... try them... + /* Now we have a colon separated list of directories to search, try them. */ unsigned PathLen = strlen(PathStr); while (PathLen) { /* Find the next colon */ @@ -76,6 +78,6 @@ char *FindExecutable(const char *ExeName) { ++Colon; } - // If we fell out, we ran out of directories in PATH to search, return failure + /* If we fell out, we ran out of directories to search, return failure. */ return NULL; } diff --git a/tools/llee/SysUtils.h b/tools/llee/SysUtils.h index 89b647970e3..84e7f9d6b2e 100644 --- a/tools/llee/SysUtils.h +++ b/tools/llee/SysUtils.h @@ -1,4 +1,4 @@ -/*===- sysutils.h - Utilities to do low-level system stuff -------*- C -*--===*\ +/*===- SysUtils.h - Utilities to do low-level system stuff -------*- C -*--===*\ * * * This file contains functions used to do a variety of low-level, often * * system-specific, tasks. * @@ -8,20 +8,14 @@ #ifndef SYSUTILS_H #define SYSUTILS_H -typedef unsigned bool; -enum { false = 0, true = 1 }; - /* * isExecutableFile - This function returns true if the filename specified * exists and is executable. */ -bool isExecutableFile(const char *ExeFileName); +unsigned isExecutableFile(const char *ExeFileName); /* - * FindExecutable - Find a named executable, giving the argv[0] of program - * being executed. This allows us to find another LLVM tool if it is built into - * the same directory, but that directory is neither the current directory, nor - * in the PATH. If the executable cannot be found, return an empty string. + * FindExecutable - Find a named executable in the path. */ char *FindExecutable(const char *ExeName);