#ifndef _INCLUDE_R_DEBUG_H_ #define _INCLUDE_R_DEBUG_H_ #include #include #include #include #include #include #include #include "list.h" /* hack to fix compilation of debugger on BSD systems */ /* This needs some testing (netbsd, freebsd, openbsd, kfreebsd) */ #if __BSD__ #include #define PTRACE_PEEKTEXT PT_READ_I #define PTRACE_POKETEXT PT_WRITE_I #define PTRACE_PEEKDATA PT_READ_D #define PTRACE_POKEDATA PT_WRITE_D #define PTRACE_ATTACH PT_ATTACH #define PTRACE_DETACH PT_DETACH #define PTRACE_SINGLESTEP PT_STEP #define PTRACE_CONT PT_CONTINUE #define PTRACE_GETREGS PT_GETREGS #define PTRACE_SETREGS PT_SETREGS #define PTRACE_SYSCALL PT_STEP #endif enum { R_DBG_PROC_STOP = 's', R_DBG_PROC_RUN = 'r', R_DBG_PROC_SLEEP = 'S', R_DBG_PROC_ZOMBIE = 'z', R_DBG_PROC_DEAD = 'd', R_DBG_PROC_RAISED = 'R' // has produced a signal, breakpoint, etc.. }; // signal handling must support application and debugger level options enum { R_DBG_SIGNAL_IGNORE, // ignore signal handler R_DBG_SIGNAL_BYPASS, R_DBG_SIGNAL_HANDLE, // R_DBG_SIGNAL_SETUP, //.. }; enum { // TODO: not yet used by r_debug R_DBG_REASON_DEAD = -1, R_DBG_REASON_UNKNOWN, R_DBG_REASON_NEW_PID, R_DBG_REASON_NEW_TID, R_DBG_REASON_NEW_LIB, R_DBG_REASON_EXIT_PID, R_DBG_REASON_EXIT_TID, R_DBG_REASON_EXIT_LIB, R_DBG_REASON_TRAP, R_DBG_REASON_ILL, R_DBG_REASON_INT, R_DBG_REASON_SIGNAL, R_DBG_REASON_FPU, R_DBG_REASON_BP, }; /* TODO: move to r_anal */ typedef struct r_debug_frame_t { ut64 addr; int size; } RDebugFrame; typedef struct r_debug_map_t { char *name; ut64 addr; ut64 addr_end; ut64 size; char *file; int perm; int user; } RDebugMap; typedef struct r_debug_trace_t { RList *traces; int count; int enabled; //int changed; int tag; int dup; char *addresses; // TODO: add range here } RDebugTrace; typedef struct r_debug_tracepoint_t { ut64 addr; ut64 tags; // XXX int tag; // XXX int size; int count; int times; ut64 stamp; } RDebugTracepoint; typedef struct r_debug_t { int arch; int bits; /// XXX: MUST SET /// int pid; /* selected process id */ int tid; /* selected thread id */ int swstep; /* steps with software traps */ int steps; /* counter of steps done */ int newstate; int reason; /* stop reason */ RDebugTrace *trace; int stop_all_threads; struct r_reg_t *reg; RBreakpoint *bp; void *user; /* io */ PrintfCallback printf; struct r_debug_plugin_t *h; struct list_head plugins; RAnal *anal; RIOBind iob; RList *maps; // RList *maps_user; // /* TODO - list of processes and their threads - list of mapped memory (from /proc/XX/maps) - list of managed memory (allocated in child...) */ } RDebug; typedef struct r_debug_desc_plugin_t { int (*open)(const char *path); int (*close)(int fd); int (*read)(int fd, ut64 addr, int len); int (*write)(int fd, ut64 addr, int len); int (*seek)(int fd, ut64 addr); int (*dup)(int fd, int newfd); RList* (*list)(); } RDebugDescPlugin; /* TODO: pass dbg and user data pointer everywhere */ typedef struct r_debug_plugin_t { const char *name; //const char **archs; // MUST BE DEPREACTED!!!! ut32 bits; ut64 arch; /* life */ int (*startv)(int argc, char **argv); int (*attach)(RDebug *dbg, int pid); int (*detach)(int pid); int (*select)(int pid, int tid); RList *(*threads)(int pid); RList *(*pids)(int pid); RList *(*tids)(int pid); RFList (*backtrace)(int count); /* flow */ int (*step)(RDebug *dbg); int (*cont)(RDebug *dbg, int pid, int tid, int sig); int (*wait)(int pid); int (*kill)(RDebug *dbg, boolt thread, int sig); int (*contsc)(RDebug *dbg, int pid, int sc); RList* (*frames)(RDebug *dbg); RBreakpointCallback breakpoint; // XXX: specify, pid, tid, or RDebug ? int (*reg_read)(struct r_debug_t *dbg, int type, ut8 *buf, int size); int (*reg_write)(int pid, int tid, int type, const ut8 *buf, int size); //XXX struct r_regset_t regs); char* (*reg_profile)(RDebug *dbg); /* memory */ RList *(*map_get)(RDebug *dbg); ut64 (*map_alloc)(RDebug *dbg, RDebugMap *map); int (*map_dealloc)(RDebug *dbg, ut64 addr); int (*init)(RDebug *dbg); RDebugDescPlugin desc; // TODO: use RList here struct list_head list; } RDebugPlugin; // TODO: rename to r_debug_process_t ? maybe a thread too ? typedef struct r_debug_pid_t { int pid; char status; /* stopped, running, zombie, sleeping ,... */ int runnable; /* when using 'run', 'continue', .. this proc will be runnable */ const char *path; ut64 pc; } RDebugPid; #ifdef R_API R_API int r_debug_attach(struct r_debug_t *dbg, int pid); R_API int r_debug_detach(struct r_debug_t *dbg, int pid); R_API int r_debug_startv(struct r_debug_t *dbg, int argc, char **argv); R_API int r_debug_start(struct r_debug_t *dbg, const char *cmd); R_API int r_debug_stop_reason(struct r_debug_t *dbg); R_API int r_debug_wait(struct r_debug_t *dbg); R_API int r_debug_step_over(struct r_debug_t *dbg, int steps); R_API int r_debug_continue_until(struct r_debug_t *dbg, ut64 addr); R_API int r_debug_continue_until_optype(RDebug *dbg, int type, int over); R_API int r_debug_continue_until_nontraced(RDebug *dbg); R_API int r_debug_continue_syscall(struct r_debug_t *dbg, int sc); //R_API int r_debug_pid_add(struct r_debug_t *dbg); //R_API int r_debug_pid_add_thread(struct r_debug_t *dbg); //R_API int r_debug_pid_del(struct r_debug_t *dbg); //R_API int r_debug_pid_del_thread(struct r_debug_t *dbg); R_API int r_debug_pid_list(RDebug *dbg, int pid); R_API RDebugPid *r_debug_pid_new(const char *path, int pid, char status, ut64 pc); R_API RDebugPid *r_debug_pid_free(RDebugPid *pid); R_API RList *r_debug_pids(RDebug *dbg, int pid); R_API int r_debug_set_arch(RDebug *dbg, int arch, int bits); R_API int r_debug_use(struct r_debug_t *dbg, const char *str); R_API int r_debug_plugin_add(struct r_debug_t *dbg, struct r_debug_plugin_t *foo); R_API int r_debug_plugin_init(struct r_debug_t *dbg); R_API int r_debug_plugin_list(struct r_debug_t *dbg); R_API struct r_debug_t *r_debug_new(int hard); R_API struct r_debug_t *r_debug_free(struct r_debug_t *dbg); /* send signals */ R_API int r_debug_kill(struct r_debug_t *dbg, boolt thread, int sig); // XXX: must be uint64 action R_API int r_debug_kill_setup(struct r_debug_t *dbg, int sig, int action); R_API int r_debug_step(struct r_debug_t *dbg, int steps); R_API int r_debug_continue(struct r_debug_t *dbg); R_API int r_debug_continue_kill(struct r_debug_t *dbg, int signal); R_API int r_debug_select(struct r_debug_t *dbg, int pid, int tid); /* handle.c */ R_API int r_debug_plugin_init(struct r_debug_t *dbg); R_API int r_debug_plugin_set(struct r_debug_t *dbg, const char *str); R_API int r_debug_plugin_list(struct r_debug_t *dbg); R_API int r_debug_plugin_add(struct r_debug_t *dbg, struct r_debug_plugin_t *foo); /* memory */ R_API int r_debug_map_alloc(RDebug *dbg, RDebugMap *map); R_API int r_debug_map_dealloc(RDebug *dbg, RDebugMap *map); R_API RList *r_debug_map_list_new(); R_API void r_debug_map_list_free(RList *maps); R_API RDebugMap *r_debug_map_get(RDebug *dbg, ut64 addr); R_API RDebugMap *r_debug_map_new (char *name, ut64 addr, ut64 addr_end, int perm, int user); R_API void r_debug_map_free(RDebugMap *map); R_API void r_debug_map_list(RDebug *dbg, ut64 addr); /* descriptors */ R_API int r_debug_desc_open(RDebug *dbg, const char *path); R_API int r_debug_desc_close(RDebug *dbg, int fd); R_API int r_debug_desc_dup(RDebug *dbg, int fd, int newfd); R_API int r_debug_desc_read(RDebug *dbg, int fd, ut64 addr, int len); R_API int r_debug_desc_seek(RDebug *dbg, int fd, ut64 addr); // TODO: whence? R_API int r_debug_desc_write(RDebug *dbg, int fd, ut64 addr, int len); R_API int r_debug_desc_list(RDebug *dbg, int rad); /* registers */ R_API int r_debug_reg_sync(RDebug *dbg, int type, int write); R_API int r_debug_reg_list(RDebug *dbg, int type, int size, int rad); R_API int r_debug_reg_set(RDebug *dbg, const char *name, ut64 num); R_API ut64 r_debug_reg_get(RDebug *dbg, const char *name); R_API void r_debug_io_bind(RDebug *dbg, RIO *io); R_API ut64 r_debug_execute(struct r_debug_t *dbg, ut8 *buf, int len); R_API int r_debug_map_sync(RDebug *dbg); /* backtrace */ R_API RList *r_debug_frames (RDebug *dbg); R_API int r_debug_is_dead (RDebug *dbg); /* args XXX: weird food */ R_API ut64 r_debug_arg_get (RDebug *dbg, int fast, int num); R_API int r_debug_arg_set (RDebug *dbg, int fast, int num, ut64 value); /* pid */ R_API int r_debug_pid_list(struct r_debug_t *dbg, int pid); R_API int r_debug_thread_list(struct r_debug_t *dbg, int pid); R_API void r_debug_trace_reset (RDebug *dbg); R_API int r_debug_trace_pc (RDebug *dbg); R_API void r_debug_trace_at (RDebug *dbg, const char *str); R_API RDebugTracepoint *r_debug_trace_get (RDebug *dbg, ut64 addr); R_API void r_debug_trace_list (RDebug *dbg, int mode); R_API RDebugTracepoint *r_debug_trace_add (RDebug *dbg, ut64 addr, int size); R_API RDebugTrace *r_debug_trace_new (); R_API void r_debug_trace_free (RDebug *dbg); R_API int r_debug_trace_tag (RDebug *dbg, int tag); R_API int r_debug_fork (RDebug *dbg); R_API int r_debug_clone (RDebug *dbg); #endif #endif /* regset */ //R_API struct r_regset_t* r_regset_diff(struct r_regset_t *a, struct r_regset_t *b); //R_API int r_regset_set(struct r_regset_t *r, int idx, const char *name, ut64 value); //R_API struct r_regset_t *r_regset_new(int size); //R_API void r_regset_free(struct r_regset_t *r); #if 0 Missing callbacks ================= - alloc - dealloc - list maps (memory regions) - change memory protections - touchtrace - filedescriptor set/get/mod.. - get/set signals - get regs, set regs #endif