[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