aboutsummaryrefslogtreecommitdiff
path: root/tools/llee/StorageProxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llee/StorageProxy.c')
-rw-r--r--tools/llee/StorageProxy.c101
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);
+}