frv: extend gdbstub to support more features of gdb

Extend gdbstub to support more features of gdb remote protocol to keep
gdb-7 and emacs gud mode happy:

 (*) The D command.  Detach debugger.

 (*) The H command.  Handle setting the target thread by ignoring it.

 (*) The qAttached command.  Indicate we 'attached' to an existing process.

 (*) The qC command.  Indicate that the current thread ID is 0.

 (*) The qOffsets command.  Indicate that no relocation has been done.

 (*) The qSymbol:: command.  Indicate that we're not interested in looking up
     any symbol addresses.

 (*) The qSupported command.  Indicate the maximum packet size and the fact
     that reverse step and continue aren't supported.

 (*) The vCont? command.  Indicate that we don't support any of its variants.

Also make it possible to trace the commands and replies without tracing
the individual character I/O.

[akpm@linux-foundation.org: make gdbstub_handle_query() static]
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
David Howells 2010-05-24 14:32:54 -07:00 committed by Linus Torvalds
parent c6f6b596a5
commit 7ca8b9c0da
3 changed files with 70 additions and 2 deletions

View File

@ -12,6 +12,7 @@
#ifndef __ASM_GDB_STUB_H #ifndef __ASM_GDB_STUB_H
#define __ASM_GDB_STUB_H #define __ASM_GDB_STUB_H
#undef GDBSTUB_DEBUG_IO
#undef GDBSTUB_DEBUG_PROTOCOL #undef GDBSTUB_DEBUG_PROTOCOL
#include <asm/ptrace.h> #include <asm/ptrace.h>
@ -108,6 +109,12 @@ extern void gdbstub_printk(const char *fmt, ...);
extern void debug_to_serial(const char *p, int n); extern void debug_to_serial(const char *p, int n);
extern void console_set_baud(unsigned baud); extern void console_set_baud(unsigned baud);
#ifdef GDBSTUB_DEBUG_IO
#define gdbstub_io(FMT,...) gdbstub_printk(FMT, ##__VA_ARGS__)
#else
#define gdbstub_io(FMT,...) ({ 0; })
#endif
#ifdef GDBSTUB_DEBUG_PROTOCOL #ifdef GDBSTUB_DEBUG_PROTOCOL
#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__) #define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
#else #else

View File

@ -171,11 +171,11 @@ int gdbstub_rx_char(unsigned char *_ch, int nonblock)
return -EINTR; return -EINTR;
} }
else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) { else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
gdbstub_proto("### GDB Rx Error (st=%02x) ###\n",st); gdbstub_io("### GDB Rx Error (st=%02x) ###\n",st);
return -EIO; return -EIO;
} }
else { else {
gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n",ch,st); gdbstub_io("### GDB Rx %02x (st=%02x) ###\n",ch,st);
*_ch = ch & 0x7f; *_ch = ch & 0x7f;
return 0; return 0;
} }

View File

@ -1344,6 +1344,44 @@ void gdbstub_get_mmu_state(void)
} /* end gdbstub_get_mmu_state() */ } /* end gdbstub_get_mmu_state() */
/*
* handle general query commands of the form 'qXXXXX'
*/
static void gdbstub_handle_query(void)
{
if (strcmp(input_buffer, "qAttached") == 0) {
/* return current thread ID */
sprintf(output_buffer, "1");
return;
}
if (strcmp(input_buffer, "qC") == 0) {
/* return current thread ID */
sprintf(output_buffer, "QC 0");
return;
}
if (strcmp(input_buffer, "qOffsets") == 0) {
/* return relocation offset of text and data segments */
sprintf(output_buffer, "Text=0;Data=0;Bss=0");
return;
}
if (strcmp(input_buffer, "qSymbol::") == 0) {
sprintf(output_buffer, "OK");
return;
}
if (strcmp(input_buffer, "qSupported") == 0) {
/* query of supported features */
sprintf(output_buffer, "PacketSize=%u;ReverseContinue-;ReverseStep-",
sizeof(input_buffer));
return;
}
gdbstub_strcpy(output_buffer,"E01");
}
/*****************************************************************************/ /*****************************************************************************/
/* /*
* handle event interception and GDB remote protocol processing * handle event interception and GDB remote protocol processing
@ -1840,6 +1878,10 @@ void gdbstub(int sigval)
case 'k' : case 'k' :
goto done; /* just continue */ goto done; /* just continue */
/* detach */
case 'D':
gdbstub_strcpy(output_buffer, "OK");
break;
/* reset the whole machine (FIXME: system dependent) */ /* reset the whole machine (FIXME: system dependent) */
case 'r': case 'r':
@ -1852,6 +1894,14 @@ void gdbstub(int sigval)
__debug_status.dcr |= DCR_SE; __debug_status.dcr |= DCR_SE;
goto done; goto done;
/* extended command */
case 'v':
if (strcmp(input_buffer, "vCont?") == 0) {
output_buffer[0] = 0;
break;
}
goto unsupported_cmd;
/* set baud rate (bBB) */ /* set baud rate (bBB) */
case 'b': case 'b':
ptr = &input_buffer[1]; ptr = &input_buffer[1];
@ -1923,8 +1973,19 @@ void gdbstub(int sigval)
gdbstub_strcpy(output_buffer,"OK"); gdbstub_strcpy(output_buffer,"OK");
break; break;
/* Thread-setting packet */
case 'H':
gdbstub_strcpy(output_buffer, "OK");
break;
case 'q':
gdbstub_handle_query();
break;
default: default:
unsupported_cmd:
gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer); gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
gdbstub_strcpy(output_buffer,"E01");
break; break;
} }