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:
		
					parent
					
						
							
								c6f6b596a5
							
						
					
				
			
			
				commit
				
					
						7ca8b9c0da
					
				
			
		
					 3 changed files with 70 additions and 2 deletions
				
			
		| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue