* RCore now depends on RThread

- Loads rabin2 information in a background thread
  - Prompt is now much more responsive
  - Fix segfault in null pointered var in RThread
* rabin2 load strings only from data sections if found
* Split r_core_prompt/exec (make it cooperative-thread-friendly)
This commit is contained in:
pancake 2010-06-23 17:30:16 +02:00
parent f641df833b
commit 37c3e25664
10 changed files with 119 additions and 49 deletions

View File

@ -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

View File

@ -1,11 +1,13 @@
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
#include "r_core.h"
#include "r_io.h"
#include <r_core.h>
#include <r_th.h>
#include <r_io.h>
#include <stdio.h>
#include <getopt.h>
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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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, ...);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}