Commit 1edfb518 authored by Julian Kranz's avatar Julian Kranz

insncb :-(

parent 60f8ec5a
......@@ -106,6 +106,8 @@ block gdsl::gdsl::decode_translate_block(preservation pres, int_t limit) {
throw gdsl_exception("decode_translate_block() failed", string(frontend->native().generic.get_error_message(gdsl_state)));
gdsl_insns cls = {this, new std::vector<instruction>()};
obj_t rreil = frontend->native().translator.decode_translate_block_optimized(gdsl_state,
frontend->native().decoder.config_default(gdsl_state), limit, pres, &cls, insn_cb)->rreil;
obj_t rreil = frontend->native().translator.decode_translate_block_optimized_insncb(gdsl_state,
frontend->native().decoder.config_default(gdsl_state), limit, pres, &cls, insn_cb)->rreil;
std::vector<rreil::statement*> *statements = convert(rreil);
......
......@@ -42,17 +42,18 @@ struct frontend {
obj_t (*decode)(state_t state, int_t config);
obj_t (*generalize)(state_t state, obj_t insn);
obj_t (*asm_convert_insn)(state_t s, asm_callbacks_t cbs, asm_insn_t insn);
obj_t *(*pretty)(state_t state, obj_t insn);
obj_t (*pretty)(state_t state, obj_t insn);
} decoder;
struct {
obj_t (*translate)(state_t state, obj_t insn);
obj_t *(*pretty)(state_t state, obj_t rreil);
obj_t *(*pretty_arch_id)(state_t state, obj_t id);
obj_t *(*pretty_arch_exception)(state_t state, obj_t id);
obj_t (*pretty)(state_t state, obj_t rreil);
obj_t (*pretty_arch_id)(state_t state, obj_t id);
obj_t (*pretty_arch_exception)(state_t state, obj_t id);
obj_t (*rreil_convert_sem_stmt_list)(state_t s, callbacks_t cbs, obj_t stmts);
opt_result_t (*decode_translate_block_optimized_insncb)(state_t state, int_t config, int_t limit, int_t pres,
opt_result_t (*decode_translate_block_optimized)(state_t state, int_t config, int_t limit, int_t pres,
obj_t insns_init, obj_t (*insn_cb)(state_t, obj_t, obj_t));
obj_t (*traverse_insn_list)(state_t state, obj_t insns_init, obj_t (*insn_cb)(state_t, obj_t, obj_t));
} translator;
void *dl;
......
......@@ -16,75 +16,75 @@
#include <gdsl_multiplex.h>
static char frontend_get(struct frontend_desc *desc, char *file) {
size_t length = strlen(file);
size_t length = strlen(file);
char *prefix = "libgdsl-";
size_t prefix_length = strlen(prefix);
char *prefix = "libgdsl-";
size_t prefix_length = strlen(prefix);
size_t suffixes_length = 2;
char *suffix[] = { ".so", ".dylib" };
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]);
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];
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;
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 *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;
desc->name = decoder;
desc->ext = suffix_next;
return 1;
}
}
return 1;
}
}
return 0;
return 0;
}
size_t gdsl_multiplex_frontends_list_with_base(struct frontend_desc **descs, char const *base) {
if(!base) return 0;
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) {
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);
}
(*descs)[frontends_length++] = desc;
}
}
closedir(dir);
}
return frontends_length;
if(!base) return 0;
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) {
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);
}
(*descs)[frontends_length++] = desc;
}
}
closedir(dir);
}
return frontends_length;
}
size_t gdsl_multiplex_frontends_list(struct frontend_desc **descs) {
char *base = getenv("GDSL_FRONTENDS");
return gdsl_multiplex_frontends_list_with_base(descs, base);
char *base = getenv("GDSL_FRONTENDS");
return gdsl_multiplex_frontends_list_with_base(descs, base);
}
#define ADD_FUNCTION_GENERIC(CAT,FUNC,NAME)\
......@@ -94,93 +94,93 @@ size_t gdsl_multiplex_frontends_list(struct frontend_desc **descs) {
#define ADD_FUNCTION(CAT,FUNC) ADD_FUNCTION_GENERIC(CAT,FUNC,"gdsl_" #FUNC)
static char gdsl_multiplex_frontend_get(struct frontend *frontend, void *dl) {
char error = 0;
ADD_FUNCTION(generic, init)
ADD_FUNCTION(generic, set_code)
ADD_FUNCTION(generic, seek)
ADD_FUNCTION(generic, err_tgt)
ADD_FUNCTION(generic, get_error_message)
ADD_FUNCTION(generic, reset_heap)
ADD_FUNCTION(generic, destroy)
ADD_FUNCTION(generic, get_ip_offset)
ADD_FUNCTION(generic, merge_rope)
ADD_FUNCTION(decoder, config_default)
ADD_FUNCTION(decoder, decoder_config)
ADD_FUNCTION(decoder, has_conf)
ADD_FUNCTION(decoder, conf_next)
ADD_FUNCTION(decoder, conf_short)
ADD_FUNCTION(decoder, conf_long)
ADD_FUNCTION(decoder, conf_data)
ADD_FUNCTION(decoder, decode)
ADD_FUNCTION(decoder, generalize)
ADD_FUNCTION(decoder, asm_convert_insn)
ADD_FUNCTION(decoder, pretty)
ADD_FUNCTION(translator, translate)
ADD_FUNCTION_GENERIC(translator, pretty, "gdsl_rreil_pretty")
ADD_FUNCTION(translator, pretty_arch_id)
ADD_FUNCTION(translator, pretty_arch_exception)
ADD_FUNCTION(translator, rreil_convert_sem_stmt_list)
ADD_FUNCTION(translator, decode_translate_block_optimized_insncb)
if(error) return GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND;
frontend->dl = dl;
return GDSL_MULTIPLEX_ERROR_NONE;
char error = 0;
ADD_FUNCTION(generic, init)
ADD_FUNCTION(generic, set_code)
ADD_FUNCTION(generic, seek)
ADD_FUNCTION(generic, err_tgt)
ADD_FUNCTION(generic, get_error_message)
ADD_FUNCTION(generic, reset_heap)
ADD_FUNCTION(generic, destroy)
ADD_FUNCTION(generic, get_ip_offset)
ADD_FUNCTION(generic, merge_rope)
ADD_FUNCTION(decoder, config_default)
ADD_FUNCTION(decoder, decoder_config)
ADD_FUNCTION(decoder, has_conf)
ADD_FUNCTION(decoder, conf_next)
ADD_FUNCTION(decoder, conf_short)
ADD_FUNCTION(decoder, conf_long)
ADD_FUNCTION(decoder, conf_data)
ADD_FUNCTION(decoder, decode)
ADD_FUNCTION(decoder, generalize)
ADD_FUNCTION(decoder, asm_convert_insn)
ADD_FUNCTION(decoder, pretty)
ADD_FUNCTION(translator, translate)
ADD_FUNCTION_GENERIC(translator, pretty, "gdsl_rreil_pretty")
ADD_FUNCTION(translator, pretty_arch_id)
ADD_FUNCTION(translator, pretty_arch_exception)
ADD_FUNCTION(translator, rreil_convert_sem_stmt_list)
ADD_FUNCTION(translator, decode_translate_block_optimized)
ADD_FUNCTION(translator, traverse_insn_list)
if(error) return GDSL_MULTIPLEX_ERROR_SYMBOL_NOT_FOUND;
frontend->dl = dl;
return GDSL_MULTIPLEX_ERROR_NONE;
}
static char gdsl_multiplex_frontend_library_open_desc(void **dl, struct frontend_desc desc) {
char *base = getenv("GDSL_FRONTENDS");
if(!base) return GDSL_MULTIPLEX_ERROR_FRONTENDS_PATH_NOT_SET;
char *base = getenv("GDSL_FRONTENDS");
if(!base) 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%s", base, desc.name, desc.ext);
fputc(0, libf);
fclose(libf);
char *lib;
size_t lib_length;
FILE *libf = open_memstream(&lib, &lib_length);
fprintf(libf, "%s/libgdsl-%s%s", base, desc.name, desc.ext);
fputc(0, libf);
fclose(libf);
*dl = dlopen(lib, RTLD_LAZY);
free(lib);
if(!*dl) return GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN;
*dl = dlopen(lib, RTLD_LAZY);
free(lib);
if(!*dl) return GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN;
return 0;
return 0;
}
char gdsl_multiplex_frontend_get_by_desc(struct frontend *frontend, struct frontend_desc desc) {
void *dl;
char error = gdsl_multiplex_frontend_library_open_desc(&dl, desc);
if(error)
return error;
void *dl;
char error = gdsl_multiplex_frontend_library_open_desc(&dl, desc);
if(error) return error;
return gdsl_multiplex_frontend_get(frontend, dl);
return gdsl_multiplex_frontend_get(frontend, dl);
}
char gdsl_multiplex_frontend_get_by_lib_name(struct frontend *frontend, char const *name) {
char *lib;
size_t lib_length;
FILE *libf = open_memstream(&lib, &lib_length);
fprintf(libf, "libgdsl-%s.so", name);
fputc(0, libf);
fclose(libf);
void *dl = dlopen(lib, RTLD_LAZY);
free(lib);
if(!dl) return GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN;
return gdsl_multiplex_frontend_get(frontend, dl);
char *lib;
size_t lib_length;
FILE *libf = open_memstream(&lib, &lib_length);
fprintf(libf, "libgdsl-%s.so", name);
fputc(0, libf);
fclose(libf);
void *dl = dlopen(lib, RTLD_LAZY);
free(lib);
if(!dl) return GDSL_MULTIPLEX_ERROR_UNABLE_TO_OPEN;
return gdsl_multiplex_frontend_get(frontend, dl);
}
/*
* Todo: Fix? What about .ext?
*/
void gdsl_multiplex_descs_free(struct frontend_desc *descs, size_t descs_length) {
for(size_t i = 0; i < descs_length; ++i)
free((char*)descs[i].name);
free(descs);
for(size_t i = 0; i < descs_length; ++i)
free((char*) descs[i].name);
free(descs);
}
void gdsl_multiplex_frontend_close(struct frontend *backend) {
dlclose(backend->dl);
dlclose(backend->dl);
}
This diff is collapsed.
export decode-translate-block-optimized: (decoder-configuration, int, rreil-configuration) -> S sem_stmt_list <{} => {}>
export decode-translate-block-optimized-insncb: (decoder-configuration, int, rreil-configuration, insn_list_obj, (insn_list_obj, insndata) -> insn_list_obj) -> S opt-result <{} => {}>
export decode-translate-block-optimized: (decoder-configuration, int, rreil-configuration) -> S opt-result <{} => {}>
export traverse-insn-list: (insn_list, insn_list_obj, (insn_list_obj, insndata) -> insn_list_obj) -> insn_list_obj
type insn_list_obj = INSN_LIST_OBJ
type insn_list =
INSNS_CONS of {insn:insndata, tl:insn_list}
| INSNS_NIL
val traverse-insn-list l init insn-append = case l of
INSNS_CONS cons: insn-append (traverse-insn-list cons.tl init insn-append) cons.insn
| INSNS_NIL: init
end
type sem_preservation =
SEM_PRESERVATION_EVERYWHERE
| SEM_PRESERVATION_BLOCK
| SEM_PRESERVATION_CONTEXT
val decode-translate-block-optimized-insncb-inner config limit pres insn-append = case pres of
val decode-translate-block-optimized-inner config limit pres = case pres of
SEM_PRESERVATION_EVERYWHERE: do
translated <- decode-translate-block-insns config limit insn-append;
translated <- decode-translate-block config limit;
clean <- cleanup translated;
return clean
end
| SEM_PRESERVATION_BLOCK: do
translated <- decode-translate-block-insns config limit insn-append;
translated <- decode-translate-block config limit;
lv-result <- liveness translated;
live <- query $live;
clean <- cleanup live;
return clean
end
| SEM_PRESERVATION_CONTEXT: do
translated <- decode-translate-super-block-insncb config limit insn-append;
translated <- decode-translate-super-block config limit;
lv-result <- liveness_super translated;
live <- query $live;
clean <- cleanup live;
......@@ -28,33 +39,19 @@ val decode-translate-block-optimized-insncb-inner config limit pres insn-append
end
end
val decode-translate-block-optimized-inner config limit pres = let
val default-append a b = a
in
decode-translate-block-optimized-insncb-inner config limit pres default-append
end
type opt-result = {
insns: insn_list_obj,
insns: insn_list,
rreil: sem_stmt_list
}
val decode-translate-block-optimized-insncb config limit rreil-config insns-initv insn-append = do
update @{insns=insns-initv};
val decode-translate-block-optimized config limit rreil-config = do
update @{insns=INSNS_NIL};
rreil <- case rreil-config of
'00.': decode-translate-block-optimized-insncb-inner config limit SEM_PRESERVATION_EVERYWHERE insn-append
| '01.': decode-translate-block-optimized-insncb-inner config limit SEM_PRESERVATION_BLOCK insn-append
| '1..': decode-translate-block-optimized-insncb-inner config limit SEM_PRESERVATION_CONTEXT insn-append
'00.': decode-translate-block-optimized-inner config limit SEM_PRESERVATION_EVERYWHERE
| '01.': decode-translate-block-optimized-inner config limit SEM_PRESERVATION_BLOCK
| '1..': decode-translate-block-optimized-inner config limit SEM_PRESERVATION_CONTEXT
end;
insns <- query $insns;
return {rreil=rreil, insns=insns}
end
val decode-translate-block-optimized config limit rreil-config = let
val default-append a b = a
in do
result <- decode-translate-block-optimized-insncb config limit rreil-config INSN_LIST_OBJ default-append;
return result.rreil
end end
type insn_list_obj = INSN_LIST_OBJ
export decode-translate-block: (decoder-configuration, int) -> S sem_stmt_list <{insns: insn_list_obj} => {insns: insn_list_obj}>
export decode-translate-single: (decoder-configuration) -> S sem_stmt_list <{insns: insn_list_obj} => {insns: insn_list_obj}>
export decode-translate-block-insns: (decoder-configuration, int, (insn_list_obj, insndata) -> insn_list_obj) -> S sem_stmt_list <{insns: insn_list_obj} => {insns: insn_list_obj}>
export decode-translate-super-block: (decoder-configuration, int) -> S translate-result <{insns: insn_list_obj} => {insns: insn_list_obj}>
export decode-translate-block: (decoder-configuration, int) -> S sem_stmt_list <{insns: insn_list} => {insns: insn_list}>
export decode-translate-single: (decoder-configuration) -> S sem_stmt_list <{insns: insn_list} => {insns: insn_list}>
export decode-translate-super-block: (decoder-configuration, int) -> S translate-result <{insns: insn_list} => {insns: insn_list}>
export select_ins_count: S int <{ins_count: int} => {ins_count: int}>
export succ-pretty: (stmts_option, string) -> rope
export rreil-config : configuration[vec=rreil-configuration]
......@@ -14,30 +13,22 @@ val rreil-config =
conf '100' "inter-bb" "perform inter-basic block liveness analysis"
val insn-append-default a b = a
val decode-translate-block-headless config limit insn-append = do
val decode-translate-block-headless config limit = do
insn <- decode config;
insns <- query $insns;
update @{insns=insn-append insns insn};
update @{insns=INSNS_CONS {insn=insn, tl=insns}};
translate-block-single insn;
jmp <- query $foundJump;
idx <- idxget;
if jmp or (idx >= limit) then
query $stack
else
decode-translate-block-headless config limit insn-append
decode-translate-block-headless config limit
end
val decode-translate-block config limit = do
update @{ins_count=0,stack=SEM_NIL,foundJump='0'};
stmts <- decode-translate-block-headless config limit insn-append-default;
return (rreil-stmts-rev stmts)
end
val decode-translate-block-insns config limit insn-append = do
update @{ins_count=0,stack=SEM_NIL,foundJump='0'};
stmts <- decode-translate-block-headless config limit insn-append;
stmts <- decode-translate-block-headless config limit;
return (rreil-stmts-rev stmts)
end
......@@ -51,45 +42,45 @@ val io-tw a = {a=a,b=a}
val relative-next-generic is_sem_ip stmts = let
val raddress addr =
case addr.address of
SEM_LIN_ADD s:
case s.opnd1 of
SEM_LIN_VAR v:
if (is_sem_ip v.id) then
case s.opnd2 of
SEM_LIN_IMM i: IO_SOME i.const
| _: IO_NONE
end
else
case addr.address of
SEM_LIN_ADD s:
case s.opnd1 of
SEM_LIN_VAR v:
if (is_sem_ip v.id) then
case s.opnd2 of
SEM_LIN_IMM i: IO_SOME i.const
| _: IO_NONE
end
else
IO_NONE
| SEM_LIN_IMM i:
case s.opnd2 of
SEM_LIN_VAR v:
if (is_sem_ip v.id) then
IO_SOME i.const
else
| SEM_LIN_IMM i:
case s.opnd2 of
SEM_LIN_VAR v:
if (is_sem_ip v.id) then
IO_SOME i.const
else
IO_NONE
| _: IO_NONE
end
end
| SEM_LIN_VAR v:
if (is_sem_ip v.id) then
IO_SOME 0
else
| _: IO_NONE
end
end
| SEM_LIN_VAR v:
if (is_sem_ip v.id) then
IO_SOME 0
else
IO_NONE
| _: IO_NONE
end
| _: IO_NONE
end
in
case stmts of
SEM_CONS x:
case x.hd of
SEM_CBRANCH b: io (raddress b.target-true) (raddress b.target-false)
| SEM_BRANCH b: io-to (raddress b.target)
| SEM_ITE c: io (relative-next (rreil-stmts-rev c.then_branch)).a (relative-next (rreil-stmts-rev c.else_branch)).a
| _: io-tw IO_NONE
end
| SEM_NIL: (io-tw IO_NONE)
end
SEM_CONS x:
case x.hd of
SEM_CBRANCH b: io (raddress b.target-true) (raddress b.target-false)
| SEM_BRANCH b: io-to (raddress b.target)
| SEM_ITE c: io (relative-next (rreil-stmts-rev c.then_branch)).a (relative-next (rreil-stmts-rev c.else_branch)).a
| _: io-tw IO_NONE
end
| SEM_NIL: (io-tw IO_NONE)
end
end
type stmts_option =
......@@ -102,30 +93,30 @@ type translate-result = {
succ_b:stmts_option
}
val decode-translate-super-block-insncb config limit insn-append = let
val decode-translate-super-block config limit = let
val translate-block-at idx = do
current <- idxget;
#error <- rseek idx;
error <- seek (current + idx);
result <- if error === 0 then do
stmts <- decode-translate-block config int-max;
seek current;
return (SO_SOME stmts)
end else
return SO_NONE
;
return result
current <- idxget;
#error <- rseek idx;
error <- seek (current + idx);
result <- if error === 0 then do
stmts <- decode-translate-block config int-max;
seek current;
return (SO_SOME stmts)
end else
return SO_NONE
;
return result
end
val seek-translate-block-at idx-opt = do
case idx-opt of
IO_SOME i: translate-block-at i
| IO_NONE: return SO_NONE
end
end
case idx-opt of
IO_SOME i: translate-block-at i
| IO_NONE: return SO_NONE
end
end
in do
update @{ins_count=0,stack=SEM_NIL,foundJump='0'};
stmts <- decode-translate-block-headless config limit insn-append;
stmts <- decode-translate-block-headless config limit;
ic <- query $ins_count;
......@@ -138,14 +129,8 @@ in do
return {insns=(rreil-stmts-rev stmts), succ_a=succ_a, succ_b=succ_b}
end end
val decode-translate-super-block config limit = let
val default-append a b = a
in
decode-translate-super-block-insncb config limit default-append
end
val succ-pretty succ name =
case succ of
SO_SOME i: "Succ " +++ (from-string-lit name) +++ ":\n" +++ (rreil-pretty i)
| SO_NONE: "Succ " +++ (from-string-lit name) +++ ": NONE :-("
end
SO_SOME i: "Succ " +++ (from-string-lit name) +++ ":\n" +++ (rreil-pretty i)
| SO_NONE: "Succ " +++ (from-string-lit name) +++ ": NONE :-("
end
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