* More R_API-zation

* More stuff in doc/release
* Added 'dk' for sending signals to processes in the debugger
  - A bit hacky, but funny enought for testing
* Initial draft of the process-related API
  - For handling tree's of processes with threads
* Fix a bug in dietline ('supr' key is working now
This commit is contained in:
pancake 2009-04-01 22:44:43 +00:00
parent 936db0db87
commit 70186e1120
13 changed files with 200 additions and 81 deletions

3
TODO
View file

@ -2,12 +2,15 @@
* Add maxrows option for r_print (fix visual problem)
* Drop #if conditionals to use #ifdef ones
- fits better with plan9 compiler
- use getopt() p9-like macros
* Add test for config.c with _set_cb
* Rename __UNIX__ as __POSIX__
* Strip non input symbols in plugins (speed up loading)
* Specify binmask in hexpairs
- wx 1234:ff0f
- /x 1234:ff0f
* radare2 -e dbg.engine=vm -d ls
- resolve path for ls
- load the program using r_bin in virtual space

View file

@ -5,9 +5,10 @@ The objective of this paper is to determine a set of rules to be done before
each release and define the instructions for generating the distribution
tarball together with a scheduler.
* We try to release every 1/2 months
* Version numbering (actually we dont follow any rules for this)
* Codenames for releases MUST be funny (until we didnt get a name that can make
me laught, we should not release anything!)
Before any release we have to:
@ -28,3 +29,17 @@ Before any release we have to:
If available, it would be good to have some unit tests to check nothing is
broken. Maybe Vala is the way to go when writing tests, because this way
we ensure that pkg-config, libr and vapis works in a shot.
- Test build on different platforms
The same codebase should be compilable on *nix and w32 systems without
modifications. It should be also possible to build it with make threads,
so using quadcore boxes with -j8 should be a good place for finding
race conditions in the build system.
- Remove commented code and review TODO/BUG/XXX comments
While developing a new release, it's pretty common to keep old versions of
the code for testing parts of libraries and be able to go back or find bugs
while refactoring code or re-doing-it from scratch. This code, should be
reviewed and removed if necessary.

View file

@ -4,5 +4,6 @@ DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib r_macr
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o
CFLAGS+=-DLIBDIR=\"${PREFIX}/lib\"
CFLAGS+=-DPREFIX=\"${PREFIX}\"
include ../rules.mk

View file

@ -469,8 +469,6 @@ static int cmd_flag(void *data, const char *input)
break;
case 'o':
{
// XXX
#define PREFIX "/usr"
char *file = PREFIX"/share/doc/radare/fortunes";
char *line = r_file_slurp_random_line (file);
r_cons_printf("%s\n", line);
@ -1376,7 +1374,23 @@ int r_core_cmd_file(struct r_core_t *core, const char *file)
static int cmd_debug(void *data, const char *input)
{
struct r_core_t *core = (struct r_core_t *)data;
char *ptr;
switch(input[0]) {
case 'k':
{
/* XXX: not for threads? signal is for a whole process!! */
/* XXX: but we want fine-grained access to process resources */
int pid = 0;
int sig = 9;
pid = atoi(input);
ptr = strchr(input, ' ');
if (ptr) sig = atoi(ptr+1);
if (pid > 0) {
fprintf(stderr, "Sending signal '%d' to pid '%d'\n");
r_debug_kill(&core->dbg, pid, sig);
} else fprintf(stderr, "Invalid arguments\n");
}
break;
case 's':
fprintf(stderr, "step\n");
r_debug_step(&core->dbg, 1);
@ -1415,6 +1429,7 @@ static int cmd_debug(void *data, const char *input)
" ds 3 ; perform 3 steps\n"
" do 3 ; perform 3 steps overs\n"
" dp [pid] ; list or set pid\n"
" dt [tid] ; select thread id\n"
" dc ; continue execution\n"
" dr ; show registers\n"
" dr* ; show registers in radare commands\n"
@ -1425,7 +1440,8 @@ static int cmd_debug(void *data, const char *input)
" db -sym.main ; drop breakpoint\n"
" dm ; show memory maps\n"
" dm 4096 ; allocate 4KB in child process\n"
" dm rw- esp 9K; set 9KB of the stack as read+write (no exec)\n");
" dm rw- esp 9K; set 9KB of the stack as read+write (no exec)\n"
" dk pid sig ; send signal to a process ID\n");
break;
}
return 0;

View file

@ -2,14 +2,14 @@
#include <r_core.h>
u64 r_core_file_resize(struct r_core_t *core, u64 newsize)
R_API u64 r_core_file_resize(struct r_core_t *core, u64 newsize)
{
if (newsize == 0 && core->file)
return core->file->size;
return 0LL;
}
struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int mode)
R_API struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int mode)
{
struct r_core_file_t *fh;
int fd;
@ -40,20 +40,20 @@ struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int
return fh;
}
int r_core_file_set(struct r_core_t *r, struct r_core_file_t *fh)
R_API int r_core_file_set(struct r_core_t *r, struct r_core_file_t *fh)
{
r->file = fh;
return R_TRUE;
}
int r_core_file_close(struct r_core_t *r, struct r_core_file_t *fh)
R_API int r_core_file_close(struct r_core_t *r, struct r_core_file_t *fh)
{
int ret = r_io_close(&r->io, fh->fd);
list_del(&(fh->list));
return ret;
}
struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
R_API struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
{
struct list_head *pos;
list_for_each_prev(pos, &core->files) {
@ -64,7 +64,7 @@ struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
return NULL;
}
int r_core_file_close_fd(struct r_core_t *core, int fd)
R_API int r_core_file_close_fd(struct r_core_t *core, int fd)
{
int ret = r_io_close(&core->io, fd);
struct r_core_file_t *fh = r_core_file_get_fd(core, fd);

View file

@ -109,6 +109,7 @@ R_API int r_core_loadlibs_init(struct r_core_t *core)
R_API int r_core_loadlibs(struct r_core_t *core)
{
/* TODO: all those default plugin paths should be defined in r_lib */
char *homeplugindir = r_str_home(".radare/plugins");
static int singleton = R_TRUE;
if (singleton) {

View file

@ -1,4 +1,4 @@
NAME=r_debug
OBJ=debug.o handle.o
OBJ=debug.o handle.o pid.o
include ../rules.mk

View file

@ -2,7 +2,7 @@
#include <r_debug.h>
int r_debug_init(struct r_debug_t *dbg)
R_API int r_debug_init(struct r_debug_t *dbg)
{
dbg->pid = -1;
dbg->tid = -1;
@ -12,7 +12,7 @@ int r_debug_init(struct r_debug_t *dbg)
return R_TRUE;
}
struct r_debug_t *r_debug_new()
R_API struct r_debug_t *r_debug_new()
{
struct r_debug_t *dbg;
dbg = MALLOC_STRUCT(struct r_debug_t);
@ -20,7 +20,7 @@ struct r_debug_t *r_debug_new()
return dbg;
}
int r_debug_attach(struct r_debug_t *dbg, int pid)
R_API int r_debug_attach(struct r_debug_t *dbg, int pid)
{
int ret = R_FALSE;
if (dbg->h && dbg->h->attach) {
@ -33,24 +33,24 @@ int r_debug_attach(struct r_debug_t *dbg, int pid)
return ret;
}
int r_debug_startv(struct r_debug_t *dbg, int argc, char **argv)
R_API int r_debug_startv(struct r_debug_t *dbg, int argc, char **argv)
{
return R_FALSE;
}
int r_debug_start(struct r_debug_t *dbg, const char *cmd)
R_API int r_debug_start(struct r_debug_t *dbg, const char *cmd)
{
return R_FALSE;
}
int r_debug_detach(struct r_debug_t *dbg, int pid)
R_API int r_debug_detach(struct r_debug_t *dbg, int pid)
{
if (dbg->h && dbg->h->detach)
return dbg->h->detach(pid);
return R_FALSE;
}
int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
R_API int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
{
dbg->pid = pid;
dbg->tid = tid;
@ -58,7 +58,7 @@ int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
return R_TRUE;
}
int r_debug_set_arch(struct r_debug_t *dbg, int arch)
R_API int r_debug_set_arch(struct r_debug_t *dbg, int arch)
{
switch(arch) {
case R_DBG_ARCH_BF:
@ -72,7 +72,7 @@ int r_debug_set_arch(struct r_debug_t *dbg, int arch)
}
/*--*/
int r_debug_stop_reason(struct r_debug_t *dbg)
R_API int r_debug_stop_reason(struct r_debug_t *dbg)
{
// TODO: return reason to stop debugging
// - new process
@ -83,7 +83,7 @@ int r_debug_stop_reason(struct r_debug_t *dbg)
return R_TRUE;
}
int r_debug_wait(struct r_debug_t *dbg)
R_API int r_debug_wait(struct r_debug_t *dbg)
{
int ret = R_FALSE;
if (dbg->h->wait)
@ -92,7 +92,7 @@ int r_debug_wait(struct r_debug_t *dbg)
}
// TODO: count number of steps done to check if no error??
int r_debug_step(struct r_debug_t *dbg, int steps)
R_API int r_debug_step(struct r_debug_t *dbg, int steps)
{
int i, ret = R_FALSE;
if (dbg->h && dbg->h->step) {
@ -109,20 +109,20 @@ int r_debug_step(struct r_debug_t *dbg, int steps)
return ret;
}
int r_debug_syscall(struct r_debug_t *dbg, int num)
R_API int r_debug_syscall(struct r_debug_t *dbg, int num)
{
fprintf(stderr, "TODO\n");
return R_FALSE;
}
int r_debug_step_over(struct r_debug_t *dbg, int steps)
R_API int r_debug_step_over(struct r_debug_t *dbg, int steps)
{
// TODO: analyze opcode if it is stepoverable
fprintf(stderr, "TODO\n");
return r_debug_step(dbg, steps);
}
int r_debug_continue(struct r_debug_t *dbg)
R_API int r_debug_continue(struct r_debug_t *dbg)
{
int ret = R_FALSE;
if (dbg->h){
@ -135,12 +135,12 @@ int r_debug_continue(struct r_debug_t *dbg)
return ret;
}
int r_debug_continue_until(struct r_debug_t *dbg, u64 addr)
R_API int r_debug_continue_until(struct r_debug_t *dbg, u64 addr)
{
return -1;
}
int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
R_API int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
{
int ret = R_FALSE;
if (dbg->h && dbg->h->contsc)
@ -149,7 +149,7 @@ int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
}
// XXX wrong function name
int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
R_API int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
{
/* use software breakpoints and continues */
return -1;
@ -157,18 +157,18 @@ int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
/* registers */
int r_debug_register_get(struct r_debug_t *dbg, int reg, u64 *value)
R_API int r_debug_register_get(struct r_debug_t *dbg, int reg, u64 *value)
{
return R_TRUE;
}
int r_debug_register_set(struct r_debug_t *dbg, int reg, u64 value)
R_API int r_debug_register_set(struct r_debug_t *dbg, int reg, u64 value)
{
return R_TRUE;
}
/* for debugging purposes? */
int r_debug_register_list(struct r_debug_t *dbg)
R_API int r_debug_register_list(struct r_debug_t *dbg)
{
int i =0;
for(i=0;i<dbg->reg.nregs;i++) {
@ -179,14 +179,26 @@ int r_debug_register_list(struct r_debug_t *dbg)
return R_TRUE;
}
// TODO: Move to pid.c ?
// TODO: Do we need an intermediate signal representation for portability?
// TODO: STOP, CONTINUE, KILL, ...
R_API int r_debug_kill(struct r_debug_t *dbg, int pid, int sig)
{
// XXX: use debugger handler backend here
#include <signal.h>
int ret = kill(pid, sig);
if (ret == -1)
return R_FALSE;
return R_TRUE;
}
/* mmu */
int r_debug_mmu_alloc(struct r_debug_t *dbg, u64 size, u64 *addr)
R_API int r_debug_mmu_alloc(struct r_debug_t *dbg, u64 size, u64 *addr)
{
return R_TRUE;
}
int r_debug_mmu_free(struct r_debug_t *dbg, u64 addr)
R_API int r_debug_mmu_free(struct r_debug_t *dbg, u64 addr)
{
return R_TRUE;
}

43
libr/debug/pid.c Normal file
View file

@ -0,0 +1,43 @@
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
#include <r_debug.h>
R_API int r_debug_pid_list(struct r_debug_t *dbg)
{
int count = 0;
return 0;
}
/* processes */
R_API int r_debug_pid_add(struct r_debug_t *dbg)
{
return R_TRUE;
}
R_API int r_debug_pid_del(struct r_debug_t *dbg)
{
return R_TRUE;
}
/* threads */
R_API int r_debug_pid_add_thread(struct r_debug_t *dbg)
{
return R_TRUE;
}
R_API int r_debug_pid_del_thread(struct r_debug_t *dbg)
{
return R_TRUE;
}
/* status */
R_API int r_debug_pid_set_status(struct r_debug_t *dbg, int pid, int status)
{
return R_TRUE;
}
/* status */
R_API struct r_debug_pid_t *r_debug_pid_get(struct r_debug_t *dbg, int pid)
{
return NULL;
}

View file

@ -2,7 +2,7 @@
#include <r_flags.h>
const const char *r_flag_space_get(struct r_flag_t *f, int idx)
R_API const char *r_flag_space_get(struct r_flag_t *f, int idx)
{
if (idx==-1)
return "";
@ -24,7 +24,7 @@ void flag_space_init(struct r_flag_t *f)
}
#endif
void r_flag_space_set(struct r_flag_t *f, const char *name)
R_API void r_flag_space_set(struct r_flag_t *f, const char *name)
{
int i;
for(i=0;i<R_FLAG_SPACES_MAX;i++) {
@ -44,7 +44,7 @@ void r_flag_space_set(struct r_flag_t *f, const char *name)
}
}
void r_flag_space_list(struct r_flag_t *f)
R_API void r_flag_space_list(struct r_flag_t *f)
{
int i,j = 0;
for(i=0;i<R_FLAG_SPACES_MAX;i++) {

View file

@ -45,6 +45,28 @@ struct r_debug_t {
int (*write)(int pid, u64 addr, u8 *buf, int len);
struct r_debug_handle_t *h;
struct list_head handlers;
/* TODO
- list of processes and their threads
- list of mapped memory (from /proc/XX/maps)
- list of managed memory (allocated in child...)
*/
};
enum {
R_DBG_PROC_STOP,
R_DBG_PROC_RUN,
R_DBG_PROC_SLEEP,
R_DBG_PROC_ZOMBIE,
};
struct r_debug_pid_t {
int pid;
int status; /* stopped, running, zombie, sleeping ,... */
int runnable; /* when using 'run', 'continue', .. this proc will be runnable */
struct list_head threads;
struct list_head childs;
struct r_debug_pid_t *parent;
struct list_head list;
};
int r_debug_handle_add(struct r_debug_t *dbg, struct r_debug_handle_t *foo);
@ -52,6 +74,8 @@ int r_debug_handle_set(struct r_debug_t *dbg, const char *str);
int r_debug_handle_init(struct r_debug_t *dbg);
int r_debug_init(struct r_debug_t *dbg);
/* send signals */
int r_debug_kill(struct r_debug_t *dbg, int pid, int sig);
int r_debug_step(struct r_debug_t *dbg, int steps);
int r_debug_continue(struct r_debug_t *dbg);
int r_debug_select(struct r_debug_t *dbg, int pid, int tid);

View file

@ -30,8 +30,8 @@ extern int r_line_disable;
int r_line_init();
int r_line_hist_load(const char *file);
char *r_line_readline(int argc, const char **argv);
extern int r_line_readchar();
extern int r_line_hist_add(const char *line);
//extern int r_line_readchar();
R_API int r_line_hist_add(const char *line);
int r_line_hist_save(const char *file);
int r_line_hist_label(const char *label, void (*cb)(const char*));
void r_line_label_show();

View file

@ -39,7 +39,7 @@ int r_line_disable = 0; // TODO use fgets..no autocompletion
// char **rad_autocompletion(const char *text, int start, int end)
// return matches = rl_completion_matches (text, rad_offset_matches);
int r_line_readchar()
static int r_line_readchar()
{
char buf[2];
#if __WINDOWS__
@ -53,9 +53,8 @@ int r_line_readchar()
ret = ReadConsole(h, buf,1, &out, NULL);
if (!ret) {
// wine hack-around
if (read(0,buf,1) == 1)
return buf[0];
return -1;
if (read(0,buf,1) != 1)
return -1
}
SetConsoleMode(h, mode);
#else
@ -63,11 +62,13 @@ int r_line_readchar()
if (ret <1)
return -1;
#endif
//printf("CHAR(%d)\n", buf[0]);
return buf[0];
}
/* scripting */
/* TODO: remove label related stuff */
#if 0
#define BLOCK 4096
static char *labels = NULL;
@ -170,7 +171,7 @@ int r_line_hist_label(const char *label, void (*cb)(const char*))
return 1;
}
int r_line_hist_add(const char *line)
R_API int r_line_hist_add(const char *line)
{
#if HAVE_LIB_READLINE
add_history(line);
@ -185,7 +186,7 @@ int r_line_hist_add(const char *line)
//#endif
}
int r_line_hist_up()
static int r_line_hist_up()
{
if (r_line_histidx>0) {
strncpy(r_line_buffer, r_line_history[--r_line_histidx], R_LINE_BUFSIZE-1);
@ -196,7 +197,7 @@ int r_line_hist_up()
return 0;
}
int r_line_hist_down()
static int r_line_hist_down()
{
r_line_buffer_idx=0;
if (r_line_histidx<r_line_histsize) {
@ -213,7 +214,7 @@ int r_line_hist_down()
return 0;
}
int r_line_hist_list()
R_API int r_line_hist_list()
{
int i = 0;
@ -227,7 +228,7 @@ int r_line_hist_list()
return i;
}
int r_line_hist_free()
R_API int r_line_hist_free()
{
int i;
if (r_line_history != NULL)
@ -238,7 +239,8 @@ int r_line_hist_free()
return r_line_histidx=0, r_line_histsize;
}
void r_line_free()
/* TODO: we need an state..? */
R_API void r_line_free()
{
printf("Bye!\n");
r_line_hist_free();
@ -247,7 +249,7 @@ void r_line_free()
}
/* load history from file. if file == NULL load from ~/.<prg>.history or so */
int r_line_hist_load(const char *file)
R_API int r_line_hist_load(const char *file)
{
#if HAVE_LIB_READLINE
rad_readline_init();
@ -273,7 +275,7 @@ int r_line_hist_load(const char *file)
#endif
}
int r_line_hist_save(const char *file)
R_API int r_line_hist_save(const char *file)
{
#if HAVE_LIB_READLINE
rad_readline_finish();
@ -296,14 +298,14 @@ int r_line_hist_save(const char *file)
#endif
}
int r_line_hist_chop(const char *file, int limit)
R_API int r_line_hist_chop(const char *file, int limit)
{
/* TODO */
return 0;
}
/* initialize history stuff */
int r_line_init()
R_API int r_line_init()
{
#if HAVE_LIB_READLINE
rad_readline_init();
@ -324,8 +326,8 @@ int r_line_init()
return 1;
}
/* test */
int r_line_printchar()
/* TODO: Remove this test case .. this is not R_API */
static int r_line_printchar()
{
unsigned char buf[10];
@ -333,30 +335,30 @@ int r_line_printchar()
buf[0]=r_line_readchar();
switch(buf[0]) {
case 226:
case 197:
case 195:
case 194:
buf[0] = r_line_readchar();
printf("unicode-%02x-%02x\n", buf[0],buf[1]);
break;
case 8: // wtf is 127?
case 127: printf("backspace\n"); break;
case 32: printf("space\n"); break;
case 27:
read(0, buf, 5);
printf("esc-%02x-%02x-%02x-%02x\n",
buf[0],buf[1],buf[2],buf[3]);
break;
case 12: printf("^L\n"); break;
case 13: printf("intro\n"); break;
case 18: printf("^R\n"); break;
case 9: printf("tab\n"); break;
case 3: printf("control-c\n"); break;
case 0: printf("control-space\n"); break;
default:
printf("(code:%d)\n", buf[0]);
break;
case 226:
case 197:
case 195:
case 194:
buf[0] = r_line_readchar();
printf("unicode-%02x-%02x\n", buf[0],buf[1]);
break;
case 8: // wtf is 127?
case 127: printf("backspace\n"); break;
case 32: printf("space\n"); break;
case 27:
read(0, buf, 5);
printf("esc-%02x-%02x-%02x-%02x\n",
buf[0],buf[1],buf[2],buf[3]);
break;
case 12: printf("^L\n"); break;
case 13: printf("intro\n"); break;
case 18: printf("^R\n"); break;
case 9: printf("tab\n"); break;
case 3: printf("control-c\n"); break;
case 0: printf("control-space\n"); break;
default:
printf("(code:%d)\n", buf[0]);
break;
}
r_cons_set_raw(0);
@ -365,7 +367,7 @@ int r_line_printchar()
}
/* main readline function */
char *r_line_readline(int argc, const char **argv)
R_API char *r_line_readline(int argc, const char **argv)
{
int buf[10];
int i, len = 0;
@ -509,7 +511,9 @@ char *r_line_readline(int argc, const char **argv)
switch(buf[1]) {
case 0x33: // supr
if (r_line_buffer_idx<r_line_buffer_len)
strcpy(r_line_buffer, r_line_buffer+1);
strcpy(r_line_buffer+r_line_buffer_idx,
r_line_buffer+r_line_buffer_idx+1);
buf[1] = r_line_readchar();
break;
/* arrows */
case 0x41: