LEVEL := ..
PARALLEL_DIRS := llvm-as llvm-dis opt gccas llc llvm-link lli gccld llvm-stub \
analyze extract bugpoint llvm-nm llvm-prof llvm-db \
- llvm-ar llvm-ranlib llvm-bcanalyzer llee llvmc llvm-ld
+ llvm-ar llvm-ranlib llvm-bcanalyzer llvmc llvm-ld
EXTRA_DIST := Makefile.JIT
+++ /dev/null
-/*===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===*\
- *
- * The LLVM Compiler Infrastructure
- *
- * This file was developed by the LLVM research group and is distributed under
- * the University of Illinois Open Source License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===
- *
- * 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 "llvm/Config/unistd.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- * These are the expected headers for all valid LLVM bytecode files.
- * The first four characters must be one of these.
- */
-static const char llvmHeaderUncompressed[] = "llvm";
-static const char llvmHeaderCompressed[] = "llvc";
-
-/*
- * 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" */
- size_t headerSize = strlen(llvmHeaderCompressed);
- char header[headerSize];
- char* realFilename = 0;
- /*
- * 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] != '/')
- realFilename = FindExecutable(filename);
- else
- realFilename = (char*) filename;
- if (!realFilename) {
- fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
- return -1;
- }
- errno = 0;
- int file = open(realFilename, O_RDONLY);
- /* Check validity of `file' */
- if (errno) return EIO;
- /* Read the header from the file */
- ssize_t bytesRead = read(file, header, headerSize);
- close(file);
- if (bytesRead != (ssize_t)headerSize) return EIO;
- if (!memcmp(llvmHeaderCompressed, header, headerSize) ||
- !memcmp(llvmHeaderUncompressed, 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;
- LLIargs[1] = realFilename;
- for (idx = 1; idx != argvSize; ++idx)
- LLIargs[idx+1] = argv[idx];
- LLIargs[argvSize + 1] = '\0';
- return executeProgram(LLIpath, LLIargs, envp);
- }
- return executeProgram(filename, argv, envp);
-}
+++ /dev/null
-##===- tools/llee/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file was developed by the LLVM research group and is distributed under
-# the University of Illinois Open Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = LLVMexecve
-SHARED_LIBRARY = 1
-DONT_BUILD_RELINKED = 1
-include $(LEVEL)/Makefile.common
-
-all:: llee
-
-llee: $(LLVMToolDir)/llee
-
-$(LLVMToolDir)/llee: Makefile
- $(Echo) Constructing llee shell script
- $(Verb) echo exec env LD_PRELOAD=$(LibDir)/libLLVMexecve$(SHLIBEXT) $$\* > $@
- $(Verb) chmod u+x $@
-
-clean::
- $(Verb) rm -f $(LLVMToolDir)/llee
+++ /dev/null
-/*===- OSInterface.h - Interface to query OS for functionality ---*- C -*--===*\
- *
- * The LLVM Compiler Infrastructure
- *
- * This file was developed by the LLVM research group and is distributed under
- * the University of Illinois Open Source License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===
- *
- *
- * This file defines the prototype interface that we will expect operating
- * systems to implement if they wish to support offline cachine.
- *
-\*===----------------------------------------------------------------------===*/
-
-#ifndef OS_INTERFACE_H
-#define OS_INTERFACE_H
-
-#include "llvm/Config/sys/types.h"
-
-struct stat;
-
-/*
- * llvmStat - equivalent to stat(3), except the key may not necessarily
- * correspond to a file by that name, implementation is up to the OS.
- * Values returned in buf are similar as they are in Unix.
- */
-void llvmStat(const char *key, struct stat *buf);
-
-/*
- * llvmWriteFile - implements a 'save' of a file in the OS. 'key' may not
- * necessarily map to a file of the same name.
- * Returns:
- * 0 - success
- * non-zero - error
- */
-int llvmWriteFile(const char *key, const void *data, size_t len);
-
-/*
- * llvmLoadFile - tells the OS to load data corresponding to a particular key
- * somewhere into memory.
- * Returns:
- * 0 - failure
- * non-zero - address of loaded file
- *
- * Value of size is the length of data loaded into memory.
- */
-void* llvmReadFile(const char *key, size_t *size);
-
-/*
- * llvmExecve - execute a file from cache. This is a temporary proof-of-concept
- * because we do not relocate what we can read from disk.
- */
-int llvmExecve(const char *filename, char *const argv[], char *const envp[]);
-
-#endif
+++ /dev/null
- 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() function, 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 <native_program>'; a good choice is a shell. Anything
-started within that program will be affected by the execve() replacement.
+++ /dev/null
-/*===- StorageProxy.c - OS implementation of the caching interface --------===*\
- * *
- * This file implements the interface that we will expect operating *
- * systems to implement if they wish to support offline cachine. *
- * *
-\*===----------------------------------------------------------------------===*/
-
-#include "OSInterface.h"
-#include "SysUtils.h"
-#include "llvm/Config/fcntl.h"
-#include "llvm/Config/unistd.h"
-#include "llvm/Config/sys/types.h"
-#include "llvm/Config/sys/stat.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-static const char CacheRoot[] = "/tmp/LLVMCache";
-static const char ExeSuffix[] = ".exe";
-
-char* computeCachedFile(const char *key) {
- /* CacheRoot + "/" + std::string(key) + ExeSuffix; */
- char *cacheFile = (char*) malloc(strlen(CacheRoot) + 1 + strlen(key) +
- strlen(ExeSuffix) + 1);
- char *pCacheFile = cacheFile;
- if (!cacheFile) return 0;
- memcpy(cacheFile, CacheRoot, strlen(CacheRoot));
- pCacheFile += strlen(CacheRoot);
- *pCacheFile++ = '/';
- memcpy(pCacheFile, key, strlen(key));
- pCacheFile += strlen(key);
- memcpy(pCacheFile, ExeSuffix, strlen(ExeSuffix));
- pCacheFile += strlen(ExeSuffix);
- *pCacheFile = 0; // Null-terminate
- return cacheFile;
-}
-
-/*
- * llvmStat - equivalent to stat(3), except the key may not necessarily
- * correspond to a file by that name, implementation is up to the OS.
- * Values returned in buf are similar as they are in Unix.
- */
-void llvmStat(const char *key, struct stat *buf) {
- char* cacheFile = computeCachedFile(key);
- fprintf(stderr, "llvmStat(%s)\n", cacheFile);
- stat(cacheFile, buf);
- free(cacheFile);
-}
-
-/*
- * llvmWriteFile - implements a 'save' of a file in the OS. 'key' may not
- * necessarily map to a file of the same name.
- * Returns:
- * 0 - success
- * non-zero - error
- */
-int llvmWriteFile(const char *key, const void *data, size_t len)
-{
- char* cacheFile = computeCachedFile(key);
- int fd = open(cacheFile, O_CREAT|O_WRONLY|O_TRUNC);
- free(cacheFile);
- if (fd < 0) return -1; // encountered an error
- if (write(fd, data, len)) return -1;
- if (fsync(fd)) return -1;
- if (close(fd)) return -1;
- return 0;
-}
-
-/*
- * llvmReadFile - tells the OS to load data corresponding to a particular key
- * somewhere into memory.
- * Returns:
- * 0 - failure
- * non-zero - address of loaded file
- *
- * Value of size is the length of data loaded into memory.
- */
-void* llvmReadFile(const char *key, size_t *size) {
- char* cacheFile = computeCachedFile(key);
- if (!cacheFile) return 0;
- struct stat buf;
- stat(cacheFile, &buf);
- int fd = open(cacheFile, O_RDONLY);
- if (fd < 0) return 0; // encountered an error
- void* data = malloc(buf.st_size);
- if (read(fd, data, buf.st_size)) {
- free(data);
- return 0;
- }
- *size = buf.st_size;
- return data;
-}
-
-/*
- * llvmExecve - execute a file from cache. This is a temporary proof-of-concept
- * because we do not relocate what we can read from disk.
- */
-int llvmExecve(const char *filename, char *const argv[], char *const envp[]) {
- char* cacheFile = computeCachedFile(filename);
- return executeProgram(cacheFile, argv, envp);
-}
+++ /dev/null
-/*===- SystemUtils.h - Utilities to do low-level system stuff -------------===*\
- *
- * The LLVM Compiler Infrastructure
- *
- * This file was developed by the LLVM research group and is distributed under
- * the University of Illinois Open Source License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===
- *
- * This file contains functions used to do a variety of low-level, often
- * system-specific, tasks.
- *
-\*===----------------------------------------------------------------------===*/
-
-#include "SysUtils.h"
-#include "llvm/Config/dlfcn.h"
-#include "llvm/Config/fcntl.h"
-#include "llvm/Config/unistd.h"
-#include "llvm/Config/sys/stat.h"
-#include "llvm/Config/sys/types.h"
-#include "llvm/Config/sys/wait.h"
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * isExecutable - This function returns true if given struct stat describes the
- * file as being executable.
- */
-unsigned isExecutable(const struct stat *buf) {
- if (!(buf->st_mode & S_IFREG))
- return 0; // 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;
-}
-
-/*
- * 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 0; // Must not be executable!
-
- return isExecutable(&buf);
-}
-
-
-/*
- * 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 0;
-
- /* 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 ? (unsigned)(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 to search, return failure. */
- return NULL;
-}
-
-/*
- * 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.
- */
- const 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);
-}
+++ /dev/null
-/*===- SysUtils.h - Utilities to do low-level system stuff ----------------===*\
- *
- * The LLVM Compiler Infrastructure
- *
- * This file was developed by the LLVM research group and is distributed under
- * the University of Illinois Open Source License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===
- *
- *
- * This file contains functions used to do a variety of low-level, often
- * system-specific, tasks.
- *
-\*===----------------------------------------------------------------------===*/
-
-#ifndef SYSUTILS_H
-#define SYSUTILS_H
-
-struct stat;
-
-/*
- * isExecutable - This function returns true if given struct stat describes the
- * file as being executable.
- */
-unsigned isExecutable(const struct stat *buf);
-
-/*
- * isExecutableFile - This function returns true if the filename specified
- * exists and is executable.
- */
-unsigned isExecutableFile(const char *ExeFileName);
-
-/*
- * FindExecutable - Find a named executable in the path.
- */
-char *FindExecutable(const char *ExeName);
-
-/*
- * 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[]);
-
-#endif