blob: adebf9ff677d3d230e49c0728fef613a00952895 [file] [log] [blame]
/*
* remote-breakpoint.c
*
* A breakpoint list for a remote gdb target.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "remote-breakpoint.h"
static breakpoint *bplist[5];
extern int verbose;
/*
* insert_breakpoint
*
* returns: FAIL/PASS
*/
static enum successcode
insert_breakpoint (enum breakpoint_type bptype,
unsigned long long addr,
unsigned long len)
{
breakpoint *this_bp;
switch (bptype) {
case ACCESS_BP:
case HARDWARE_BP:
case READ_BP:
case WRITE_BP:
default:
/* Can't do those. */
return FAIL;
break;
case SOFTWARE_BP:
this_bp = malloc (sizeof (breakpoint));
this_bp->addr = addr;
this_bp->len = len;
this_bp->next = bplist[bptype];
bplist[bptype] = this_bp;
return PASS;
}
}
/*
* unlink_breakpoint
*
* returns: 0 for fail, 1 for success
*/
static int
unlink_breakpoint (enum breakpoint_type bptype,
unsigned long long addr,
unsigned long len)
{
breakpoint *this_bp, *tmp;
switch (bptype) {
case ACCESS_BP:
case HARDWARE_BP:
case READ_BP:
case WRITE_BP:
default:
/* Can't do those. */
return FAIL;
break;
case SOFTWARE_BP:
/* Special case - list is empty. */
if (bplist[bptype] == NULL)
return FAIL;
/* Start from list head. */
this_bp = bplist[bptype];
/* Special case -- remove head of list. */
if (this_bp->addr == addr &&
this_bp->len == len)
{
bplist[bptype] = this_bp->next;
return PASS;
}
/* Scan list. */
for (; this_bp && this_bp->next; this_bp = this_bp->next)
if (this_bp->next->addr == addr &&
this_bp->next->len == len)
{
/* Remove from middle of list. */
tmp = this_bp->next->next;
free (this_bp->next);
this_bp->next = tmp;
return PASS;
}
/* Not found. */
return FAIL;
}
}
extern enum successcode
remote_remove_breakpoint (enum breakpoint_type bptype,
unsigned long long addr,
unsigned long len)
{
if (verbose)
fprintf (stdout, "remote-breakpoint: Remove sw breakpoint type %d\n",
bptype);
if (unlink_breakpoint (bptype, addr, len) == 0)
{
fprintf (stderr, " FAILED!\n");
return FAIL;
}
return PASS;
}
extern enum successcode
remote_set_breakpoint (enum breakpoint_type bptype,
unsigned long long addr,
unsigned long len)
{
if (verbose)
fprintf (stdout, "remote-breakpoint: Set sw breakpoint type %d\n",
bptype);
if (insert_breakpoint (bptype, addr, len) == 0)
{
fprintf (stderr, " FAILED!\n");
return FAIL;
}
return PASS;
}
/*
* remote_breakpoint_here_p
*
* Scan the list of breakpoints of type BPTYPE.
* Return PASS if there is one that matches ADDR, else FAIL.
*
* FIXME: do I need to consider the length?
*/
enum successcode
remote_breakpoint_here_p (enum breakpoint_type bptype,
unsigned long long addr)
{
breakpoint *bp = bplist[bptype];
while (bp != NULL)
{
if (bp->addr == addr)
return PASS;
bp = bp->next;
}
return FAIL;
}