📄 generic-stub.c
字号:
{
/* When there is a comma, there must be a length */
if (!__hexToInt (&ptr, &length))
{
strcpy (remcomOutBuffer, "E02");
break;
}
}
else
length = 0;
addr = (target_register_t)TARGET_ADDR_TO_PTR(taddr);
switch (ztype)
{
case 0:
/* sw breakpoint */
if (is_Z)
err = __set_breakpoint(addr,length);
else
err = __remove_breakpoint(addr,length);
if (!err)
strcpy (remcomOutBuffer, "OK");
else
strcpy (remcomOutBuffer, "E02");
break;
#ifdef HAL_STUB_HW_BREAKPOINT
case 1:
/* hw breakpoint */
if (!HAL_STUB_HW_BREAKPOINT(is_Z, (void *)addr, length))
strcpy (remcomOutBuffer, "OK");
else
strcpy (remcomOutBuffer, "E02");
break;
#endif
#ifdef HAL_STUB_HW_WATCHPOINT
case 2:
case 3:
case 4:
{
/* hw watchpoint */
if (!HAL_STUB_HW_WATCHPOINT(is_Z, (void *)addr, length, ztype))
strcpy (remcomOutBuffer, "OK");
else
strcpy (remcomOutBuffer, "E02");
}
break;
#endif
}
}
}
break;
}
#endif // Z packet support
default:
__process_target_packet (packet, remcomOutBuffer, 300);
break;
}
/* reply to the request */
__putpacket (remcomOutBuffer);
return 0;
}
static void
send_t_packet (int sigval)
{
__build_t_packet (sigval, remcomOutBuffer);
__putpacket (remcomOutBuffer);
}
/*
* This function does all command procesing for interfacing to gdb.
*/
static int
process_exception (int sigval)
{
int status;
/* Nasty. */
if (ungot_char < 0)
send_t_packet (sigval);
do {
getpacket (remcomInBuffer);
status = __process_packet (remcomInBuffer);
} while (status == 0);
if (status < 0)
return 0;
else
return 1;
}
void
__send_exit_status (int status)
{
remcomOutBuffer[0] = 'W';
remcomOutBuffer[1] = hexchars[(status >> 4) & 0xf];
remcomOutBuffer[2] = hexchars[status & 0xf];
remcomOutBuffer[3] = 0;
__putpacket (remcomOutBuffer);
}
/* Read up to MAXLEN bytes from the remote GDB client, and store in DEST
(which is a pointer in the user program). BLOCK indicates what mode
is being used; if it is set, we will wait for MAXLEN bytes to be
entered. Otherwise, the function will return immediately with whatever
bytes are waiting to be read.
The value returned is the number of bytes read. A -1 indicates that an
error of some sort occurred. */
int
__get_gdb_input (target_register_t dest, int maxlen, int block)
{
char buf[4];
int len, i;
char d;
buf[0] = 'I';
buf[1] = '0';
buf[2] = block ? '0' : '1';
buf[3] = 0;
__putpacket (buf);
getpacket (remcomInBuffer);
if (remcomInBuffer[0] != 'I')
return -1;
len = stubhex (remcomInBuffer[1]) * 16 + stubhex (remcomInBuffer[2]);
for (i = 0; i < len; i++)
{
d = stubhex (remcomInBuffer[3 + i * 2]) * 16;
d |= stubhex (remcomInBuffer[3 + i * 2 + 1]);
__write_mem_safe (&d, (void *)(dest + i), 1);
}
/* Write the trailing \0. */
d = '\0';
__write_mem_safe (&d, (void *)(dest + i), 1);
return len;
}
void
__output_hex_value (target_register_t i)
{
char buf[32], *ptr=buf+31;
unsigned int x;
*ptr = 0;
for (x = 0; x < (sizeof (i) * 2); x++)
{
*(--ptr) = hexchars[i & 15];
i = i >> 4;
}
while (*ptr)
{
putDebugChar (*(ptr++));
}
}
/* Write the C-style string pointed to by STR to the GDB comm port. */
void
__putDebugStr (char *str)
{
while (*str)
{
putDebugChar (*str);
str++;
}
}
/* Send STRING_LEN bytes of STR to GDB, using 'O' packets.
STR is assumed to be in the program being debugged. */
int
__output_gdb_string (target_register_t str, int string_len)
{
/* We will arbitrarily limit output packets to less than 400 bytes. */
static char buf[400];
int x;
int len;
if (string_len == 0)
{
/* We can't do strlen on a user pointer. */
return -1;
}
len = string_len;
while (len > 0)
{
int packetlen = ((len < 175) ? len : 175);
buf[0] = 'O';
for (x = 0; x < packetlen; x++)
{
char c;
__read_mem_safe (&c, (void *)(str + x), 1);
buf[x*2+1] = hexchars[(c >> 4) & 0xf];
buf[x*2+2] = hexchars[c % 16];
}
str += x;
len -= x;
buf[x*2+1] = 0;
__putpacket (buf);
}
return string_len;
}
static void
do_nothing (void)
{
/* mmmm */
}
static int
syscall_do_nothing (int junk)
{
return 0;
}
/* Start the stub running. */
void
__switch_to_stub (void)
{
__process_exception_vec = process_exception;
#ifdef CYGPKG_CYGMON
// Cygmon will have consumed the '$' character for this packet.
// Let's put one in the unget buffer.
// Actually, Cygmon does an unget, but since it uses different
// unget handling, we need to do this here.
ungetDebugChar('$');
#endif
}
#if ! defined(BOARD_SPECIFIC_STUB_INIT)
void
initialize_stub (void)
{
set_debug_traps ();
/* FIXME: This function should be renamed to specifically init the
hardware required by debug operations. If initHardware is implemented at
all, it should be called before main ().
*/
initHardware () ;
/* This acks any stale packets , NOT an effective solution */
putDebugChar ('+');
}
#endif
void
ungetDebugChar (int c)
{
ungot_char = c;
}
void
__kill_program (int sigval)
{
remcomOutBuffer[0] = 'X';
remcomOutBuffer[1] = hexchars[(sigval >> 4) & 15];
remcomOutBuffer[2] = hexchars[sigval & 15];
remcomOutBuffer[3] = 0;
__putpacket (remcomOutBuffer);
}
#define MAX_ARG_COUNT 20
#define MAX_ARGDATA 128
static char *program_argv [MAX_ARG_COUNT];
static int program_argc;
static int last_program_arg;
static char program_argstr [MAX_ARGDATA], *argptr;
static int args_initted = 0;
void
__free_program_args (void)
{
last_program_arg = -1;
program_argc = 0;
program_argv [0] = NULL;
argptr = program_argstr;
args_initted = 1;
}
static char *
__add_program_arg (int argc, uint32 len)
{
char *res;
if (! args_initted)
{
__free_program_args ();
}
if ((argc >= (MAX_ARG_COUNT - 1))
|| ((argptr - program_argstr + len) > MAX_ARGDATA))
{
return NULL;
}
if (argc != last_program_arg)
{
if (argc >= program_argc)
{
program_argc = argc + 1;
program_argv [program_argc] = NULL;
}
program_argv [argc] = argptr;
last_program_arg = argc;
}
res = argptr;
argptr += len;
return res;
}
void
__set_program_args (int argc, char **argv)
{
int x;
__free_program_args ();
if (argc)
{
for (x = 0; x < argc; x++)
{
uint32 len = strlen (argv[x])+1;
char *s = __add_program_arg (x, len);
if (s == NULL)
return;
memcpy (s, argv[x], len);
}
}
}
char **
__get_program_args (target_register_t argcPtr)
{
if (!args_initted)
{
__free_program_args ();
}
__write_mem_safe ((char *) &program_argc, (void *)argcPtr, sizeof (program_argc));
return program_argv;
}
/* Table used by the crc32 function to calcuate the checksum. */
static uint32 crc32_table[256];
static int tableInit = 0;
/*
Calculate a CRC-32 using LEN bytes of PTR. CRC is the initial CRC
value.
PTR is assumed to be a pointer in the user program. */
static uint32
crc32 (target_addr_t mem, int len, uint32 crc)
{
unsigned char *ptr = (unsigned char *)TARGET_ADDR_TO_PTR(mem);
#ifdef TARGET_HAS_HARVARD_MEMORY
int is_progmem = TARGET_ADDR_IS_PROGMEM(mem);
#endif
if (! tableInit)
{
/* Initialize the CRC table and the decoding table. */
uint32 i, j;
uint32 c;
tableInit = 1;
for (i = 0; i < 256; i++)
{
for (c = i << 24, j = 8; j > 0; --j)
c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
crc32_table[i] = c;
}
}
__mem_fault = 0;
while (len--)
{
unsigned char ch;
#ifdef TARGET_HAS_HARVARD_MEMORY
if (is_progmem)
__read_progmem_safe (&ch, (void *)ptr, 1);
else
#endif
__read_mem_safe (&ch, (void *)ptr, 1);
if (__mem_fault)
{
break;
}
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ ch) & 255];
ptr++;
}
return crc;
}
/* Handle the 'q' request */
static void
process_query (char *pkt)
{
remcomOutBuffer[0] = '\0';
#ifdef __ECOS__
if ('C' == pkt[0] &&
'R' == pkt[1] &&
'C' == pkt[2] &&
':' == pkt[3])
#else // __ECOS__
if (strncmp (pkt, "CRC:", 4) == 0)
#endif // __ECOS__
{
target_addr_t startmem;
target_register_t length;
uint32 our_crc;
pkt += 4;
if (__hexToAddr (&pkt, &startmem)
&& *(pkt++) == ','
&& __hexToInt (&pkt, &length))
{
our_crc = crc32 (startmem, length, 0xffffffff);
if (__mem_fault)
{
strcpy (remcomOutBuffer, "E01");
}
else
{
int numb = __intToHex (remcomOutBuffer + 1, our_crc, 32);
remcomOutBuffer[0] = 'C';
remcomOutBuffer[numb + 1] = 0;
}
}
return;
}
else
{
char ch ;
char * subpkt ;
ch = *pkt ;
subpkt = pkt + 1 ;
switch (ch)
{
case 'L' : /* threadlistquery */
STUB_PKT_GETTHREADLIST (subpkt, remcomOutBuffer, 300);
break ;
case 'P' : /* Thread or process information request */
STUB_PKT_GETTHREADINFO (subpkt, remcomOutBuffer, 300);
break ;
case 'C' : /* current thread query */
STUB_PKT_CURRTHREAD(subpkt, remcomOutBuffer, sizeof(remcomOutBuffer));
break;
default:
__process_target_query (pkt, remcomOutBuffer, 300);
break ;
}
}
}
/* Handle the 'Q' request */
static void
process_set (char *pkt)
{
char ch ;
ch = *pkt ;
switch (ch)
{
case 'p' : /* Set current process or thread */
/* reserve the packet id even if support is not present */
/* Dont strip the 'p' off the header, there are several variations of
this packet */
STUB_PKT_CHANGETHREAD (pkt, remcomOutBuffer, 300) ;
break ;
default:
__process_target_set (pkt, remcomOutBuffer, 300);
break ;
}
}
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -