📄 generic-stub.c
字号:
break;
case ZTYPE_HW_WATCHPOINT_WRITE:
case ZTYPE_HW_WATCHPOINT_READ:
case ZTYPE_HW_WATCHPOINT_ACCESS:
#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
if (is_Z)
err = __set_hw_watchpoint(addr, length, ztype);
else
err = __remove_hw_watchpoint(addr, length, ztype);
if (!err)
strcpy (__remcomOutBuffer, "OK");
else
#endif
strcpy (__remcomOutBuffer, "E02");
break;
}
}
}
break;
}
#endif // Z packet support
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
case 'F':
{
extern void cyg_hal_gdbfileio_process_F_packet( char *, char *);
cyg_hal_gdbfileio_process_F_packet( packet, __remcomOutBuffer );
return -1;
}
#endif
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);
}
#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
#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;
}
#endif
/* Table used by the crc32 function to calcuate the checksum. */
#ifdef CYGDBG_HAL_CRCTABLE_LOCATION_RAM
static uint32 crc32_table[256];
static int tableInit = 0;
#else
static const uint32 crc32_table[256]={
0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4,
};
#endif
/*
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
#ifdef CYGDBG_HAL_CRCTABLE_LOCATION_RAM
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;
}
}
#endif
__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;
}
#ifdef CYG_HAL_STUB_PROCESS_QUERY
else if (CYG_HAL_STUB_PROCESS_QUERY (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
return;
#endif
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 ;
#ifdef CYG_HAL_STUB_PROCESS_SET
if (CYG_HAL_STUB_PROCESS_SET (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
return;
#endif
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 + -