forked from OSchip/llvm-project
102 lines
3.2 KiB
C
102 lines
3.2 KiB
C
/*===- 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/unistd.h"
|
|
#include "Config/sys/types.h"
|
|
#include "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);
|
|
executeProgram(cacheFile, argv, envp);
|
|
}
|