From bc2c79ee8df8fafd4f2937c8c945e625e41c0853 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 30 Jun 2010 01:13:09 +0200 Subject: [PATCH] * Use RList in r_bp - vapi updated * Generalize the use of PrintfCallback typedef - used in r_bp and handled by r_cons in r_core --- TODO | 9 ++++--- libr/bp/bp.c | 60 +++++++++++++++++++----------------------- libr/bp/io.c | 20 ++++++-------- libr/bp/plugin.c | 38 ++++++++++++-------------- libr/bp/traptrace.c | 33 +++++++++++------------ libr/core/cmd.c | 2 +- libr/core/core.c | 3 ++- libr/core/io.c | 2 +- libr/include/r_bp.h | 23 ++++++++-------- libr/include/r_debug.h | 6 ++--- libr/include/r_sign.h | 2 +- libr/include/r_types.h | 2 +- libr/sign/README | 2 ++ libr/sign/sign.c | 2 +- swig/vapi/r_bp.vapi | 4 ++- 15 files changed, 100 insertions(+), 108 deletions(-) diff --git a/TODO b/TODO index 41851643fc..1a47325cd3 100644 --- a/TODO +++ b/TODO @@ -14,6 +14,7 @@ Questions: * imports from PE doesnt works with /a because there's an indirect call * rabin2 doesnt works for osx-x86 mach0 bins..so io.va=1 fails * Store version information in libraries ? debian claims for it +* Load symbol information from libraries (only the ones imported by rabin2?) Bugs: ----- @@ -27,13 +28,15 @@ Bugs: TODO: ----- +* port r_sign to RList +* pancake: implement callback for conditional breakpoints * nibble: trace counts after step..thats not correct! * implement grep{col,row} * nibble: mach0 new binary format is not supported by bin_mach0 :( * Implement r_sys_setenv stuff from r1 in core/file.c:33 (!!?) -* pancake: Implement search.align -* Handle metadata from disassembler (structs, hexdump, ...) - - r_meta_print (RMeta, RMetaItem, RPrint); +################ * pancake: Implement search.align +################ * Handle metadata from disassembler (structs, hexdump, ...) +################ - r_meta_print (RMeta, RMetaItem, RPrint); * pancake: FileDescriptors: dd -- copy from !fd in r1 * pancake: we need an api to define function signatures - arg/var set name/get value/ .. diff --git a/libr/bp/bp.c b/libr/bp/bp.c index dc3675f9e5..9fba73f4a8 100644 --- a/libr/bp/bp.c +++ b/libr/bp/bp.c @@ -7,12 +7,10 @@ static struct r_bp_plugin_t *bp_static_plugins[] = { R_BP_STATIC_PLUGINS }; R_API RBreakpoint *r_bp_new() { - RBreakpoint *bp; RBreakpointPlugin *static_plugin; - int i; - - bp = R_NEW (RBreakpoint); + RBreakpoint *bp = R_NEW (RBreakpoint); if (bp) { + int i; bp->cur = NULL; bp->nbps = 0; bp->trace_bp = R_FALSE; @@ -20,14 +18,15 @@ R_API RBreakpoint *r_bp_new() { bp->breakpoint = NULL; bp->endian = 0; // little by default bp->traces = r_bp_traptrace_new (); - INIT_LIST_HEAD (&bp->bps); - INIT_LIST_HEAD (&bp->plugins); + bp->printf = (PrintfCallback)printf; + bp->bps = r_list_new (); + bp->plugins = r_list_new (); for (i=0; bp_static_plugins[i]; i++) { static_plugin = R_NEW (RBreakpointPlugin); memcpy (static_plugin, bp_static_plugins[i], sizeof (RBreakpointPlugin)); r_bp_plugin_add (bp, static_plugin); } - memset (&bp->iob, 0, sizeof(bp->iob)); + memset (&bp->iob, 0, sizeof (bp->iob)); } return bp; } @@ -58,9 +57,9 @@ R_API int r_bp_get_bytes(RBreakpoint *bp, ut8 *buf, int len, int endian, int idx } R_API RBreakpointItem *r_bp_at_addr(RBreakpoint *bp, ut64 addr, int rwx) { - struct list_head *pos; - list_for_each(pos, &bp->bps) { - RBreakpointItem *b = list_entry (pos, RBreakpointItem, list); + RListIter *iter; + RBreakpointItem *b; + r_list_foreach(bp->bps, iter, b) { // eprintf ("---ataddr--- 0x%08"PFMT64x" %d %d\n", b->addr, b->size, b->recoil); if (addr>=b->addr && addr<=b->addr+b->size && rwx&b->rwx) return b; @@ -69,10 +68,9 @@ R_API RBreakpointItem *r_bp_at_addr(RBreakpoint *bp, ut64 addr, int rwx) { } R_API struct r_bp_item_t *r_bp_enable(RBreakpoint *bp, ut64 addr, int set) { - struct list_head *pos; - struct r_bp_item_t *b; - list_for_each(pos, &bp->bps) { - b = list_entry(pos, struct r_bp_item_t, list); + RListIter *iter; + RBreakpointItem *b; + r_list_foreach(bp->bps, iter, b) { if (addr >= b->addr && addr <= b->addr+b->size) { b->enabled = set; return b; @@ -89,7 +87,7 @@ R_API int r_bp_stepy_continuation(RBreakpoint *bp) { /* TODO: detect overlapping of breakpoints */ static RBreakpointItem *r_bp_add(RBreakpoint *bp, const ut8 *obytes, ut64 addr, int size, int hw, int rwx) { int ret; - struct r_bp_item_t *b; + RBreakpointItem *b; if (r_bp_at_addr (bp, addr, rwx)) { eprintf ("Breakpoint already set at this address.\n"); return NULL; @@ -109,7 +107,7 @@ static RBreakpointItem *r_bp_add(RBreakpoint *bp, const ut8 *obytes, ut64 addr, } else { b->bbytes = malloc (size+16); if (obytes) { - b->obytes = malloc(size); + b->obytes = malloc (size); memcpy (b->obytes, obytes, size); } else b->obytes = NULL; /* XXX: endian .. use bp->endian */ @@ -126,7 +124,7 @@ static RBreakpointItem *r_bp_add(RBreakpoint *bp, const ut8 *obytes, ut64 addr, } bp->nbps++; - list_add_tail (&(b->list), &bp->bps); + r_list_append (bp->bps, b); return b; } @@ -136,7 +134,7 @@ R_API int r_bp_add_fault(RBreakpoint *bp, ut64 addr, int size, int rwx) { } R_API struct r_bp_item_t *r_bp_add_sw(RBreakpoint *bp, ut64 addr, int size, int rwx) { - struct r_bp_item_t *item; + RBreakpointItem *item; ut8 *bytes; if (size<1) size = 1; @@ -156,12 +154,11 @@ R_API struct r_bp_item_t *r_bp_add_hw(RBreakpoint *bp, ut64 addr, int size, int } R_API int r_bp_del(RBreakpoint *bp, ut64 addr) { - struct list_head *pos; - struct r_bp_item_t *b; - list_for_each (pos, &bp->bps) { - b = list_entry (pos, struct r_bp_item_t, list); + RListIter *iter; + RBreakpointItem *b; + r_list_foreach (bp->bps, iter, b) { if (b->addr == addr) { - list_del (&b->list); + r_list_delete (bp->bps, iter); return R_TRUE; } } @@ -172,10 +169,9 @@ R_API int r_bp_del(RBreakpoint *bp, ut64 addr) { // TODO: use a r_bp_item instead of address // TODO: we can just drop it.. its just b->trace = R_TRUE or so.. R_API int r_bp_set_trace(RBreakpoint *bp, ut64 addr, int set) { - struct list_head *pos; - struct r_bp_item_t *b; - list_for_each (pos, &bp->bps) { - b = list_entry (pos, struct r_bp_item_t, list); + RListIter *iter; + RBreakpointItem *b; + r_list_foreach (bp->bps, iter, b) { if (addr >= b->addr && addr <= b->addr+b->size) { b->trace = set; return R_TRUE; @@ -197,13 +193,11 @@ R_API int r_bp_set_trace_bp(RBreakpoint *bp, ut64 addr, int set) // TODO: deprecate R_API int r_bp_list(RBreakpoint *bp, int rad) { int n = 0; - struct r_bp_item_t *b; - struct list_head *pos; - + RBreakpointItem *b; + RListIter *iter; eprintf ("Breakpoint list:\n"); - list_for_each (pos, &bp->bps) { - b = list_entry (pos, struct r_bp_item_t, list); - printf ("0x%08"PFMT64x" - 0x%08"PFMT64x" %d %c%c%c %s %s %s\n", + r_list_foreach (bp->bps, iter, b) { + bp->printf ("0x%08"PFMT64x" - 0x%08"PFMT64x" %d %c%c%c %s %s %s\n", b->addr, b->addr+b->size, b->size, (b->rwx & R_BP_PROT_READ)?'r':'-', (b->rwx & R_BP_PROT_WRITE)?'w':'-', diff --git a/libr/bp/io.c b/libr/bp/io.c index 4913672893..f8e700ef83 100644 --- a/libr/bp/io.c +++ b/libr/bp/io.c @@ -55,23 +55,20 @@ R_API int r_debug_bp_add(struct r_debug_t *dbg, ut64 addr, int size, int hw, int * reflect all r_bp stuff in the process using dbg->bp_write */ // XXX remove -R_API int r_bp_restore(struct r_bp_t *bp, int set) -{ - struct list_head *pos; - struct r_bp_item_t *b; +R_API int r_bp_restore(struct r_bp_t *bp, int set) { + RListIter *iter; + RBreakpointItem *b; /* write obytes from every breakpoint in r_bp */ if (set) { - list_for_each(pos, &bp->bps) { - b = list_entry(pos, struct r_bp_item_t, list); + r_list_foreach (bp->bps, iter, b) { if (b->hw || !b->obytes) eprintf ("hw breakpoints not supported yet\n"); else bp->iob.write_at (bp->iob.io, b->addr, b->obytes, b->size); // TODO: CALL TO bp->breakpoint() } } else { - list_for_each(pos, &bp->bps) { - b = list_entry(pos, struct r_bp_item_t, list); + r_list_foreach (bp->bps, iter, b) { if (b->hw || !b->bbytes) eprintf ("hw breakpoints not supported yet\n"); else bp->iob.write_at (bp->iob.io, b->addr, b->bbytes, b->size); @@ -81,15 +78,14 @@ R_API int r_bp_restore(struct r_bp_t *bp, int set) return R_TRUE; } -R_API int r_bp_recoil(RBreakpoint *bp, ut64 addr) -{ +R_API int r_bp_recoil(RBreakpoint *bp, ut64 addr) { RBreakpointItem *b = r_bp_at_addr (bp, addr, 0xFFFFFF); if (b) { eprintf("HIT AT ADDR 0x%"PFMT64x"\n", addr); eprintf(" recoil = %d\n", b->recoil); eprintf(" size = %d\n", b->size); + if (!b->hw && ((b->addr + b->size) == addr)) + return b->recoil; } - if (b) if (!b->hw && ((b->addr + b->size) == addr)) - return b->recoil; return 0; } diff --git a/libr/bp/plugin.c b/libr/bp/plugin.c index 9d02b09270..62bc5461cd 100644 --- a/libr/bp/plugin.c +++ b/libr/bp/plugin.c @@ -1,36 +1,33 @@ -/* radare - LGPL - Copyright 2009 pancake */ +/* radare - LGPL - Copyright 2009-2010 pancake */ #include -R_API int r_bp_plugin_del(struct r_bp_t *bp, const char *name) -{ +R_API int r_bp_plugin_del(struct r_bp_t *bp, const char *name) { #warning TODO: r_bp_plugin_del return R_FALSE; } -R_API int r_bp_plugin_add(struct r_bp_t *bp, struct r_bp_plugin_t *foo) -{ - struct list_head *pos; +R_API int r_bp_plugin_add(RBreakpoint *bp, RBreakpointPlugin *foo) { + RListIter *iter; + RBreakpointPlugin *h; if (bp == NULL) { - eprintf("Cannot add plugin because dbg->bp is null and/or plugin is null\n"); + eprintf ("Cannot add plugin because dbg->bp is null and/or plugin is null\n"); return R_FALSE; } /* avoid dupped plugins */ - list_for_each_prev (pos, &bp->bps) { - struct r_bp_plugin_t *h = list_entry (pos, struct r_bp_plugin_t, list); + r_list_foreach (bp->bps, iter, h) { if (!strcmp (h->name, foo->name)) return R_FALSE; } bp->nbps++; - list_add_tail (&(foo->list), &(bp->plugins)); + r_list_append (bp->plugins, foo); return R_TRUE; } -R_API int r_bp_use(struct r_bp_t *bp, const char *name) -{ - struct list_head *pos; - list_for_each_prev (pos, &bp->plugins) { - struct r_bp_plugin_t *h = list_entry(pos, struct r_bp_plugin_t, list); +R_API int r_bp_use(struct r_bp_t *bp, const char *name) { + RListIter *iter; + RBreakpointPlugin *h; + r_list_foreach (bp->plugins, iter, h) { if (!strcmp (h->name, name)) { bp->cur = h; return R_TRUE; @@ -40,12 +37,11 @@ R_API int r_bp_use(struct r_bp_t *bp, const char *name) } // TODO: deprecate -R_API void r_bp_plugin_list(struct r_bp_t *bp) { - struct r_bp_plugin_t *b; - struct list_head *pos; - list_for_each (pos, &bp->plugins) { - b = list_entry(pos, struct r_bp_plugin_t, list); - printf ("bp %c %s\n", +R_API void r_bp_plugin_list(RBreakpoint *bp) { + RListIter *iter; + RBreakpointPlugin *b; + r_list_foreach (bp->plugins, iter, b) { + bp->printf ("bp %c %s\n", (bp->cur && !strcmp (bp->cur->name, b->name))?'*':'-', b->name); } diff --git a/libr/bp/traptrace.c b/libr/bp/traptrace.c index 527a5a6b6c..793eddc828 100644 --- a/libr/bp/traptrace.c +++ b/libr/bp/traptrace.c @@ -19,20 +19,18 @@ R_API RList *r_bp_traptrace_new() { } R_API void r_bp_traptrace_enable(RBreakpoint *bp, int enable) { - RListIter *iter = r_list_iterator (bp->traces); - ut8 *buf; - while (r_list_iter_next (iter)) { - RBreakpointTrace *trace = r_list_iter_get (iter); - if (enable) buf = trace->traps; - else buf = trace->buffer; + RListIter *iter; + RBreakpointTrace *trace; + r_list_foreach (bp->traces, iter, trace) { + ut8 *buf = (enable)?trace->traps:trace->buffer; bp->iob.write_at (bp->iob.io, trace->addr, buf, trace->length); } } R_API void r_bp_traptrace_reset(RBreakpoint *bp, int hard) { - RListIter *iter = r_list_iterator (bp->traces); - while (r_list_iter_next (iter)) { - RBreakpointTrace *trace = r_list_iter_get (iter); + RListIter *iter; + RBreakpointTrace *trace; + r_list_foreach (bp->traces, iter, trace) { if (hard) { r_bp_traptrace_free (trace); // XXX: This segfaults @@ -49,9 +47,9 @@ R_API void r_bp_traptrace_reset(RBreakpoint *bp, int hard) { // FIX: efficiency R_API ut64 r_bp_traptrace_next(RBreakpoint *bp, ut64 addr) { int i, delta; - RListIter *iter = r_list_iterator (bp->traces); - while (r_list_iter_next (iter)) { - RBreakpointTrace *trace = r_list_iter_get (iter); + RListIter *iter; + RBreakpointTrace *trace; + r_list_foreach (bp->traces, iter, trace) { if (addr>=trace->addr && addr<=trace->addr_end) { delta = (int)(addr-trace->addr); for (i=delta; ilength; i++) { @@ -127,8 +125,9 @@ R_API int r_bp_traptrace_free_at(RBreakpoint *bp, ut64 from) { R_API void r_bp_traptrace_list(RBreakpoint *bp) { int i; - RListIter *iter = r_list_iterator (bp->traces); - while (r_list_iter_next (iter)) { + RListIter *iter; + RBreakpointTrace *trace; + r_list_foreach (bp->traces, iter, trace) { RBreakpointTrace *trace = r_list_iter_get (iter); for (i=0; ibitlen; i++) { if (BIT_CHK (trace->bits, i)) @@ -139,10 +138,10 @@ R_API void r_bp_traptrace_list(RBreakpoint *bp) { R_API int r_bp_traptrace_at(RBreakpoint *bp, ut64 from, int len) { int delta; + RListIter *iter; + RBreakpointTrace *trace; + r_list_foreach (bp->traces, iter, trace) { // TODO: do we really need len? - RListIter *iter = r_list_iterator (bp->traces); - while (r_list_iter_next (iter)) { - RBreakpointTrace *trace = r_list_iter_get (iter); if (from>=trace->addr && from+len<=trace->addr_end) { delta = (int) (from-trace->addr); if (BIT_CHK (trace->bits, delta)) diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 62246b7d6f..4034d3c69e 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -174,7 +174,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, //TODO: core->offset+idx must be a var named 'addr'!! less ops if (show_trace) { RDebugTracepoint *tp = r_debug_trace_get (core->dbg, core->offset+idx); - r_cons_printf ("%d:%d ", tp?tp->times:0, tp?tp->count:0); + r_cons_printf ("%02x:%04x ", tp?tp->times:0, tp?tp->count:0); } if (show_stackptr) { r_cons_printf ("%3d%s ", stackptr, diff --git a/libr/core/core.c b/libr/core/core.c index dcac806665..40112f0119 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -71,7 +71,7 @@ static const char *radare_argv[CMDS] ={ }; #define TMP_ARGV_SZ 256 -static char *tmp_argv[TMP_ARGV_SZ]; +static const char *tmp_argv[TMP_ARGV_SZ]; static int autocomplete(RLine *line) { RCore *core = line->user; struct list_head *pos; @@ -223,6 +223,7 @@ R_API int r_core_init(RCore *core) { core->sign->printf = r_cons_printf; core->io->printf = r_cons_printf; core->dbg->printf = r_cons_printf; + core->dbg->bp->printf = r_cons_printf; r_debug_io_bind (core->dbg, core->io); r_core_config_init (core); // XXX fix path here diff --git a/libr/core/io.c b/libr/core/io.c index 68145629a6..72bedbbf39 100644 --- a/libr/core/io.c +++ b/libr/core/io.c @@ -68,7 +68,7 @@ R_API int r_core_seek(RCore *core, ut64 addr, int rb) { r_io_set_fd (core->io, core->file->fd); ret = r_io_seek (core->io, addr, R_IO_SEEK_SET); if (ret == -1) { -eprintf ("RET =%d %llx\n", ret, addr); +//eprintf ("RET =%d %llx\n", ret, addr); /* if (core->ffio) { core->offset = addr; diff --git a/libr/include/r_bp.h b/libr/include/r_bp.h index 72b5d509f2..8ab7834f2c 100644 --- a/libr/include/r_bp.h +++ b/libr/include/r_bp.h @@ -4,7 +4,6 @@ #include #include #include -#include "list.h" #define R_BP_MAXPIDS 10 #define R_BP_CONT_NORMAL 0 @@ -30,9 +29,10 @@ typedef struct r_bp_plugin_t { int type; // R_BP_TYPE_SW int nbps; struct r_bp_arch_t *bps; - struct list_head list; } RBreakpointPlugin; +typedef int (*RBreakpointCallback)(void *user, int type, ut64 addr, int hw, int rwx); + typedef struct r_bp_item_t { ut64 addr; int size; /* size of breakpoint area */ @@ -45,23 +45,23 @@ typedef struct r_bp_item_t { ut8 *obytes; /* original bytes */ ut8 *bbytes; /* breakpoint bytes */ int pids[R_BP_MAXPIDS]; - struct list_head list; + void *data; + RBreakpointCallback callback; // per-bp callback } RBreakpointItem; -typedef int (*RBreakpointCallback)(void *user, int type, ut64 addr, int hw, int rwx); - typedef struct r_bp_t { int trace_all; ut64 trace_bp; int nbps; int stepcont; int endian; + RBreakpointCallback breakpoint; // global callback + RIOBind iob; // compile time dependency + RBreakpointPlugin *cur; + RList *bps; RList *traces; - RBreakpointCallback breakpoint; - struct r_io_bind_t iob; // compile time dependency - struct r_bp_plugin_t *cur; - struct list_head plugins; - struct list_head bps; + RList *plugins; + PrintfCallback printf; } RBreakpoint; enum { @@ -78,7 +78,6 @@ typedef struct r_bp_trace_t { ut8 *bits; int length; int bitlen; - struct list_head list; } RBreakpointTrace; #ifdef R_API @@ -125,9 +124,9 @@ R_API void r_bp_traptrace_enable(RBreakpoint *bp, int enable); /* plugin pointers */ extern struct r_bp_plugin_t r_bp_plugin_x86; extern struct r_bp_plugin_t r_bp_plugin_arm; +extern struct r_bp_plugin_t r_bp_plugin_mips; #if 0 extern struct r_bp_plugin_t r_bp_plugin_powerpc; -extern struct r_bp_plugin_t r_bp_plugin_mips; extern struct r_bp_plugin_t r_bp_plugin_sparc; #endif diff --git a/libr/include/r_debug.h b/libr/include/r_debug.h index 2ec54ce1f4..9040ae6a66 100644 --- a/libr/include/r_debug.h +++ b/libr/include/r_debug.h @@ -73,10 +73,10 @@ typedef struct r_debug_t { int stop_all_threads; char *reg_profile; struct r_reg_t *reg; - struct r_bp_t *bp; + RBreakpoint *bp; void *user; /* io */ - void (*printf)(const char *str, ...); + PrintfCallback printf; struct r_debug_plugin_t *h; struct list_head plugins; RAnal *anal; @@ -122,7 +122,7 @@ typedef struct r_debug_plugin_t { int (*contsc)(int pid, int sc); RList* (*frames)(RDebug *dbg); /* registers */ - RBreakpointCallback breakpoint; + RBreakpointCallback breakpoint; // ??? int (*reg_read)(struct r_debug_t *dbg, int type, ut8 *buf, int size); char* (*reg_profile)(); int (*reg_write)(int pid, int type, const ut8 *buf, int size); //XXX struct r_regset_t regs); diff --git a/libr/include/r_sign.h b/libr/include/r_sign.h index 83bd54dc56..a45dde04b4 100644 --- a/libr/include/r_sign.h +++ b/libr/include/r_sign.h @@ -30,7 +30,7 @@ typedef struct r_sign_t { int s_head; int s_func; // TODO: this must be an array count[N] char prefix[32]; - FunctionPrintf printf; + PrintfCallback printf; struct list_head items; } RSign; diff --git a/libr/include/r_types.h b/libr/include/r_types.h index 195ea23b64..3ee3512189 100644 --- a/libr/include/r_types.h +++ b/libr/include/r_types.h @@ -23,7 +23,7 @@ #define IFDBG if (0) #endif -typedef void (*FunctionPrintf)(const char *str, ...); +typedef void (*PrintfCallback)(const char *str, ...); // TODO NOT USED. DEPREACATE #if R_RTDEBUG diff --git a/libr/sign/README b/libr/sign/README index ad58f15a1f..e760d60db0 100644 --- a/libr/sign/README +++ b/libr/sign/README @@ -1,6 +1,8 @@ r_sign: signature api for radare2 ================================= +// XXX: this documentation does not reflects the reality. must remove, keep it just for inspiration + Plugins are used to implement data collectors for r_sign. A data collector is a piece of code that feeds the r_sign diff --git a/libr/sign/sign.c b/libr/sign/sign.c index d7880de938..97577ac11e 100644 --- a/libr/sign/sign.c +++ b/libr/sign/sign.c @@ -8,7 +8,7 @@ R_API RSign *r_sign_new() { if (sig) { sig->s_byte = sig->s_anal = 0; sig->prefix[0] = '\0'; - sig->printf = (FunctionPrintf) printf; + sig->printf = (PrintfCallback) printf; INIT_LIST_HEAD (&(sig->items)); } return sig; diff --git a/swig/vapi/r_bp.vapi b/swig/vapi/r_bp.vapi index 3f1a6bc495..7fd621c9a8 100644 --- a/swig/vapi/r_bp.vapi +++ b/swig/vapi/r_bp.vapi @@ -1,9 +1,11 @@ /* radare - LGPL - Copyright 2009-2010 pancake */ [Compact] -[CCode (cheader_filename="r_bp.h", cname="struct r_bp_t", free_function="r_bp_free", cprefix="r_bp_")] +[CCode (cheader_filename="r_bp.h,r_list.h", cname="struct r_bp_t", free_function="r_bp_free", cprefix="r_bp_")] public class Radare.RBreakpoint { public RBreakpoint (); + public RList bps; + public RList traces; public bool use (string arch); public void enable (uint64 addr, bool enabled); public unowned Item? at_addr (uint64 addr, int rwx);