mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-19 12:22:43 +00:00
* 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:
parent
f641df833b
commit
37c3e25664
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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, ...);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user