From 2f89140dba7214f26e0104de2478ac8b723f3cf9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 8 Mar 2002 16:32:07 +0000 Subject: 2001-03-05 Greg Menke * mips-stub.c: Debugged & tweaked the gdb command processing, zbreak stuff, breakpoint and step code. Implemented 'T' command support and debugged remote gdb support w/ the Mongoose bsp. Added the memory segment support. * memlimits.h: Disabled all contents in favor of memory sement support. This file could probably go away. * rtems-stub-glue.c (rtems_gdb_index_to_stub_id()): New routine. rtems_gdb_stub_get_register_from_context(): Implemented MIPS version. rtems_gdb_stub_get_offsets(): Implemented MIPS version. * README: Updated. --- c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c | 416 ++++++++++++++-------- 1 file changed, 264 insertions(+), 152 deletions(-) (limited to 'c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c') diff --git a/c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c b/c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c index 6c525bb2a0..8d17911abf 100644 --- a/c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c +++ b/c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c @@ -29,7 +29,6 @@ */ #include - #include #include "gdb_if.h" @@ -40,6 +39,7 @@ extern const char gdb_hexchars[]; + /* * Prototypes for CPU dependent routines that are conditional * at the bottom of this file. @@ -50,6 +50,12 @@ void rtems_gdb_stub_get_registers_from_context( Thread_Control *th ); + + + + + + /* Check whether it is OK to enable thread support */ int rtems_gdb_stub_thread_support_ok(void) { @@ -59,6 +65,10 @@ int rtems_gdb_stub_thread_support_ok(void) return 0; } + + + + /* * rtems_gdb_stub_id_to_index * @@ -101,12 +111,84 @@ int rtems_gdb_stub_id_to_index( return first_posix_id + (thread_obj_id - min_id); } + + +/* Return the RTEMS thread id from a gdb thread id */ +Thread_Control *rtems_gdb_index_to_stub_id( + int thread +) +{ + Objects_Id thread_obj_id; + Objects_Id min_id, max_id; + int first_posix_id, first_rtems_id; + Objects_Information *obj_info; + Thread_Control *th; + + ASSERT(registers != NULL); + + if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { + /* Should not happen */ + return NULL; + } + + if (thread == 1) { + th = _Thread_Idle; + goto found; + } + + /* Let us get object associtated with current thread */ + first_rtems_id = 2; + + thread_obj_id = _Thread_Executing->Object.id; + + /* Let us figure out thread_id for gdb */ + obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; + + min_id = obj_info->minimum_id; + max_id = obj_info->maximum_id; + + if (thread <= (first_rtems_id + (max_id - min_id))) { + th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); + + if (th != NULL) { + goto found; + } + + /* Thread does not exist */ + return NULL; + } + + first_posix_id = first_rtems_id + (max_id - min_id) + 1; + + obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; + + min_id = obj_info->minimum_id; + max_id = obj_info->maximum_id; + + th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); + if (th == NULL) { + /* Thread does not exist */ + return NULL; + } + + found: + return th; +} + + + + + + /* Get id of the thread stopped by exception */ int rtems_gdb_stub_get_current_thread(void) { return rtems_gdb_stub_id_to_index( _Thread_Executing->Object.id ); } + + + /* Get id of the next thread after athread, if argument <= 0 find the first available thread, return thread if found or 0 if not */ int rtems_gdb_stub_get_next_thread(int athread) @@ -176,6 +258,10 @@ int rtems_gdb_stub_get_next_thread(int athread) } + + + + /* Get thread registers, return 0 if thread does not exist, and 1 otherwise */ int rtems_gdb_stub_get_thread_regs( @@ -183,70 +269,27 @@ int rtems_gdb_stub_get_thread_regs( unsigned int *registers ) { - Objects_Id thread_obj_id; - Objects_Id min_id, max_id; - int first_posix_id, first_rtems_id; - Objects_Information *obj_info; - Thread_Control *th; - - ASSERT(registers != NULL); + Thread_Control *th; - if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { - /* Should not happen */ - return 0; - } - - if (thread == 1) { - th = _Thread_Idle; - goto found; - } - - /* Let us get object associtated with current thread */ - first_rtems_id = 2; - - thread_obj_id = _Thread_Executing->Object.id; - - /* Let us figure out thread_id for gdb */ - obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; - - min_id = obj_info->minimum_id; - max_id = obj_info->maximum_id; + th= rtems_gdb_index_to_stub_id(thread); - if (thread <= (first_rtems_id + (max_id - min_id))) { - th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); - - if (th != NULL) { - goto found; - } - - /* Thread does not exist */ - return 0; - } - - first_posix_id = first_rtems_id + (max_id - min_id) + 1; - - obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; - - min_id = obj_info->minimum_id; - max_id = obj_info->maximum_id; + if( th ) + { + rtems_gdb_stub_get_registers_from_context( registers, th ); + return 1; + } + return 0; +} - th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); - if (th == NULL) { - /* Thread does not exist */ - return 0; - } -found: - rtems_gdb_stub_get_registers_from_context( registers, th ); - return 1; -} /* Set thread registers, return 0 if thread does not exist or register values will screw up the threads, and 1 otherwise */ + int rtems_gdb_stub_set_thread_regs( int thread, unsigned int *registers @@ -260,6 +303,10 @@ int rtems_gdb_stub_set_thread_regs( } + + + + /* Get thread information, return 0 if thread does not exist and 1 otherwise */ int rtems_gdb_stub_get_thread_info( @@ -267,122 +314,126 @@ int rtems_gdb_stub_get_thread_info( struct rtems_gdb_stub_thread_info *info ) { - Objects_Id thread_obj_id; - Objects_Id min_id, max_id; - int first_posix_id, first_rtems_id; - Objects_Information *obj_info; - Thread_Control *th; - unsigned32 name; - char tmp_buf[20]; + Objects_Id thread_obj_id; + Objects_Id min_id, max_id; + int first_posix_id, first_rtems_id; + Objects_Information *obj_info; + Thread_Control *th; + unsigned32 name; + char tmp_buf[20]; - ASSERT(info != NULL); + ASSERT(info != NULL); - if (thread <= 0) { - return 0; - } + if (thread <= 0) { + return 0; + } - if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) { - /* We have one thread let us use value + if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) { + /* We have one thread let us use value which will never happen for real thread */ - strcpy(info->display, "idle thread"); - strcpy(info->name, "IDLE"); - info->more_display[0] = 0; /* Nothing */ + strcpy(info->display, "idle thread"); + strcpy(info->name, "IDLE"); + info->more_display[0] = 0; /* Nothing */ - return 1; - } + return 1; + } - /* Let us get object associtated with current thread */ - thread_obj_id = _Thread_Executing->Object.id; + /* Let us get object associtated with current thread */ + thread_obj_id = _Thread_Executing->Object.id; - /* Let us figure out thread_id for gdb */ - first_rtems_id = 2; + /* Let us figure out thread_id for gdb */ + first_rtems_id = 2; - obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; + obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; - min_id = obj_info->minimum_id; - max_id = obj_info->maximum_id; + min_id = obj_info->minimum_id; + max_id = obj_info->maximum_id; - if (thread <= (first_rtems_id + (max_id - min_id))) { + if (thread <= (first_rtems_id + (max_id - min_id))) { th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); - if (th == NULL) { - /* Thread does not exist */ - return 0; - } + if (th == NULL) { + /* Thread does not exist */ + return 0; + } - strcpy(info->display, "rtems task: control at 0x"); + strcpy(info->display, "rtems task: control at 0x"); - tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; - tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; - tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; - tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; - tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; - tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; - tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; - tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; - tmp_buf[8] = 0; + tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; + tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; + tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; + tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; + tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; + tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; + tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; + tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; + tmp_buf[8] = 0; - strcat(info->display, tmp_buf); + strcat(info->display, tmp_buf); - name = *(unsigned32 *)(obj_info->local_table[thread]->name); + name = *(unsigned32 *)(obj_info->local_table[thread]->name); - info->name[0] = (name >> 24) & 0xff; - info->name[1] = (name >> 16) & 0xff; - info->name[2] = (name >> 8) & 0xff; - info->name[3] = name & 0xff; - info->name[4] = 0; + info->name[0] = (name >> 24) & 0xff; + info->name[1] = (name >> 16) & 0xff; + info->name[2] = (name >> 8) & 0xff; + info->name[3] = name & 0xff; + info->name[4] = 0; - info->more_display[0] = 0; /* Nothing */ + info->more_display[0] = 0; /* Nothing */ - return 1; -} + return 1; + } - first_posix_id = first_rtems_id + (max_id - min_id) + 1; + first_posix_id = first_rtems_id + (max_id - min_id) + 1; - obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; + obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; - min_id = obj_info->minimum_id; - max_id = obj_info->maximum_id; + min_id = obj_info->minimum_id; + max_id = obj_info->maximum_id; - th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); - if (th == NULL) - { + th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); + if (th == NULL) + { /* Thread does not exist */ return 0; - } + } - strcpy(info->display, "posix thread: control at 0x"); + strcpy(info->display, "posix thread: control at 0x"); - tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; - tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; - tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; - tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; - tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; - tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; - tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; - tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; - tmp_buf[8] = 0; + tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; + tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; + tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; + tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; + tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; + tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; + tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; + tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; + tmp_buf[8] = 0; - strcat(info->display, tmp_buf); + strcat(info->display, tmp_buf); - name = *(unsigned32 *)(obj_info->local_table[thread - - first_posix_id + 1]->name); + name = *(unsigned32 *)(obj_info->local_table[thread - + first_posix_id + 1]->name); - info->name[0] = (name >> 24) & 0xff; - info->name[1] = (name >> 16) & 0xff; - info->name[2] = (name >> 8) & 0xff; - info->name[3] = name & 0xff; - info->name[4] = 0; + info->name[0] = (name >> 24) & 0xff; + info->name[1] = (name >> 16) & 0xff; + info->name[2] = (name >> 8) & 0xff; + info->name[3] = name & 0xff; + info->name[4] = 0; - info->more_display[0] = 0; /* Nothing */ + info->more_display[0] = 0; /* Nothing */ - return 1; + return 1; } /*******************************************************/ + + + + /* Format: x,,, where x is 'z' or 'Z' */ int parse_zbreak(const char *in, int *type, unsigned char **addr, int *len) { @@ -597,27 +648,36 @@ pack_qm_thread(char *out, int thread) static void pack_qm_header(char *out, int count, int done, int athread) { - ASSERT(out != 0); - ASSERT(count >= 0 && count < 256); + ASSERT(out != 0); + ASSERT(count >= 0 && count < 256); - *out++ = 'q'; - *out++ = 'M'; + *out++ = 'q'; + *out++ = 'M'; - *out++ = gdb_hexchars[(count >> 4) & 0x0f]; - *out++ = gdb_hexchars[count & 0x0f]; - - if (done) { - *out++ = '1'; - } else { - *out++ = '0'; - } + *out++ = gdb_hexchars[(count >> 4) & 0x0f]; + *out++ = gdb_hexchars[count & 0x0f]; - thread2fhstr(out, athread); + if (done) { + *out++ = '1'; + } else { + *out++ = '0'; + } - return; + thread2fhstr(out, athread); + return; } + + + + + + + + + + void rtems_gdb_process_query( char *inbuffer, char *outbuffer, @@ -642,6 +702,9 @@ void rtems_gdb_process_query( *optr = 0; break; + + + case 'P': /* Thread info query */ if (!do_threads) { @@ -669,10 +732,14 @@ void rtems_gdb_process_query( /* Build response */ pack_qq(outbuffer, mask, rthread, &info); } - break; + + + + + case 'L': - /* Thread info query */ + /* Thread list query */ if (!do_threads) { break; } @@ -724,9 +791,14 @@ void rtems_gdb_process_query( /* Fill header */ pack_qm_header(outbuffer, i, done, athread); - } break; + + + + + + default: if (memcmp(inbuffer, "qOffsets", 8) == 0) { unsigned char *t, *d, *b; @@ -772,9 +844,13 @@ void rtems_gdb_process_query( /* qCRC, qRcmd, qu and qz will be added here */ break; } - } + + + + + /* Present thread in the variable length string format */ char* thread2vhstr(char *buf, int thread) @@ -1196,6 +1272,7 @@ set_mem_err (void) that the compiler won't save any registers (if there is a fault to mem_fault, they won't get restored, so there better not be any saved). */ + unsigned char get_byte (const unsigned char *addr) { @@ -1210,6 +1287,12 @@ set_byte (unsigned char *addr, int val) + + + + + + /* * From here down, the code is CPU model specific and generally maps * the RTEMS thread context format to gdb's. @@ -1273,24 +1356,53 @@ int rtems_gdb_stub_get_offsets( return 1; } + + + + #elif defined(__mips__) + + void rtems_gdb_stub_get_registers_from_context( int *registers, Thread_Control *th ) { + registers[S0] = (unsigned)th->Registers.s0; + registers[S1] = (unsigned)th->Registers.s1; + registers[S2] = (unsigned)th->Registers.s2; + registers[S3] = (unsigned)th->Registers.s3; + registers[S4] = (unsigned)th->Registers.s4; + registers[S5] = (unsigned)th->Registers.s5; + registers[S6] = (unsigned)th->Registers.s6; + registers[S7] = (unsigned)th->Registers.s7; + + registers[SP] = (unsigned)th->Registers.sp; + registers[RA] = (unsigned)th->Registers.ra; + + registers[SR] = (unsigned)th->Registers.c0_sr; + registers[PC] = (unsigned)th->Registers.c0_epc; } + int rtems_gdb_stub_get_offsets( unsigned char **text_addr, unsigned char **data_addr, unsigned char **bss_addr ) -{ +{ +/* + extern unsigned32 _ftext; + extern unsigned32 _fdata; + extern unsigned32 _bss_start; + + *text_addr = &_ftext; + *data_addr = &_fdata; + *bss_addr = &_bss_start; +*/ *text_addr = 0; *data_addr = 0; *bss_addr = 0; - return 1; } -- cgit v1.2.3