Commit f127fa13 authored by Julian Kranz's avatar Julian Kranz

GDSL Multiplexer: Portability

parent 33b68301
......@@ -66,3 +66,16 @@
/tools/x86-test-runner/x86-test-runner
/tools/x86-test-stats-runner/x86-test-stats-runner
/tools/xed-cmp/xed-cmp
libs/gdsl-multiplex/build/
libs/gdwrap/build/
libs/jrreil/build/
libs/readhex/build/
libs/rreil-sim/build/
libs/rreil/build/
libs/util/build/
libs/x86-generator/build/
libs/x86-tester/build/
tools/x86-test-runner/build/
tools/x86-test-stats-runner/build/
tools/xed-cmp/build/
......@@ -11,7 +11,12 @@
#include <gdsl.h>
#include <stdint.h>
struct backend {
struct frontend_desc {
char *name;
char *ext;
};
struct frontend {
struct {
state_t (*init)();
void (*set_code)(state_t state, char *buffer, uint64_t size, uint64_t base);
......@@ -39,12 +44,12 @@ struct backend {
};
#define GDSL_MULTIPLEX_ERROR_NONE 0
#define GDSL_MULTIPLEX_ERROR_BACKENDS_PATH_NOT_SET 1
#define GDSL_MULTIPLEX_ERROR_FRONTENDS_PATH_NOT_SET 1
#define GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN 2
#define GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND 3
size_t gdsl_multiplex_backends_list(char ***backends);
char gdsl_multiplex_backend_get(struct backend *backend, const char *name);
void gdsl_multiplex_backend_close(struct backend *backend);
extern size_t gdsl_multiplex_frontends_list(struct frontend_desc **descs);
extern char gdsl_multiplex_frontend_get(struct frontend *backend, struct frontend_desc desc);
extern void gdsl_multiplex_frontend_close(struct frontend *frontend);
#endif /* GDSL_MULTIPLEX_H_ */
......@@ -14,70 +14,90 @@
#include <gdsl_multiplex.h>
static char *backend_get(char *file) {
static char frontend_get(struct frontend_desc *desc, char *file) {
size_t length = strlen(file);
char *prefix = "libgdsl-";
size_t prefix_length = strlen(prefix);
char *suffix = ".dylib";
size_t suffix_length = strlen(suffix);
if(!strncmp(file, prefix, prefix_length) && length > suffix_length
&& !strcmp(file + length - suffix_length, suffix)) {
size_t decoder_length = length - prefix_length - suffix_length;
char *decoder = (char*)malloc(decoder_length + 1);
memcpy(decoder, file + prefix_length, decoder_length);
decoder[decoder_length] = 0;
return decoder;
size_t suffixes_length = 2;
char *suffix[] = { ".so", ".dylib" };
size_t suffix_length[suffixes_length];
for (size_t i = 0; i < suffixes_length; ++i)
suffix_length[i] = strlen(suffix[i]);
for (size_t i = 0; i < suffixes_length; ++i) {
char *suffix_next = suffix[i];
size_t suffix_length_next = suffix_length[i];
if(!strncmp(file, prefix, prefix_length) && length > suffix_length_next
&& !strcmp(file + length - suffix_length_next, suffix_next)) {
size_t decoder_length = length - prefix_length - suffix_length_next;
char *decoder = (char*)malloc(decoder_length + 1);
memcpy(decoder, file + prefix_length, decoder_length);
decoder[decoder_length] = 0;
// char *suffix_ = (char*)malloc(suffix_length + 1);
// memcpy(suffix_, suffix, suffix_length + 1);
desc->name = decoder;
desc->ext = suffix_next;
return 1;
}
}
return NULL;
return 0;
}
size_t gdsl_multiplex_backends_list(char ***backends) {
size_t gdsl_multiplex_frontends_list(struct frontend_desc **descs) {
char *base = getenv("GDSL_FRONTENDS");
if(!base)
return 0;
size_t backends_length = 0;
size_t backends_size = 8;
*backends = (char**)malloc(sizeof(char*) * backends_size);
size_t frontends_length = 0;
size_t frontends_size = 8;
*descs = (struct frontend_desc*)malloc(sizeof(struct frontend_desc) * frontends_size);
DIR *dir;
struct dirent *ent;
dir = opendir(base);
if(dir) {
while((ent = readdir(dir)) != NULL) {
char *backend = backend_get(ent->d_name);
if(backend) {
if(backends_length == backends_size) {
backends_size <<= 1;
*backends = (char**)realloc(*backends, sizeof(char*)*backends_size);
struct frontend_desc desc;
char frontend = frontend_get(&desc, ent->d_name);
if(frontend) {
if(frontends_length == frontends_size) {
frontends_size <<= 1;
*descs = (struct frontend_desc*)realloc(descs, sizeof(struct frontend_desc) * frontends_size);
}
(*backends)[backends_length++] = backend;
(*descs)[frontends_length++] = desc;
}
}
closedir(dir);
}
return backends_length;
return frontends_length;
}
#define ADD_FUNCTION_GENERIC(CAT,FUNC,NAME)\
backend->CAT.FUNC = (__typeof__(backend->CAT.FUNC))dlsym(dl, NAME);\
if(!backend->CAT.FUNC)\
frontend->CAT.FUNC = (__typeof__(frontend->CAT.FUNC))dlsym(dl, NAME);\
if(!frontend->CAT.FUNC)\
error = 1;
#define ADD_FUNCTION(CAT,FUNC) ADD_FUNCTION_GENERIC(CAT,FUNC,"gdsl_" #FUNC)
char gdsl_multiplex_backend_get(struct backend *backend, const char *name) {
char gdsl_multiplex_frontend_get(struct frontend *frontend, struct frontend_desc desc) {
char *base = getenv("GDSL_FRONTENDS");
if(!base)
return GDSL_MULTIPLEX_ERROR_BACKENDS_PATH_NOT_SET;
return GDSL_MULTIPLEX_ERROR_FRONTENDS_PATH_NOT_SET;
char *lib;
size_t lib_length;
FILE *libf = open_memstream(&lib, &lib_length);
fprintf(libf, "%s/libgdsl-%s.dylib", base, name);
fprintf(libf, "%s/libgdsl-%s%s", base, desc.name, desc.ext);
fputc(0, libf);
fclose(libf);
......@@ -106,11 +126,11 @@ char gdsl_multiplex_backend_get(struct backend *backend, const char *name) {
if(error)
return GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND;
backend->dl = dl;
frontend->dl = dl;
return GDSL_MULTIPLEX_ERROR_NONE;
}
void gdsl_multiplex_backend_close(struct backend *backend) {
void gdsl_multiplex_frontend_close(struct frontend *backend) {
dlclose(backend->dl);
}
......@@ -692,7 +692,7 @@ static obj_t sem_stmts_init(state_t state, obj_t nothing) {
return (obj_t)ret;
}
struct backend backend;
struct frontend frontend;
JNIEXPORT
jobject
......@@ -706,22 +706,22 @@ JNICALL Java_rnati_NativeInterface_decodeAndTranslateNative(JNIEnv *env, jobject
size_t length = (*env)->GetArrayLength(env, input);
char *bytes = (char*)(*env)->GetByteArrayElements(env, input, 0);
state_t state = backend.generic.init();
backend.generic.set_code(state, bytes, length, 0);
state_t state = frontend.generic.init();
frontend.generic.set_code(state, bytes, length, 0);
if(setjmp(*backend.generic.err_tgt(state))) {
if(setjmp(*frontend.generic.err_tgt(state))) {
jclass exp = (*env)->FindClass(env, "rnati/GdslDecodeException");
(*env)->ThrowNew(env, exp, "Decode failed.");
return NULL;
}
obj_t insn = backend.decoder.decode(state, backend.decoder.config_default(state));
obj_t insn = frontend.decoder.decode(state, frontend.decoder.config_default(state));
if(setjmp(*backend.generic.err_tgt(state))) {
if(setjmp(*frontend.generic.err_tgt(state))) {
jclass exp = (*env)->FindClass(env, "rnati/RReilTranslateException");
(*env)->ThrowNew(env, exp, "Translate failed.");
return NULL;
}
obj_t rreil = backend.translator.translate(state, insn);
obj_t rreil = frontend.translator.translate(state, insn);
// __pretty(__rreil_pretty__, r, fmt, 2048);
// printf("---------------------------\n");
......@@ -853,29 +853,31 @@ JNICALL Java_rnati_NativeInterface_decodeAndTranslateNative(JNIEnv *env, jobject
ud.env = env;
ud.obj = obj;
backend.translator.rreil_cif_userdata_set(state, &ud);
frontend.translator.rreil_cif_userdata_set(state, &ud);
return backend.translator.rreil_convert_sem_stmts(state, &callbacks, rreil);
return frontend.translator.rreil_convert_sem_stmts(state, &callbacks, rreil);
}
struct frontend_desc *descs;
size_t frontends_length;
JNIEXPORT
jobjectArray
JNICALL Java_rnati_NativeInterface_getFrontendsNative(JNIEnv *env, jobject obj) {
char **backends;
size_t backends_length = gdsl_multiplex_backends_list(&backends);
frontends_length = gdsl_multiplex_frontends_list(&descs);
jobjectArray jbackends = (*env)->NewObjectArray(env, backends_length, (*env)->FindClass(env, "java/lang/String"),
jobjectArray jfrontends = (*env)->NewObjectArray(env, frontends_length, (*env)->FindClass(env, "java/lang/String"),
(*env)->NewStringUTF(env, ""));
for(size_t i = 0; i < backends_length; ++i) {
jstring next = (*env)->NewStringUTF(env, backends[i]);
free(backends[i]);
(*env)->SetObjectArrayElement(env, jbackends, i, next);
for(size_t i = 0; i < frontends_length; ++i) {
jstring next = (*env)->NewStringUTF(env, descs[i].name);
// free(frontends[i]);
(*env)->SetObjectArrayElement(env, jfrontends, i, next);
}
if(backends_length)
free(backends);
// if(frontends_length)
// free(frontends);
return jbackends;
return jfrontends;
}
#define THROW_RUNTIME(MSG) {\
......@@ -886,21 +888,21 @@ JNICALL Java_rnati_NativeInterface_getFrontendsNative(JNIEnv *env, jobject obj)
JNIEXPORT
void
JNICALL Java_rnati_NativeInterface_useBackendNative(JNIEnv *env, jobject obj, jstring backend_str) {
const char *backend_str_n = (*env)->GetStringUTFChars(env, backend_str, 0);
JNICALL Java_rnati_NativeInterface_usefrontendNative(JNIEnv *env, jobject obj, jlong frontend) {
// const char *frontend_str_n = (*env)->GetStringUTFChars(env, frontend_str, 0);
switch(gdsl_multiplex_backend_get(&backend, backend_str_n)) {
case GDSL_MULTIPLEX_ERROR_BACKENDS_PATH_NOT_SET: THROW_RUNTIME("Unable to open backend: Path to backends not set")
case GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN: THROW_RUNTIME("Unable to open backend: Unable to open backend library")
case GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND: THROW_RUNTIME("Unable to open backend: Symbol not found")
switch(gdsl_multiplex_frontend_get(&frontend, descs[(long)frontend])) {
case GDSL_MULTIPLEX_ERROR_FRONTENDS_PATH_NOT_SET: THROW_RUNTIME("Unable to open frontend: Path to frontends not set")
case GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN: THROW_RUNTIME("Unable to open frontend: Unable to open frontend library")
case GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND: THROW_RUNTIME("Unable to open frontend: Symbol not found")
case GDSL_MULTIPLEX_ERROR_NONE: break;
}
(*env)->ReleaseStringUTFChars(env, backend_str, backend_str_n);
// (*env)->ReleaseStringUTFChars(env, frontend_str, frontend_str_n);
}
JNIEXPORT
void
JNICALL Java_rnati_NativeInterface_closeBackendNative(JNIEnv *env, jobject obj) {
gdsl_multiplex_backend_close(&backend);
JNICALL Java_rnati_NativeInterface_closeFrontendNative(JNIEnv *env, jobject obj) {
gdsl_multiplex_frontend_close(&frontend);
}
......@@ -15,8 +15,8 @@ extern "C" {
JNIEXPORT jobject JNICALL Java_rnati_NativeInterface_decodeAndTranslateNative(JNIEnv *, jobject, jbyteArray);
JNIEXPORT jobjectArray JNICALL Java_rnati_NativeInterface_getFrontendsNative(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_rnati_NativeInterface_useBackendNative(JNIEnv *, jobject, jstring);
JNIEXPORT void JNICALL Java_rnati_NativeInterface_closeBackendNative(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_rnati_NativeInterface_useFrontendNative(JNIEnv *, jobject, jlong);
JNIEXPORT void JNICALL Java_rnati_NativeInterface_closeFrontendNative(JNIEnv *, jobject);
#ifdef __cplusplus
}
......
......@@ -15,36 +15,36 @@
int main(int argc, char** argv) {
char retval = 0;
char **backends;
size_t backends_count = gdsl_multiplex_backends_list(&backends);
struct frontend_desc *frontends;
size_t frontends_count = gdsl_multiplex_frontends_list(&frontends);
size_t backend_ind = 0;
if(!backends_count) {
size_t frontend_ind = 0;
if(!frontends_count) {
fprintf(stderr, "No frontends available.\n");
return 1;
}
if(backends_count > 1) {
if(frontends_count > 1) {
printf("Available frontends:\n");
for(size_t i = 0; i < backends_count; ++i)
printf("\t[%zu] %s\n", i, backends[i]);
for(size_t i = 0; i < frontends_count; ++i)
printf("\t[%zu] %s\n", i, frontends[i].name);
printf("Your choice? ");
scanf("%zu", &backend_ind);
scanf("%zu", &frontend_ind);
}
if(backend_ind >= backends_count) {
fprintf(stderr, "Frontend %zu is invalid.\n", backend_ind);
if(frontend_ind >= frontends_count) {
fprintf(stderr, "Frontend %zu is invalid.\n", frontend_ind);
return 1;
}
printf("Using frontend %s...\n", backends[backend_ind]);
printf("Using frontend %s...\n", frontends[frontend_ind].name);
// __fpurge(stdin);
uint8_t *buffer;
size_t size = readhex_hex_read(stdin, &buffer);
struct backend backend;
if(gdsl_multiplex_backend_get(&backend, backends[backend_ind])) {
struct frontend backend;
if(gdsl_multiplex_frontend_get(&backend, frontends[frontend_ind])) {
fprintf(stderr, "Unable to open frontend.\n");
return 1;
}
......@@ -89,11 +89,11 @@ int main(int argc, char** argv) {
backend.generic.destroy(state);
free(buffer);
for (size_t i = 0; i < backends_count; ++i)
free(backends[i]);
free(backends);
// for (size_t i = 0; i < frontends_count; ++i)
// free(frontends[i]);
// free(frontends);
gdsl_multiplex_backend_close(&backend);
gdsl_multiplex_frontend_close(&backend);
return retval;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment