diff options
Diffstat (limited to 'tools/llee/StorageProxy.c')
-rw-r--r-- | tools/llee/StorageProxy.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/tools/llee/StorageProxy.c b/tools/llee/StorageProxy.c new file mode 100644 index 0000000000..0562796ec2 --- /dev/null +++ b/tools/llee/StorageProxy.c @@ -0,0 +1,101 @@ +/*===- 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 "Config/fcntl.h" +#include "Config/stdlib.h" +#include "Config/unistd.h" +#include "Config/sys/types.h" +#include "Config/sys/stat.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); + executeProgram(cacheFile, argv, envp); +} |