blob: 91f909225b1430275445015f45cb415d9984ee07 [file] [log] [blame]
Misha Brukman0abaaf42003-08-11 22:29:36 +00001//===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===//
2//
3// This file implements a replacement execve() to spawn off LLVM programs to run
4// transparently, without needing to be (JIT-)compiled manually by the user.
5//
6//===----------------------------------------------------------------------===//
7
8#include "SysUtils.h"
Misha Brukman593ece02003-08-15 23:31:16 +00009#include "Config/dlfcn.h"
10#include "Config/errno.h"
11#include "Config/stdlib.h"
12#include "Config/unistd.h"
13#include <fcntl.h>
Misha Brukman0abaaf42003-08-11 22:29:36 +000014#include <stdio.h>
15#include <string.h>
16
17/*
18 * This is the expected header for all valid LLVM bytecode files.
19 * The first four characters must be exactly this.
20 */
21static const char llvmHeader[] = "llvm";
22
23/*
24 * The type of the execve() function is long and boring, but required.
25 */
26typedef int(*execveTy)(const char*, char *const[], char *const[]);
27
28/*
29 * This method finds the real `execve' call in the C library and executes the
30 * given program.
31 */
32int executeProgram(const char *filename, char *const argv[], char *const envp[])
33{
34 /*
35 * Find a pointer to the *real* execve() function starting the search in the
36 * next library and forward, to avoid finding the one defined in this file.
37 */
38 char *error;
39 execveTy execvePtr = (execveTy) dlsym(RTLD_NEXT, "execve");
40 if ((error = dlerror()) != NULL) {
41 fprintf(stderr, "%s\n", error);
42 return -1;
43 }
44
45 /* Really execute the program */
46 return execvePtr(filename, argv, envp);
47}
48
49/*
50 * This replacement execve() function first checks the file to be executed
51 * to see if it is a valid LLVM bytecode file, and then either invokes our
52 * execution environment or passes it on to the system execve() call.
53 */
54int execve(const char *filename, char *const argv[], char *const envp[])
55{
56 /* Open the file, test to see if first four characters are "llvm" */
Misha Brukman593ece02003-08-15 23:31:16 +000057 size_t headerSize = strlen(llvmHeader);
58 char header[headerSize];
59 errno = 0;
60 int file = open(filename, O_RDONLY);
Misha Brukman0abaaf42003-08-11 22:29:36 +000061 /* Check validity of `file' */
Misha Brukman593ece02003-08-15 23:31:16 +000062 if (errno) return EIO;
Misha Brukman0abaaf42003-08-11 22:29:36 +000063 /* Read the header from the file */
Misha Brukman593ece02003-08-15 23:31:16 +000064 ssize_t bytesRead = read(file, header, headerSize);
65 close(file);
66 if (bytesRead != headerSize) return EIO;
67 if (!memcmp(llvmHeader, header, headerSize)) {
Misha Brukman0abaaf42003-08-11 22:29:36 +000068 /*
69 * This is a bytecode file, so execute the JIT with the program and
70 * parameters.
71 */
72 unsigned argvSize, idx;
73 for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
74 ++argvSize;
75 char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
Misha Brukman593ece02003-08-15 23:31:16 +000076 char *BCpath;
77 /*
78 * If the program is specified with a relative or absolute path,
79 * then just use the path and filename as is, otherwise search for it.
80 */
81 if (filename[0] != '.' && filename[0] != '/')
82 BCpath = FindExecutable(filename);
83 else
84 BCpath = (char*) filename;
85 if (!BCpath) {
86 fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
87 return -1;
88 }
Misha Brukman0abaaf42003-08-11 22:29:36 +000089 char *LLIpath = FindExecutable("lli");
90 if (!LLIpath) {
91 fprintf(stderr, "Cannot find path to `lli', exiting.\n");
92 return -1;
93 }
94 LLIargs[0] = LLIpath;
Misha Brukman593ece02003-08-15 23:31:16 +000095 LLIargs[1] = BCpath;
96 for (idx = 1; idx != argvSize; ++idx)
Misha Brukman0abaaf42003-08-11 22:29:36 +000097 LLIargs[idx+1] = argv[idx];
98 LLIargs[argvSize + 1] = '\0';
Misha Brukman0abaaf42003-08-11 22:29:36 +000099 return executeProgram(LLIpath, LLIargs, envp);
100 }
Misha Brukman593ece02003-08-15 23:31:16 +0000101 return executeProgram(filename, argv, envp);
Misha Brukman0abaaf42003-08-11 22:29:36 +0000102}