[llvm-commits] CVS: llvm/tools/llee/ExecveHandler.c Makefile SysUtils.c SysUtils.h llee
Misha Brukman
brukman at cs.uiuc.edu
Mon Aug 11 17:30:01 PDT 2003
Changes in directory llvm/tools/llee:
ExecveHandler.c added (r1.1)
Makefile added (r1.1)
SysUtils.c added (r1.1)
SysUtils.h added (r1.1)
llee added (r1.1)
---
Log message:
Initial checkin of the LLEE, the (LL)VM (E)xecution (E)nvironment.
---
Diffs of the changes:
Index: llvm/tools/llee/ExecveHandler.c
diff -c /dev/null llvm/tools/llee/ExecveHandler.c:1.1
*** /dev/null Mon Aug 11 17:29:46 2003
--- llvm/tools/llee/ExecveHandler.c Mon Aug 11 17:29:36 2003
***************
*** 0 ****
--- 1,92 ----
+ //===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===//
+ //
+ // This file implements a replacement execve() to spawn off LLVM programs to run
+ // transparently, without needing to be (JIT-)compiled manually by the user.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "SysUtils.h"
+ #include <Config/dlfcn.h>
+ #include <Config/errno.h>
+ #include <Config/stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+
+ /*
+ * This is the expected header for all valid LLVM bytecode files.
+ * The first four characters must be exactly this.
+ */
+ static const char llvmHeader[] = "llvm";
+
+ /*
+ * The type of the execve() function is long and boring, but required.
+ */
+ typedef int(*execveTy)(const char*, char *const[], char *const[]);
+
+ /*
+ * This method finds the real `execve' call in the C library and executes the
+ * given program.
+ */
+ int executeProgram(const char *filename, char *const argv[], char *const envp[])
+ {
+ /*
+ * Find a pointer to the *real* execve() function starting the search in the
+ * next library and forward, to avoid finding the one defined in this file.
+ */
+ char *error;
+ execveTy execvePtr = (execveTy) dlsym(RTLD_NEXT, "execve");
+ if ((error = dlerror()) != NULL) {
+ fprintf(stderr, "%s\n", error);
+ return -1;
+ }
+
+ /* Really execute the program */
+ return execvePtr(filename, argv, envp);
+ }
+
+ /*
+ * This replacement execve() function first checks the file to be executed
+ * to see if it is a valid LLVM bytecode file, and then either invokes our
+ * execution environment or passes it on to the system execve() call.
+ */
+ 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");
+ /* Check validity of `file' */
+ if (errno) { return errno; }
+ /* 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)) {
+ /*
+ * This is a bytecode file, so execute the JIT with the program and
+ * parameters.
+ */
+ unsigned argvSize, idx;
+ for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
+ ++argvSize;
+ char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
+ 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[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;
+ }
Index: llvm/tools/llee/Makefile
diff -c /dev/null llvm/tools/llee/Makefile:1.1
*** /dev/null Mon Aug 11 17:29:46 2003
--- llvm/tools/llee/Makefile Mon Aug 11 17:29:36 2003
***************
*** 0 ****
--- 1,21 ----
+ LEVEL = ../..
+ include $(LEVEL)/Makefile.config
+
+ SRCS = ExecveHandler.c SysUtils.c
+
+ OBJS = $(SRCS:%.c=%.o)
+ SO = execve.so
+
+ all: $(SO) execve_test
+
+ %.o: %.c
+ gcc -g -I../../include -D_GNU_SOURCE $< -c -o $@
+
+ $(SO): $(OBJS)
+ gcc -g -shared -ldl -rdynamic $(OBJS) -o $@
+
+ execve_test: execve_test.c
+ gcc -g $< -o $@
+
+ clean:
+ rm -f $(OBJS) $(SO)
Index: llvm/tools/llee/SysUtils.c
diff -c /dev/null llvm/tools/llee/SysUtils.c:1.1
*** /dev/null Mon Aug 11 17:29:46 2003
--- llvm/tools/llee/SysUtils.c Mon Aug 11 17:29:36 2003
***************
*** 0 ****
--- 1,81 ----
+ //===- SystemUtils.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.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "SysUtils.h"
+ #include "Config/sys/types.h"
+ #include "Config/sys/stat.h"
+ #include "Config/fcntl.h"
+ #include "Config/sys/wait.h"
+ #include "Config/unistd.h"
+ #include "Config/errno.h"
+ #include <stdlib.h>
+ #include <string.h>
+
+ /// isExecutableFile - This function returns true if the filename specified
+ /// exists and is executable.
+ ///
+ bool isExecutableFile(const char *ExeFileName) {
+ struct stat Buf;
+ if (stat(ExeFileName, &Buf))
+ return false; // Must not be executable!
+
+ if (!(Buf.st_mode & S_IFREG))
+ return false; // Not a regular file?
+
+ if (Buf.st_uid == getuid()) // Owner of file?
+ return Buf.st_mode & S_IXUSR;
+ else if (Buf.st_gid == getgid()) // In group of file?
+ return Buf.st_mode & S_IXGRP;
+ else // Unrelated to file?
+ 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.
+ ///
+ 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...
+ unsigned PathLen = strlen(PathStr);
+ while (PathLen) {
+ /* Find the next colon */
+ const char *Colon = strchr(PathStr, ':');
+
+ /* Check to see if this first directory contains the executable... */
+ unsigned DirLen = Colon ? (Colon-PathStr) : strlen(PathStr);
+ char *FilePath = alloca(sizeof(char) * (DirLen+1+strlen(ExeName)+1));
+ unsigned i, e;
+ for (i = 0; i != DirLen; ++i)
+ FilePath[i] = PathStr[i];
+ FilePath[i] = '/';
+ for (i = 0, e = strlen(ExeName); i != e; ++i)
+ FilePath[DirLen + 1 + i] = ExeName[i];
+ FilePath[DirLen + 1 + i] = '\0';
+ if (isExecutableFile(FilePath))
+ return strdup(FilePath); /* Found the executable! */
+
+ /* If Colon is NULL, there are no more colon separators and no more dirs */
+ if (!Colon) break;
+
+ /* Nope, it wasn't in this directory, check the next range! */
+ PathLen -= DirLen;
+ PathStr = Colon;
+ while (*PathStr == ':') { /* Advance past colons */
+ PathStr++;
+ PathLen--;
+ }
+
+ /* Advance past the colon */
+ ++Colon;
+ }
+
+ // If we fell out, we ran out of directories in PATH to search, return failure
+ return NULL;
+ }
Index: llvm/tools/llee/SysUtils.h
diff -c /dev/null llvm/tools/llee/SysUtils.h:1.1
*** /dev/null Mon Aug 11 17:29:46 2003
--- llvm/tools/llee/SysUtils.h Mon Aug 11 17:29:36 2003
***************
*** 0 ****
--- 1,28 ----
+ /*===- 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. *
+ * *
+ \*===----------------------------------------------------------------------===*/
+
+ #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);
+
+ /*
+ * 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.
+ */
+ char *FindExecutable(const char *ExeName);
+
+ #endif
Index: llvm/tools/llee/llee
diff -c /dev/null llvm/tools/llee/llee:1.1
*** /dev/null Mon Aug 11 17:29:46 2003
--- llvm/tools/llee/llee Mon Aug 11 17:29:36 2003
***************
*** 0 ****
--- 1 ----
+ exec env LD_PRELOAD=`pwd`/execve.so $*
More information about the llvm-commits
mailing list