For PR351:

llee was a nice hack, but it wasn't portable so its gone, with Misha's
approval.  Operating systems have facilities available for making bytecode
directly executable without this utility.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18916 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2004-12-13 23:15:32 +00:00
parent 395fd5949b
commit 90484fb9a2
8 changed files with 1 additions and 451 deletions

View File

@ -10,7 +10,7 @@
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

View File

@ -1,84 +0,0 @@
/*===-- 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);
}

View File

@ -1,25 +0,0 @@
##===- 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

View File

@ -1,56 +0,0 @@
/*===- 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

View File

@ -1,12 +0,0 @@
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.

View File

@ -1,101 +0,0 @@
/*===- 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);
}

View File

@ -1,127 +0,0 @@
/*===- 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);
}

View File

@ -1,45 +0,0 @@
/*===- 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