Fix 10811 - Improvements in gdbclient breakpoints (#10940)

This commit is contained in:
AsFaBw 2018-08-07 12:15:11 +02:00 committed by radare
parent 201c360b10
commit 84852de244
7 changed files with 113 additions and 24 deletions

View File

@ -284,8 +284,8 @@ R_API int r_bp_list(RBreakpoint *bp, int rad) {
" %d %c%c%c %s %s %s cmd=\"%s\" cond=\"%s\" " \
"name=\"%s\" module=\"%s\"\n",
b->addr, b->addr + b->size, b->size,
(b->rwx & R_BP_PROT_READ) ? 'r' : '-',
(b->rwx & R_BP_PROT_WRITE) ? 'w' : '-',
((b->rwx & R_BP_PROT_READ) | (b->rwx & R_BP_PROT_ACCESS)) ? 'r' : '-',
((b->rwx & R_BP_PROT_WRITE)| (b->rwx & R_BP_PROT_ACCESS)) ? 'w' : '-',
(b->rwx & R_BP_PROT_EXEC) ? 'x' : '-',
b->hw ? "hw": "sw",
b->trace ? "trace" : "break",

View File

@ -76,7 +76,7 @@ static const char *help_msg_db[] = {
"dbh-", " <name>", "Remove breakpoint plugin handler",
"dbt", "[?]", "Show backtrace. See dbt? for more details",
"dbx", " [expr]", "Set expression for bp in current offset",
"dbw", " <addr> <rw>", "Add watchpoint",
"dbw", " <addr> <r/w/rw>", "Add watchpoint",
"drx", " number addr len rwx", "Modify hardware breakpoint",
"drx-", "number", "Clear hardware breakpoint",
NULL
@ -96,6 +96,11 @@ static const char *help_msg_dbt[] = {
NULL
};
static const char *help_msg_dbw[] = {
"Usage: dbw", "<addr> <r/w/rw>"," # Add watchpoint",
NULL
};
static const char *help_msg_dc[] = {
"Usage: dc", "", "Execution continuation commands",
"dc", "", "Continue execution of all children",
@ -1445,7 +1450,7 @@ static void get_hash_debug_file(RCore *core, const char *path, char *hash, int h
RBinSection *s;
r_list_foreach (sects, iter, s) {
if (strstr (s->name, ".note.gnu.build-id")) {
if (r_buf_read_at (binfile->buf, s->vaddr + 16, (ut8*)buf, 20) == 20) {
if (r_buf_read_at (binfile->buf, s->vaddr + 16, buf, 20) == 20) {
break;
}
eprintf ("Cannot read from buffer\n");
@ -3405,13 +3410,26 @@ static void r_core_cmd_bp(RCore *core, const char *input) {
int sl = r_str_word_set0 (str);
addr = r_num_math (core->num, DB_ARG(0));
if (watch) {
if (sl == 2) {
rw = (strcmp (DB_ARG(1), "r") == 0 ? R_BP_PROT_READ : R_BP_PROT_WRITE);
} else {
eprintf ("Usage: dbw <addr> <rw> # Add watchpoint\n");
if (sl == 2) {
if (!strcmp (DB_ARG(1), "r")){
rw = R_BP_PROT_READ;
}
else if (!strcmp (DB_ARG(1), "w")){
rw = R_BP_PROT_WRITE;
}
else if (!strcmp (DB_ARG(1), "rw")){
rw = R_BP_PROT_ACCESS;
}
else{
r_core_cmd_help (core, help_msg_dbw);
free (str);
break;
}
} else {
r_core_cmd_help (core, help_msg_dbw);
free (str);
break;
}
}
if (validAddress (core, addr)) {
bpi = r_debug_bp_add (core->dbg, addr, hwbp, watch, rw, NULL, 0);

View File

@ -976,17 +976,43 @@ static int r_debug_gdb_breakpoint (RBreakpoint *bp, RBreakpointItem *b, bool set
if (!b) {
return false;
}
bpsize = b->size;
// TODO handle rwx and conditions
if (set)
ret = b->hw?
gdbr_set_hwbp (desc, b->addr, "", bpsize):
gdbr_set_bp (desc, b->addr, "", bpsize);
else
ret = b->hw?
gdbr_remove_hwbp (desc, b->addr, bpsize):
gdbr_remove_bp (desc, b->addr, bpsize);
// TODO handle conditions
switch (b->rwx){
case R_BP_PROT_EXEC : {
if (set)
ret = b->hw?
gdbr_set_hwbp (desc, b->addr, "", bpsize):
gdbr_set_bp (desc, b->addr, "", bpsize);
else
ret = b->hw?
gdbr_remove_hwbp (desc, b->addr, bpsize):
gdbr_remove_bp (desc, b->addr, bpsize);
break;
}
// TODO handle size (area of watch in upper layer and then bpsize. For the moment watches are set on exact on byte
case R_BP_PROT_WRITE : {
if (set)
gdbr_set_hww (desc, b->addr, "", 1);
else
gdbr_remove_hwbp (desc, b->addr, 1);
break;
}
case R_BP_PROT_READ : {
if (set)
gdbr_set_hwr (desc, b->addr, "", 1);
else
gdbr_remove_hwr (desc, b->addr, 1);
break;
}
case R_BP_PROT_ACCESS : {
if (set)
gdbr_set_hwa (desc, b->addr, "", 1);
else
gdbr_remove_hwa (desc, b->addr, 1);
break;
}
}
return !ret;
}

View File

@ -62,8 +62,7 @@ typedef struct r_bp_item_t {
char *expr; /* to be used for named breakpoints (see r_debug_bp_update) */
} RBreakpointItem;
struct r_bp_t;
typedef int (*RBreakpointCallback)(struct r_bp_t *bp, RBreakpointItem *b, bool set);
typedef int (*RBreakpointCallback)(void *bp, RBreakpointItem *b, bool set);
typedef struct r_bp_t {
void *user;
@ -89,6 +88,7 @@ enum {
R_BP_PROT_EXEC = 1,
R_BP_PROT_WRITE = 2,
R_BP_PROT_READ = 4,
R_BP_PROT_ACCESS = 8,
};
typedef struct r_bp_trace_t {

View File

@ -101,9 +101,14 @@ int test_command(libgdbr_t *g, const char *command);
*/
int gdbr_set_bp(libgdbr_t *g, ut64 address, const char *conditions, int sizebp);
int gdbr_set_hwbp(libgdbr_t *g, ut64 address, const char *conditions, int sizebp);
int gdbr_set_hww(libgdbr_t *g, ut64 address, const char *conditions, int sizebp);
int gdbr_set_hwr(libgdbr_t *g, ut64 address, const char *conditions, int sizebp);
int gdbr_set_hwa(libgdbr_t *g, ut64 address, const char *conditions, int sizebp);
int gdbr_remove_bp(libgdbr_t *g, ut64 address, int sizebp);
int gdbr_remove_hwbp(libgdbr_t *g, ut64 address, int sizebp);
int gdbr_remove_hww(libgdbr_t *g, ut64 address, int sizebp);
int gdbr_remove_hwr(libgdbr_t *g, ut64 address, int sizebp);
int gdbr_remove_hwa(libgdbr_t *g, ut64 address, int sizebp);
/*!
* File read from remote target (only one file open at a time for now)
*/

View File

@ -28,11 +28,17 @@
#define CMD_RBP "z0"
#define CMD_HBP "Z1"
#define CMD_RHBP "z1"
#define CMD_HWW "Z2"
#define CMD_RHWW "z2"
#define CMD_HWR "Z3"
#define CMD_RHWR "z3"
#define CMD_HWA "Z4"
#define CMD_RHWA "z4"
#define CMD_QRCMD "qRcmd,"
#define CMD_C "vCont"
#define CMD_C_CONT "c"
#define CMD_C "vCont"
#define CMD_C_CONT "c"
#define CMD_C_CONT_SIG "C"
#define CMD_C_STEP "s"
#define CMD_C_STEP "s"
enum Breakpoint {
BREAKPOINT,

View File

@ -981,10 +981,16 @@ int set_bp(libgdbr_t *g, ut64 address, const char *conditions, enum Breakpoint t
"%s,%"PFMT64x ",%d", CMD_HBP, address, sizebp);
break;
case WRITE_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1,
"%s,%"PFMT64x ",%d", CMD_HWW, address, sizebp);
break;
case READ_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1,
"%s,%"PFMT64x ",%d", CMD_HWR, address, sizebp);
break;
case ACCESS_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1,
"%s,%"PFMT64x ",%d", CMD_HWA, address, sizebp);
break;
default:
break;
@ -1012,6 +1018,18 @@ int gdbr_set_hwbp(libgdbr_t *g, ut64 address, const char *conditions, int sizebp
return set_bp (g, address, conditions, HARDWARE_BREAKPOINT, sizebp);
}
int gdbr_set_hww(libgdbr_t *g, ut64 address, const char *conditions, int sizebp) {
return set_bp (g, address, conditions, WRITE_WATCHPOINT, sizebp);
}
int gdbr_set_hwr(libgdbr_t *g, ut64 address, const char *conditions, int sizebp) {
return set_bp (g, address, conditions, READ_WATCHPOINT, sizebp);
}
int gdbr_set_hwa(libgdbr_t *g, ut64 address, const char *conditions, int sizebp) {
return set_bp (g, address, conditions, ACCESS_WATCHPOINT, sizebp);
}
int gdbr_remove_bp(libgdbr_t *g, ut64 address, int sizebp) {
return remove_bp (g, address, BREAKPOINT, sizebp);
}
@ -1020,6 +1038,19 @@ int gdbr_remove_hwbp(libgdbr_t *g, ut64 address, int sizebp) {
return remove_bp (g, address, HARDWARE_BREAKPOINT, sizebp);
}
int gdbr_remove_hww(libgdbr_t *g, ut64 address, int sizebp) {
return remove_bp (g, address, WRITE_WATCHPOINT, sizebp);
}
int gdbr_remove_hwr(libgdbr_t *g, ut64 address, int sizebp) {
return remove_bp (g, address, READ_WATCHPOINT, sizebp);
}
int gdbr_remove_hwa(libgdbr_t *g, ut64 address, int sizebp) {
return remove_bp (g, address, ACCESS_WATCHPOINT, sizebp);
}
int remove_bp(libgdbr_t *g, ut64 address, enum Breakpoint type, int sizebp) {
char tmp[255] = {0};
int ret = -1;
@ -1034,10 +1065,13 @@ int remove_bp(libgdbr_t *g, ut64 address, enum Breakpoint type, int sizebp) {
ret = snprintf (tmp, sizeof (tmp) - 1, "%s,%"PFMT64x ",%d", CMD_RHBP, address, sizebp);
break;
case WRITE_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1, "%s,%"PFMT64x ",%d", CMD_RHWW, address, sizebp);
break;
case READ_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1, "%s,%"PFMT64x ",%d", CMD_RHWR, address, sizebp);
break;
case ACCESS_WATCHPOINT:
ret = snprintf (tmp, sizeof (tmp) - 1, "%s,%"PFMT64x ",%d", CMD_RHWA, address, sizebp);
break;
default:
break;