mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-28 06:58:19 +00:00
A lot of changes were suggested by Chris.
ExecveHandler.c: * Use "" instead of <> for LLVM include files * Use raw I/O, we don't need buffering * Set errno = 0 before using open() * strlen() doesn't count NULL terminator in its size * Use memcmp() instead of strcmp() * Return result of the real execve(), not 0 * Search for path to bytecode file if not absolute/relative path SysUtils.c: * Convert all comments to C-style * Stop using `bool', use `unsigned' instead SysUtils.h: * Stop using `bool', use `unsigned' instead * Updated comment to FindExecutable() README.txt: * Describe the goal of LLEE and an application git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7911 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a1ee42ac8e
commit
593ece0050
@ -6,9 +6,11 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "SysUtils.h"
|
#include "SysUtils.h"
|
||||||
#include <Config/dlfcn.h>
|
#include "Config/dlfcn.h"
|
||||||
#include <Config/errno.h>
|
#include "Config/errno.h"
|
||||||
#include <Config/stdlib.h>
|
#include "Config/stdlib.h"
|
||||||
|
#include "Config/unistd.h"
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -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[])
|
int execve(const char *filename, char *const argv[], char *const envp[])
|
||||||
{
|
{
|
||||||
/* Open the file, test to see if first four characters are "llvm" */
|
/* Open the file, test to see if first four characters are "llvm" */
|
||||||
char header[4];
|
size_t headerSize = strlen(llvmHeader);
|
||||||
FILE *file = fopen(filename, "r");
|
char header[headerSize];
|
||||||
|
errno = 0;
|
||||||
|
int file = open(filename, O_RDONLY);
|
||||||
/* Check validity of `file' */
|
/* Check validity of `file' */
|
||||||
if (errno) { return errno; }
|
if (errno) return EIO;
|
||||||
/* Read the header from the file */
|
/* Read the header from the file */
|
||||||
size_t headerSize = strlen(llvmHeader) - 1; // ignore the NULL terminator
|
ssize_t bytesRead = read(file, header, headerSize);
|
||||||
size_t bytesRead = fread(header, sizeof(char), headerSize, file);
|
close(file);
|
||||||
fclose(file);
|
if (bytesRead != headerSize) return EIO;
|
||||||
if (bytesRead != headerSize) {
|
if (!memcmp(llvmHeader, header, headerSize)) {
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
if (!strncmp(llvmHeader, header, headerSize)) {
|
|
||||||
/*
|
/*
|
||||||
* This is a bytecode file, so execute the JIT with the program and
|
* This is a bytecode file, so execute the JIT with the program and
|
||||||
* parameters.
|
* 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)
|
for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
|
||||||
++argvSize;
|
++argvSize;
|
||||||
char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
|
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");
|
char *LLIpath = FindExecutable("lli");
|
||||||
if (!LLIpath) {
|
if (!LLIpath) {
|
||||||
fprintf(stderr, "Cannot find path to `lli', exiting.\n");
|
fprintf(stderr, "Cannot find path to `lli', exiting.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LLIargs[0] = LLIpath;
|
LLIargs[0] = LLIpath;
|
||||||
for (idx = 0; idx != argvSize; ++idx)
|
LLIargs[1] = BCpath;
|
||||||
|
for (idx = 1; idx != argvSize; ++idx)
|
||||||
LLIargs[idx+1] = argv[idx];
|
LLIargs[idx+1] = argv[idx];
|
||||||
LLIargs[argvSize + 1] = '\0';
|
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);
|
return executeProgram(LLIpath, LLIargs, envp);
|
||||||
}
|
}
|
||||||
executeProgram(filename, argv, envp);
|
return executeProgram(filename, argv, envp);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
12
tools/llee/README.txt
Normal file
12
tools/llee/README.txt
Normal file
@ -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 <native_program>', a good choice is a shell. Anything
|
||||||
|
started within that program will be affected by the execve() replacement.
|
@ -15,16 +15,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/// isExecutableFile - This function returns true if the filename specified
|
/*
|
||||||
/// exists and is executable.
|
* isExecutableFile - This function returns true if the filename specified
|
||||||
///
|
* exists and is executable.
|
||||||
bool isExecutableFile(const char *ExeFileName) {
|
*/
|
||||||
|
unsigned isExecutableFile(const char *ExeFileName) {
|
||||||
struct stat Buf;
|
struct stat Buf;
|
||||||
if (stat(ExeFileName, &Buf))
|
if (stat(ExeFileName, &Buf))
|
||||||
return false; // Must not be executable!
|
return 0; // Must not be executable!
|
||||||
|
|
||||||
if (!(Buf.st_mode & S_IFREG))
|
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?
|
if (Buf.st_uid == getuid()) // Owner of file?
|
||||||
return Buf.st_mode & S_IXUSR;
|
return Buf.st_mode & S_IXUSR;
|
||||||
@ -34,15 +35,16 @@ bool isExecutableFile(const char *ExeFileName) {
|
|||||||
return Buf.st_mode & S_IXOTH;
|
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) {
|
char *FindExecutable(const char *ExeName) {
|
||||||
/* Try to find the executable in the path */
|
/* Try to find the executable in the path */
|
||||||
const char *PathStr = getenv("PATH");
|
const char *PathStr = getenv("PATH");
|
||||||
if (PathStr == 0) return "";
|
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);
|
unsigned PathLen = strlen(PathStr);
|
||||||
while (PathLen) {
|
while (PathLen) {
|
||||||
/* Find the next colon */
|
/* Find the next colon */
|
||||||
@ -76,6 +78,6 @@ char *FindExecutable(const char *ExeName) {
|
|||||||
++Colon;
|
++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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -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 *
|
* This file contains functions used to do a variety of low-level, often *
|
||||||
* system-specific, tasks. *
|
* system-specific, tasks. *
|
||||||
@ -8,20 +8,14 @@
|
|||||||
#ifndef SYSUTILS_H
|
#ifndef SYSUTILS_H
|
||||||
#define SYSUTILS_H
|
#define SYSUTILS_H
|
||||||
|
|
||||||
typedef unsigned bool;
|
|
||||||
enum { false = 0, true = 1 };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* isExecutableFile - This function returns true if the filename specified
|
* isExecutableFile - This function returns true if the filename specified
|
||||||
* exists and is executable.
|
* 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
|
* FindExecutable - Find a named executable in the path.
|
||||||
* 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);
|
char *FindExecutable(const char *ExeName);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user