forked from Imagelibrary/rtems
2001-03-05 Greg Menke <gregory.menke@gsfc.nasa.gov>
* 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.
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
2001-03-05 Greg Menke <gregory.menke@gsfc.nasa.gov>
|
||||
|
||||
* 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.
|
||||
|
||||
2001-03-01 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
* ChangeLog: Corrected previous entry.
|
||||
|
||||
@@ -2,6 +2,29 @@
|
||||
# $Id$
|
||||
#
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
Debugged this stub against the MongooseV bsp. Relies on putting break
|
||||
instructions on breakpoints and step targets- normal stuff, and does not
|
||||
employ hardware breakpoint support at this time. As written, a single
|
||||
breakpoint in a loop will not be reasserted unless the user steps or has
|
||||
a 2nd one, since breakpoints are only reset when the gdb stub is
|
||||
re-entered. A useful enhancement would be to fix the break instruction
|
||||
management so the stub could invisibly put a 2nd break after the 1st
|
||||
"official" one so it can silently reset breakpoints. Shouldn't be too
|
||||
hard, mostly a matter of working it out.
|
||||
|
||||
This was tested only against an R3000 MIPS. It should work OK on a
|
||||
R4000. Needs to be tested at some point.
|
||||
|
||||
This stub supports threads as implemented by gdb 5 and doesn't have any
|
||||
bugs I'm aware of.
|
||||
|
||||
Greg Menke
|
||||
3/5/2002
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
|
||||
The contents of this directory are based upon the "r46kstub.tar.gz" package
|
||||
released to the net by
|
||||
|
||||
@@ -49,6 +49,7 @@ const char* vhstr2int(const char *buf, int *ival);
|
||||
int hstr2byte(const char *buf, int *bval);
|
||||
int hstr2nibble(const char *buf, int *nibble);
|
||||
|
||||
Thread_Control *rtems_gdb_index_to_stub_id(int);
|
||||
int rtems_gdb_stub_thread_support_ok(void);
|
||||
int rtems_gdb_stub_get_current_thread(void);
|
||||
int rtems_gdb_stub_get_next_thread(int);
|
||||
@@ -159,4 +160,21 @@ void rtems_gdb_process_query(
|
||||
|
||||
#define NUM_REGS 72
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void mips_gdb_stub_install(int enableThreads) ;
|
||||
|
||||
|
||||
#define MEMOPT_READABLE 1
|
||||
#define MEMOPT_WRITEABLE 2
|
||||
|
||||
#define NUM_MEMSEGS 10
|
||||
|
||||
int gdbstub_add_memsegment(unsigned,unsigned,int);
|
||||
|
||||
|
||||
|
||||
#endif /* _GDB_IF_H */
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _LIMITS_H_
|
||||
#define _LIMITS_H_
|
||||
#ifndef _MEMLIMITS_H_
|
||||
#define _MEMLIMITS_H_
|
||||
|
||||
/*
|
||||
* The macros in this file are specific to a given implementation.
|
||||
@@ -45,6 +45,7 @@
|
||||
* to have different readability and/or writeability attributes.
|
||||
*/
|
||||
|
||||
/*
|
||||
#define K0_LIMIT_FOR_READ (K0BASE+0x18000000)
|
||||
#define K1_LIMIT_FOR_READ (K1BASE+K1SIZE)
|
||||
|
||||
@@ -67,4 +68,21 @@
|
||||
&& (((K0BASE <= (int)ptr) && ((int)ptr < K0_LIMIT_FOR_STEP)) \
|
||||
|| ((K1BASE <= (int)ptr) && ((int)ptr < K1_LIMIT_FOR_STEP))))
|
||||
|
||||
#endif /* _LIMITS_H_ */
|
||||
struct memseg
|
||||
{
|
||||
unsigned begin, end, opts;
|
||||
};
|
||||
|
||||
#define MEMOPT_READABLE 1
|
||||
#define MEMOPT_WRITEABLE 2
|
||||
|
||||
#define NUM_MEMSEGS 10
|
||||
|
||||
|
||||
int add_memsegment(unsigned,unsigned,int);
|
||||
int is_readable(unsigned,unsigned);
|
||||
int is_writeable(unsigned,unsigned);
|
||||
int is_steppable(unsigned);
|
||||
*/
|
||||
|
||||
#endif /* _MEMLIMITS_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
Thread_Control *th;
|
||||
|
||||
ASSERT(registers != NULL);
|
||||
th= rtems_gdb_index_to_stub_id(thread);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
if( th )
|
||||
{
|
||||
rtems_gdb_stub_get_registers_from_context( registers, th );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 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<type-1x>,<address-x>,<length-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];
|
||||
*out++ = gdb_hexchars[(count >> 4) & 0x0f];
|
||||
*out++ = gdb_hexchars[count & 0x0f];
|
||||
|
||||
if (done) {
|
||||
*out++ = '1';
|
||||
} else {
|
||||
*out++ = '0';
|
||||
}
|
||||
if (done) {
|
||||
*out++ = '1';
|
||||
} else {
|
||||
*out++ = '0';
|
||||
}
|
||||
|
||||
thread2fhstr(out, athread);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
Thread_Control *th;
|
||||
|
||||
ASSERT(registers != NULL);
|
||||
th= rtems_gdb_index_to_stub_id(thread);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
if( th )
|
||||
{
|
||||
rtems_gdb_stub_get_registers_from_context( registers, th );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 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<type-1x>,<address-x>,<length-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];
|
||||
*out++ = gdb_hexchars[(count >> 4) & 0x0f];
|
||||
*out++ = gdb_hexchars[count & 0x0f];
|
||||
|
||||
if (done) {
|
||||
*out++ = '1';
|
||||
} else {
|
||||
*out++ = '0';
|
||||
}
|
||||
if (done) {
|
||||
*out++ = '1';
|
||||
} else {
|
||||
*out++ = '0';
|
||||
}
|
||||
|
||||
thread2fhstr(out, athread);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user