📄 brktab.c
字号:
/*
* File: brktab.c
* Purpose: Breakpoint table management routines.
*
* Notes:
*
* Author: Eric DeVolder
* Date:
*
* Modifications:
*
*/
#include "src/include/dbug.h"
#include "src/uif/uif.h"
/********************************************************************/
/*
* Data structure used to maintain break points and trace
* information.
*/
typedef struct
{
ADDRESS address;
INSTRUCTION instruction;
int count;
int trigger;
int valid; /* and type info */
} BRKENT;
BRKENT
brktab[UIF_MAX_BRKPTS];
/********************************************************************/
static void
breakpoint_clear (int index)
{
if ((index >= 0) && (index < UIF_MAX_BRKPTS))
{
brktab[index].address = NULL;
brktab[index].instruction = NULL;
brktab[index].count = 0;
brktab[index].trigger = 0;
brktab[index].valid = BKPT_NONE;
}
}
/********************************************************************/
void
breakpoint_init (void)
{
int index;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
breakpoint_clear(index);
}
/********************************************************************/
static int
breakpoint_find (ADDRESS address)
{
/*
* This function searches the breakpoint table for `address'.
* If it is found, then an index into the table is returned,
* otherwise -1 is returned.
*/
int index;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
{
if (brktab[index].address == address)
return index;
}
return -1;
}
/********************************************************************/
static void
breakpoint_display_info (int index)
{
if ((index >= 0) && (index < UIF_MAX_BRKPTS))
{
printf("%08X: %08X %08X\n",
(int)brktab[index].address,
brktab[index].count,
brktab[index].trigger );
}
}
/********************************************************************/
static void
breakpoint_display (int argc, char **argv)
{
ADDRESS address;
int i,j;
(void)argc;
printf(" Address Count Trigger\n");
/* break points are listed one by one starting at argv[1] */
/* if no break points listed, argv[1] == NULL, display all */
if (argv[1] == NULL)
{
/* display all */
for (i = 0; i < UIF_MAX_BRKPTS; i++)
{
if (brktab[i].valid)
breakpoint_display_info(i);
}
}
else
{
i = 1;
while (argv[i] != NULL)
{
address = (ADDRESS)strtoul(argv[i],NULL,16);
for (j = 0; j < UIF_MAX_BRKPTS; j++)
{
if (brktab[j].address == address)
breakpoint_display_info(j);
}
i++;
}
}
}
/********************************************************************/
static void
breakpoint_set_count (ADDRESS brkpnt, int count)
{
int index;
index = breakpoint_find(brkpnt);
if ((index >= 0) && (index < UIF_MAX_BRKPTS))
{
brktab[index].count = count;
}
}
/********************************************************************/
static void
breakpoint_set_all_count (int value)
{
int index;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
brktab[index].count = value;
}
/********************************************************************/
static void
breakpoint_set_trigger (ADDRESS brkpnt, int count)
{
int index;
index = breakpoint_find(brkpnt);
if ((index >= 0) && (index < UIF_MAX_BRKPTS))
{
brktab[index].trigger = count;
}
}
/********************************************************************/
static void
breakpoint_set_all_trigger (int value)
{
int index;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
brktab[index].trigger = value;
}
/********************************************************************/
void
breakpoint_remove (ADDRESS address)
{
int index;
if ((index = breakpoint_find(address)) != -1)
{
breakpoint_clear(index);
}
}
/********************************************************************/
void
breakpoint_add (ADDRESS address, int type)
{
int i;
/* first check to make sure not already in table */
if (breakpoint_find(address) != -1)
return;
/* find an open slot and put it in */
for (i = 0; i < UIF_MAX_BRKPTS; i++)
{
if (!brktab[i].valid)
break;
}
if (i == UIF_MAX_BRKPTS)
{
printf("Break table full.\n");
return;
}
/*
* Test for valid breakpoint address
*/
if (!cpu_valid_insn_addr(address))
{
printf("Error: Invalid breakpoint address!\n");
return;
}
/*
* Test for read-only memory
*/
brktab[i].instruction = *(INSTRUCTION *)address;
*(INSTRUCTION *)address = (INSTRUCTION)ILLEGAL;
if (*(INSTRUCTION *)address != (INSTRUCTION)ILLEGAL)
{
printf("Error: Address is read-only!\n");
}
else
{
*(INSTRUCTION *)address = brktab[i].instruction;
brktab[i].address = address;
brktab[i].count = 0;
brktab[i].trigger = 1;
brktab[i].valid = type;
}
}
/********************************************************************/
int
breakpoint_install (ADDRESS address)
{
/*
* This function inserts the breakpoints in user code. Extensive
* checking of breakpoints is done before entry into the table, so
* all breakpoints in table should be OK to just implant. If
* a breakpoint with the same `address' is found, it is not
* inserted, and TRUE is returned, otherwise FALSE.
* This routine is generally called right before executing user
* code.
*/
int index, found = FALSE;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
{
if (brktab[index].valid)
{
if (brktab[index].address == address)
{
found = TRUE;
}
else
{
brktab[index].instruction =
*(INSTRUCTION *)brktab[index].address;
*(INSTRUCTION *)brktab[index].address =
(INSTRUCTION)ILLEGAL;
}
}
}
cpu_cache_flush();
return found;
}
/********************************************************************/
int
breakpoint_deinstall (ADDRESS address, int *triggered)
{
/*
* This function removes breakpoints from user code. If
* `address' is/was installed, TRUE is returned, else FALSE
* if `address' was encountered, its count is incremented.
*/
int index, found = FALSE;
*triggered = FALSE;
for (index = 0; index < UIF_MAX_BRKPTS; index++)
{
if (brktab[index].valid)
{
*(INSTRUCTION *)brktab[index].address =
(INSTRUCTION)brktab[index].instruction;
if (brktab[index].address == address)
{
found = TRUE;
if ( ++brktab[index].count >=
brktab[index].trigger)
*triggered = TRUE;
}
if (brktab[index].valid == BKPT_TEMP)
{
/* knock out Temporary breakpoints */
breakpoint_clear(index);
}
}
}
cpu_cache_flush();
return found;
}
/********************************************************************/
void
uif_cmd_br (int argc, char **argv)
{
int i, value, success;
ADDRESS brkpnt;
char *p;
brkpnt = (ADDRESS)-1; /* improbable breakpoint address */
if (argc == 1)
{
/* display all break points */
breakpoint_display(argc,argv);
return ;
}
/* parse through arguments */
i = 1;
while (i < argc)
{
if (argv[i][0] != '-')
{
/* must be a breakpoint address */
brkpnt = get_value(argv[i],&success,16);
if (success == 0)
{
printf("Error: Bad Value: %s\n",argv[i]);
return;
}
/* add breakpont, if not already there */
breakpoint_add(brkpnt, BKPT_PERM);
i++;
}
else
{
/* must be an option of some sort */
switch (argv[i][1])
{
case 'c':
case 'C':
/* set break point count */
if (argv[i+1] == NULL)
value = 0;
else
{
value = strtoul(argv[++i],&p,BASE);
if ((value == 0) && (p == argv[i]))
value = 0;
}
if (brkpnt == (ADDRESS)-1)
{
/* set all counts */
breakpoint_set_all_count(value);
return;
}
else
{
breakpoint_set_count(brkpnt,value);
}
break;
case 't':
case 'T':
/* set break point trigger */
if (argv[i+1] == NULL)
value = 1;
else
{
value = strtoul(argv[++i],&p,BASE);
if ((value == 0) && (p == argv[i]))
value = 1;
}
if (brkpnt == (ADDRESS)-1)
{
/* set all triggers */
breakpoint_set_all_trigger(value);
return;
}
else
{
breakpoint_set_trigger(brkpnt,value);
}
break;
case 'r':
case 'R':
/* remove break points */
if (brkpnt == (ADDRESS)-1)
{
/* check for address given after '-r' */
if (argv[i+1] == NULL)
breakpoint_init();
else
{
while (++i < argc)
{
brkpnt = get_value(argv[i],&success,16);
if (success == 0)
breakpoint_init();
else
breakpoint_remove(brkpnt);
}
}
}
else
{
breakpoint_remove(brkpnt);
}
break;
case 'i':
case 'I':
breakpoint_set_all_trigger(1);
breakpoint_set_all_count(0);
break;
default:
printf("Error: Invalid option: %s\n",argv[1]);
break;
}
i++;
}
}
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -