Implement Po& and r2 -tp to load projects in a thread

This commit is contained in:
pancake 2016-11-04 23:07:02 +01:00
parent 36085eb03d
commit 9c57ff07a6
6 changed files with 100 additions and 46 deletions

View File

@ -13,8 +13,8 @@
#if USE_THREADS
#include <r_th.h>
static char *rabin_cmd = NULL;
static int threaded = 0;
#endif
static bool threaded = false;
static struct r_core_t r;
static int verify_version(int show) {
@ -343,7 +343,6 @@ int main(int argc, char **argv, char **envp) {
RCoreFile *fh = NULL;
const char *patchfile = NULL;
const char *prj = NULL;
//int threaded = false;
int debug = 0;
int zflag = 0;
int do_analysis = 0;
@ -809,7 +808,8 @@ int main(int argc, char **argv, char **envp) {
pfile = r_core_project_info (&r, prj);
if (pfile) {
fh = r_core_file_open (&r, pfile, perms, mapaddr);
r_core_project_open (&r, prj);
// run_anal = 0;
run_anal = -1;
} else {
eprintf ("Cannot find project file\n");
}
@ -847,8 +847,9 @@ int main(int argc, char **argv, char **envp) {
// rabin_delegate (NULL);
} // else eprintf ("Metadata loaded from 'prj.name'\n");
#endif
if (mapaddr)
if (mapaddr) {
r_core_seek (&r, mapaddr, 1);
}
r_list_foreach (evals, iter, cmdn) {
r_config_eval (r.config, cmdn);
@ -897,7 +898,7 @@ int main(int argc, char **argv, char **envp) {
const char *npath, *nsha1;
char *path = strdup (r_config_get (r.config, "file.path"));
char *sha1 = strdup (r_config_get (r.config, "file.sha1"));
has_project = r_core_project_open (&r, r_config_get (r.config, "prj.name"));
has_project = r_core_project_open (&r, r_config_get (r.config, "prj.name"), threaded);
if (has_project) {
r_config_set (r.config, "bin.strings", "false");
}
@ -997,7 +998,9 @@ int main(int argc, char **argv, char **envp) {
r_core_patch (&r, data);
r_core_seek (&r, 0, 1);
free (data);
} else eprintf ("Cannot open '%s'\n", patchfile);
} else {
eprintf ("Cannot open '%s'\n", patchfile);
}
}
if ((patchfile && !quiet) || !patchfile) {
if (zerosep)

View File

@ -14,8 +14,16 @@ static int cmd_project(void *data, const char *input) {
return false;
}
str = strdup (fileproject);
if (arg && *arg==' ') arg++;
file = (input[0] && input[1])? arg: str;
arg = strchr (input, ' ');
if (arg) {
arg++;
} else {
arg = input + 1;
if (*arg == '&') {
arg++;
}
}
file = arg;
switch (input[0]) {
case 'c':
if (input[1]==' ') {
@ -26,8 +34,10 @@ static int cmd_project(void *data, const char *input) {
break;
case 'o':
// if (r_file_is_regular (file))
if (input[1]) {
r_core_project_open (core, file);
if (input[1] == '&') {
r_core_project_open (core, file, true);
} else if (input[1]) {
r_core_project_open (core, file, false);
} else {
if (file && *file) {
r_cons_println (file);

View File

@ -278,21 +278,55 @@ static bool r_core_rop_load(RCore *core, const char *prjfile) {
}
R_API bool r_core_project_load(RCore *core, const char *prjName, const char *rcpath) {
const bool cfg_fortunes = r_config_get_i (core->config, "cfg.fortunes");
const bool scr_interactive = r_config_get_i (core->config, "scr.interactive");
const bool scr_prompt = r_config_get_i (core->config, "scr.prompt");
(void)r_core_rop_load (core, prjName);
(void)r_core_project_load_xrefs (core, prjName);
return r_core_cmd_file (core, rcpath);
bool ret = r_core_cmd_file (core, rcpath);
r_config_set_i (core->config, "cfg.fortunes", cfg_fortunes);
r_config_set_i (core->config, "scr.interactive", scr_interactive);
r_config_set_i (core->config, "scr.prompt", scr_prompt);
r_config_bump (core->config, "asm.arch");
return ret;
}
R_API int r_core_project_open(RCore *core, const char *prjfile) {
/*** vvv thready ***/
typedef struct {
RCore *core;
char *prjName;
char *rcPath;
} ProjectState;
static int prjloadbg(RThread *th) {
ProjectState *ps = th->user;
r_core_project_load (ps->core, ps->prjName, ps->rcPath);
free (ps->prjName);
free (ps->rcPath);
free (ps);
return 0;
}
R_API RThread *r_core_project_load_bg(RCore *core, const char *prjName, const char *rcPath) {
ProjectState *ps = R_NEW (ProjectState);
ps->core = core;
ps->prjName = strdup (prjName);
ps->rcPath = strdup (rcPath);
RThread* th = r_th_new (prjloadbg, ps, false);
r_th_start (th, true);
return th;
}
/*** ^^^ thready ***/
R_API int r_core_project_open(RCore *core, const char *prjfile, bool thready) {
int askuser = 1;
int ret, close_current_session = 1;
char *prj, *filepath;
if (!prjfile || !*prjfile) {
return false;
}
const bool cfg_fortunes = r_config_get_i (core->config, "cfg.fortunes");
const bool scr_interactive = r_config_get_i (core->config, "scr.interactive");
const bool scr_prompt = r_config_get_i (core->config, "scr.prompt");
prj = r_core_project_file (core, prjfile);
if (!prj) {
eprintf ("Invalid project name '%s'\n", prjfile);
@ -351,12 +385,13 @@ R_API int r_core_project_open(RCore *core, const char *prjfile) {
// TODO: handle base address
r_core_bin_load (core, filepath, UT64_MAX);
}
/* load sdb stuff in here */
ret = r_core_project_load (core, prjfile, prj);
r_config_set_i (core->config, "cfg.fortunes", cfg_fortunes);
r_config_set_i (core->config, "scr.interactive", scr_interactive);
r_config_set_i (core->config, "scr.prompt", scr_prompt);
r_config_bump (core->config, "asm.arch");
if (thready) {
(void)r_core_project_load_bg (core, prjfile, prj);
return true;
} else {
/* load sdb stuff in here */
ret = r_core_project_load (core, prjfile, prj);
}
free (filepath);
free (prj);
return ret;

View File

@ -294,6 +294,7 @@ R_API void r_core_debug_rr (RCore *core, RReg *reg);
/* project */
R_API bool r_core_project_load(RCore *core, const char *prjfile, const char *rcfile);
R_API RThread *r_core_project_load_bg(RCore *core, const char *prjfile, const char *rcfile);
#define R_CORE_FOREIGN_ADDR -1
R_API int r_core_yank(RCore *core, ut64 addr, int len);
@ -414,7 +415,7 @@ R_API int r_core_pseudo_code (RCore *core, const char *input);
R_API int r_core_gdiff(RCore *core1, RCore *core2);
R_API int r_core_gdiff_fcn(RCore *c, ut64 addr, ut64 addr2);
R_API int r_core_project_open(RCore *core, const char *file);
R_API int r_core_project_open(RCore *core, const char *file, bool thready);
R_API int r_core_project_cat(RCore *core, const char *name);
R_API int r_core_project_delete(RCore *core, const char *prjfile);
R_API int r_core_project_list(RCore *core, int mode);

View File

@ -51,12 +51,12 @@ typedef struct r_th_pool_t {
#ifdef R_API
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 bool 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 void *r_th_free(RThread *th);
R_API int r_th_kill(struct r_th_t *th, int force);
R_API int r_th_kill(RThread *th, int force);
R_API RThreadLock *r_th_lock_new(void);
R_API int r_th_lock_wait(RThreadLock *th);

View File

@ -1,28 +1,31 @@
/* radare - LGPL - Copyright 2009-2012 - pancake */
/* radare - LGPL - Copyright 2009-2016 - pancake */
#include <r_th.h>
static void *_r_th_launcher(void *_th) {
int ret;
struct r_th_t *th = _th;
RThread *th = _th;
th->ready = true;
#if __UNIX__
if (th->delay>0) sleep(th->delay);
else if (th->delay<0) r_th_lock_wait(th->lock);
if (th->delay > 0) {
sleep (th->delay);
} else if (th->delay < 0) {
r_th_lock_wait (th->lock);
}
#else
if (th->delay<0) r_th_lock_wait(th->lock);
if (th->delay < 0) {
r_th_lock_wait (th->lock);
}
#endif
do {
r_th_lock_leave(th->lock);
r_th_lock_leave (th->lock);
th->running = true;
ret = th->fun(th);
ret = th->fun (th);
th->running = false;
r_th_lock_enter(th->lock);
} while(ret);
r_th_lock_enter (th->lock);
} while (ret);
#if HAVE_PTHREAD
pthread_exit(&ret);
pthread_exit (&ret);
#endif
return 0;
}
@ -30,14 +33,14 @@ static void *_r_th_launcher(void *_th) {
R_API int r_th_push_task(struct r_th_t *th, void *user) {
int ret = true;
th->user = user;
r_th_lock_leave(th->lock);
r_th_lock_leave (th->lock);
return ret;
}
R_API struct r_th_t *r_th_new(R_TH_FUNCTION(fun), void *user, int delay) {
R_API RThread *r_th_new(R_TH_FUNCTION(fun), void *user, int delay) {
RThread *th = R_NEW0 (RThread);
if (th) {
th->lock = r_th_lock_new();
th->lock = r_th_lock_new ();
th->running = false;
th->fun = fun;
th->user = user;
@ -45,19 +48,19 @@ R_API struct r_th_t *r_th_new(R_TH_FUNCTION(fun), void *user, int delay) {
th->breaked = false;
th->ready = false;
#if HAVE_PTHREAD
pthread_create(&th->tid, NULL, _r_th_launcher, th);
pthread_create (&th->tid, NULL, _r_th_launcher, th);
#elif __WIN32__ || __WINDOWS__ && !defined(__CYGWIN__)
th->tid = CreateThread(NULL, 0, _r_th_launcher, th, 0, &th->tid);
th->tid = CreateThread (NULL, 0, _r_th_launcher, th, 0, &th->tid);
#endif
}
return th;
}
R_API void r_th_break(struct r_th_t *th) {
R_API void r_th_break(RThread *th) {
th->breaked = true;
}
R_API int r_th_kill(struct r_th_t *th, int force) {
R_API int r_th_kill(RThread *th, int force) {
th->breaked = true;
r_th_break(th);
r_th_wait(th);
@ -71,12 +74,14 @@ R_API int r_th_kill(struct r_th_t *th, int force) {
return 0;
}
R_API int r_th_start(struct r_th_t *th, int enable) {
int ret = true;
R_API bool r_th_start(RThread *th, int enable) {
bool ret = true;
if (enable) {
if (!th->running) {
// start thread
while (!th->ready);
while (!th->ready) {
/* spinlock */
}
r_th_lock_leave (th->lock);
}
} else {