diff --git a/binr/radare2/Makefile b/binr/radare2/Makefile index 6242cc6018..79a23e118c 100644 --- a/binr/radare2/Makefile +++ b/binr/radare2/Makefile @@ -1,6 +1,6 @@ BIN=radare2 DEPS=r_diff r_config r_parse r_lib r_cons r_search r_anal r_reg -DEPS+=r_bin r_flags r_debug r_util r_core r_bp r_io r_cmd +DEPS+=r_bin r_flags r_debug r_util r_core r_bp r_io r_cmd r_th DEPS+=r_sign r_meta r_print r_lang r_asm r_syscall r_hash r_line include ../binr.mk diff --git a/binr/radare2/radare2.c b/binr/radare2/radare2.c index 3c3eab2a99..6bd7dd9197 100644 --- a/binr/radare2/radare2.c +++ b/binr/radare2/radare2.c @@ -1,11 +1,13 @@ /* radare - LGPL - Copyright 2009-2010 pancake */ -#include "r_core.h" -#include "r_io.h" +#include +#include +#include #include #include static struct r_core_t r; +static char *rabin_cmd = NULL; static int main_help(int line) { printf ("Usage: radare2 [-dwnLV] [-p prj] [-s addr] [-b bsz] [-e k=v] [file]\n"); @@ -32,7 +34,32 @@ static int main_version() { return 0; } +// Load the binary information from rabin2 +// TODO: use thread to load this, split contents line, per line and use global lock +static int rabin_delegate(RThread *th) { + eprintf ("rabin2: loading data in thread\n"); + if (rabin_cmd && r_file_exist (r.file->filename)) { + char *nptr, *ptr, *cmd = r_sys_cmd_str (rabin_cmd, NULL, NULL); + ptr = cmd; + do { + r_th_lock_enter(th->user); + nptr = strchr (ptr, '\n'); + if (nptr) *nptr = 0; + r_core_cmd (&r, ptr, 0); + if (nptr) ptr = nptr+1; + r_th_lock_leave(th->user); + } while (nptr); + //r_core_cmd (&r, cmd, 0); + r_str_free (rabin_cmd); + rabin_cmd = NULL; + } + eprintf ("rabin2: done\n"); + return 0; +} + int main(int argc, char **argv) { + RThreadLock *lock; + RThread *rabin_th; RCoreFile *fh = NULL; int ret, c, perms = R_IO_READ; int run_rc = 1; @@ -163,14 +190,10 @@ int main(int argc, char **argv) { if (fullfile) r_core_block_size (&r, r.file->size); else if (bsize) r_core_block_size (&r, bsize); - // Load the binary information from rabin2 - // TODO: use thread to load this, split contents line, per line and use global lock - if (r_file_exist (r.file->filename)) { - char *cmd = r_str_dup_printf (".!rabin2 -rSIeMzis%s %s", - (debug||r.io->va)?"v":"", r.file->filename); - r_core_cmd (&r, cmd, 0); - r_str_free (cmd); - } + rabin_cmd = r_str_dup_printf ("rabin2 -rSIeMzis%s %s", + (debug||r.io->va)?"v":"", r.file->filename); + lock = r_th_lock_new (); + rabin_th = r_th_new (&rabin_delegate, lock, 0); if (run_rc && r_config_get_i (r.config, "cfg.fortunes")) { r_core_cmd (&r, "fo", 0); @@ -195,8 +218,19 @@ int main(int argc, char **argv) { free (path); } for (;;) { - do { if ((ret = r_core_prompt (&r))==-1) - eprintf ("Invalid command\n"); + do { + r_core_prompt (&r, R_FALSE); + if (lock) r_th_lock_enter (lock); + if ((ret = r_core_prompt_exec (&r))==-1) + eprintf ("Invalid command\n"); + if (lock)r_th_lock_leave (lock); + if (rabin_th && !r_th_wait_async (rabin_th)) { + eprintf ("rabin thread end \n"); + r_th_free (rabin_th); + r_th_lock_free (lock); + lock = NULL; + rabin_th = NULL; + } } while (ret != R_CORE_CMD_EXIT); if (debug) { diff --git a/libr/bin/bin.c b/libr/bin/bin.c index 5f2603b974..ba00557f5b 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -14,24 +14,17 @@ static RBinPlugin *bin_static_plugins[] = { R_BIN_STATIC_PLUGINS }; -// TODO: check only in data section. filter chars only in -r mode -static RList* get_strings(RBin *bin, int min) { - RList *ret; - RBinString *ptr = NULL; +static void get_strings_range(RBin *bin, RList *list, int min, ut64 from, ut64 to) { char str[R_BIN_SIZEOF_STRINGS]; int i, matches = 0, ctr = 0; + RBinString *ptr = NULL; - if (!(ret = r_list_new ())) { - eprintf ("Error allocating array\n"); - return NULL; - } - ret->free = free; - for(i = 0; i < bin->size; i++) { + for(i = from; i < to; i++) { if ((IS_PRINTABLE (bin->buf->buf[i])) && matches < R_BIN_SIZEOF_STRINGS-1) { str[matches] = bin->buf->buf[i]; matches++; } else { - /* check if the length fits on our request */ + /* check if the length fits in our request */ if (matches >= min) { if (!(ptr = R_NEW (RBinString))) { eprintf ("Error allocating string\n"); @@ -44,12 +37,39 @@ static RList* get_strings(RBin *bin, int min) { // copying so many bytes here.. memcpy (ptr->string, str, R_BIN_SIZEOF_STRINGS); ptr->string[R_BIN_SIZEOF_STRINGS-1] = '\0'; - r_list_append (ret, ptr); + r_list_append (list, ptr); ctr++; } matches = 0; } } +} + +// TODO: check only in data section. filter chars only in -r mode +static RList* get_strings(RBin *bin, int min) { + RList *ret; + int count = 0; + + if (!(ret = r_list_new ())) { + eprintf ("Error allocating array\n"); + return NULL; + } + ret->free = free; + + if (bin->sections) { + RBinSection *section; + RListIter *iter; + r_list_foreach (bin->sections, iter, section) { + // XXX: should we check sections srwx to be READ ONLY and NONEXEC? + if (strstr (section->name, "data")) { + count ++; + get_strings_range (bin, ret, min, + section->offset, section->offset+section->size); + } + } + } + if (count == 0) + get_strings_range (bin, ret, min, 0, bin->size); return ret; } diff --git a/libr/core/core.c b/libr/core/core.c index 3cdcb1812c..3b7c2db585 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -189,7 +189,7 @@ R_API RCore *r_core_free(RCore *c) { return NULL; } -R_API int r_core_prompt(RCore *r) { +R_API int r_core_prompt(RCore *r, int sync) { static char *prevcmd = NULL; int ret; char *cmd; @@ -211,13 +211,24 @@ R_API int r_core_prompt(RCore *r) { if (ret == -2) return R_CORE_CMD_EXIT; if (ret == -1) - return 0; + return R_FALSE; if (strcmp (line, ".")) { free (prevcmd); prevcmd = strdup (line); cmd = line; } else cmd = prevcmd; - ret = r_core_cmd (r, cmd, R_TRUE); + if (sync) { + ret = r_core_cmd (r, r->cmdqueue, R_TRUE); + r_cons_flush (); + } else { + r->cmdqueue = cmd; + ret = R_TRUE; + } + return ret; +} + +R_API int r_core_prompt_exec(RCore *r) { + int ret = r_core_cmd (r, r->cmdqueue, R_TRUE); r_cons_flush (); return ret; } diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 6dab29b5a5..a1e5c6d28b 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -151,7 +151,7 @@ typedef struct r_anal_aop_t { int stackop; /* operation on stack? */ int cond; /* condition type */ int length; /* length in bytes of opcode */ - int nopcode; /* number of opcodes */ + int nopcode; /* number of bytes representing the opcode (not the arguments) */ int family; /* family of opcode */ int eob; /* end of block (boolean) */ ut64 jump; /* true jmp */ diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 01545a13a9..b3e2b89ee6 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -73,6 +73,7 @@ typedef struct r_core_t { RConfig *config; RSearch *search; RSign *sign; + char *cmdqueue; } RCore; #ifdef R_API @@ -81,7 +82,8 @@ R_API int r_core_init(struct r_core_t *core); R_API struct r_core_t *r_core_new(); R_API struct r_core_t *r_core_free(struct r_core_t *c); R_API int r_core_config_init(struct r_core_t *core); -R_API int r_core_prompt(struct r_core_t *r); +R_API int r_core_prompt(RCore *r, int sync); +R_API int r_core_prompt_exec(RCore *r); R_API int r_core_cmd(struct r_core_t *r, const char *cmd, int log); // XXX void*?? must be RCore ! R_API int r_core_cmdf(void *user, const char *fmt, ...); diff --git a/libr/include/r_th.h b/libr/include/r_th.h index cc8f17acad..d3ef26a6e2 100644 --- a/libr/include/r_th.h +++ b/libr/include/r_th.h @@ -34,7 +34,7 @@ typedef struct r_th_lock_t { typedef struct r_th_t { R_TH_TID tid; - struct r_th_lock_t *lock; + RThreadLock *lock; R_TH_FUNCTION(fun); void *user; // user pointer int running; @@ -45,24 +45,24 @@ typedef struct r_th_t { typedef struct r_th_pool_t { int size; - struct r_th_t **threads; + RThread **threads; } RThreadPool; #ifdef R_API -R_API struct r_th_t *r_th_new(R_TH_FUNCTION(fun), void *user, int delay); -R_API int r_th_start(struct r_th_t *th, int enable); -R_API int r_th_wait(struct r_th_t *th); -R_API int r_th_wait_async(struct r_th_t *th); -R_API void r_th_break(struct r_th_t *th); -R_API int r_th_wait(struct r_th_t *th); -R_API void *r_th_free(struct r_th_t *th); +R_API RThread *r_th_new(R_TH_FUNCTION(fun), void *user, int delay); +R_API int r_th_start(RThread *th, int enable); +R_API int r_th_wait(RThread *th); +R_API int r_th_wait_async(RThread *th); +R_API void r_th_break(RThread *th); +R_API int r_th_wait(RThread *th); +R_API void *r_th_free(RThread *th); -R_API struct r_th_lock_t *r_th_lock_new(); -R_API int r_th_lock_wait(struct r_th_lock_t *th); -R_API int r_th_lock_check(struct r_th_lock_t *thl); -R_API int r_th_lock_enter(struct r_th_lock_t *thl); -R_API int r_th_lock_leave(struct r_th_lock_t *thl); -R_API void *r_th_lock_free(struct r_th_lock_t *thl); +R_API RThreadLock *r_th_lock_new(); +R_API int r_th_lock_wait(RThreadLock *th); +R_API int r_th_lock_check(RThreadLock *thl); +R_API int r_th_lock_enter(RThreadLock *thl); +R_API int r_th_lock_leave(RThreadLock *thl); +R_API void *r_th_lock_free(RThreadLock *thl); #endif #endif diff --git a/libr/th/TODO b/libr/th/TODO index 5fdd6136a7..4e9dc00be1 100644 --- a/libr/th/TODO +++ b/libr/th/TODO @@ -1,6 +1,7 @@ R_TH :: TODO ============ +* implement non-threaded thread api (dummy one, when no support) * test w32 port * Implement a pure clone(2) backend * Added a threading pool super-api diff --git a/libr/th/t/test.c b/libr/th/t/test.c index aa096bf2b0..c61c0727d4 100644 --- a/libr/th/t/test.c +++ b/libr/th/t/test.c @@ -10,7 +10,7 @@ int looper(struct r_th_t *th) { printf ("%d loop %d\r", i, *ctr); fflush (stdout); #if __UNIX__ -sleep (1); + sleep (1); #endif } return 0; // do not loop diff --git a/libr/th/th.c b/libr/th/th.c index e220b68dc6..73a437ec50 100644 --- a/libr/th/th.c +++ b/libr/th/th.c @@ -91,10 +91,12 @@ R_API int r_th_start(struct r_th_t *th, int enable) { R_API int r_th_wait(struct r_th_t *th) { int ret = R_FALSE; -#if HAVE_PTHREAD void *thret; - ret = pthread_join (th->tid, &thret); - th->running = R_FALSE; +#if HAVE_PTHREAD + if (th) { + ret = pthread_join (th->tid, &thret); + th->running = R_FALSE; + } #endif return ret; }