* So many patches have been posted recently on the mailing list and

because we were unable to find correct solution to compile on various
	linux distros (due to rpcgen incompatibilities), and because the coding
	style of rdbg was rather inconsistant among various pieces of code, I
	decided to:
	    1) make some cleaning regarding global coding style (using
	       indent + manual edits),
	    2) incorporate/review the paches send by various people
	       (S. Holford, T. Strauman),
	    3) Fix the bug due to varying rpcgen code generation
	       in remdeb_svc.c,
	    4) Remove some dead code,
	    5) Apply a patches enabling to call enterRdbg imediately
	       after rdbg initialization is done,

	NB : the paches is huge but it is mainly due to coding styke chnages.
	Only few lines of codes have been really changed and they do not impact
	rdbg functionnality (AFAIKT).

	* include/rdbg/servrpc.h, include/rdbg/i386/rdbg_f.h,
	include/rdbg/m68k/rdbg_f.h, include/rdbg/powerpc/rdbg_f.h,
	src/_servtgt.c, src/awk.svc, src/excep.c, src/ptrace.c, src/rdbg.c,
	src/remdeb.x, src/servbkpt.c, src/servcon.c, src/servrpc.c,
	src/servtgt.c, src/servtsp.c, src/servutil.c, src/i386/excep_f.c,
	src/i386/rdbg_f.c, src/i386/any/Makefile.am, src/i386/any/remdeb.h,
	src/i386/any/remdeb_svc.c, src/i386/any/remdeb_xdr.c,
	src/m68k/excep_f.c, src/m68k/rdbg_f.c, src/m68k/any/Makefile.am,
	src/m68k/any/remdeb.h, src/m68k/any/remdeb_svc.c,
	src/m68k/any/remdeb_xdr.c, src/powerpc/excep_f.c, src/powerpc/rdbg_f.c,
	src/powerpc/new_exception_processing/Makefile.am,
	src/powerpc/new_exception_processing/remdeb.h,
	src/powerpc/new_exception_processing/remdeb_svc.c,
	src/powerpc/new_exception_processing/remdeb_xdr.c: Modified.
This commit is contained in:
Joel Sherrill
2002-02-01 17:00:01 +00:00
parent 8e3caa52cd
commit 40cf43eab4
35 changed files with 5725 additions and 5455 deletions

View File

@@ -1,3 +1,38 @@
* So many patches have been posted recently on the mailing list and
because we were unable to find correct solution to compile on various
linux distros (due to rpcgen incompatibilities), and because the coding
style of rdbg was rather inconsistant among various pieces of code, I
decided to:
1) make some cleaning regarding global coding style (using
indent + manual edits),
2) incorporate/review the paches send by various people
(S. Holford, T. Strauman),
3) Fix the bug due to varying rpcgen code generation
in remdeb_svc.c,
4) Remove some dead code,
5) Apply a patches enabling to call enterRdbg imediately
after rdbg initialization is done,
NB : the paches is huge but it is mainly due to coding styke chnages.
Only few lines of codes have been really changed and they do not impact
rdbg functionnality (AFAIKT).
* include/rdbg/servrpc.h, include/rdbg/i386/rdbg_f.h,
include/rdbg/m68k/rdbg_f.h, include/rdbg/powerpc/rdbg_f.h,
src/_servtgt.c, src/awk.svc, src/excep.c, src/ptrace.c, src/rdbg.c,
src/remdeb.x, src/servbkpt.c, src/servcon.c, src/servrpc.c,
src/servtgt.c, src/servtsp.c, src/servutil.c, src/i386/excep_f.c,
src/i386/rdbg_f.c, src/i386/any/Makefile.am, src/i386/any/remdeb.h,
src/i386/any/remdeb_svc.c, src/i386/any/remdeb_xdr.c,
src/m68k/excep_f.c, src/m68k/rdbg_f.c, src/m68k/any/Makefile.am,
src/m68k/any/remdeb.h, src/m68k/any/remdeb_svc.c,
src/m68k/any/remdeb_xdr.c, src/powerpc/excep_f.c, src/powerpc/rdbg_f.c,
src/powerpc/new_exception_processing/Makefile.am,
src/powerpc/new_exception_processing/remdeb.h,
src/powerpc/new_exception_processing/remdeb_svc.c,
src/powerpc/new_exception_processing/remdeb_xdr.c: Modified.
2002-01-18 Till Straumann <strauman@slac.stanford.edu>
* src/powerpc/excep_f.c: This patch addresses the following issues:

View File

@@ -34,6 +34,7 @@ static inline int getExcNum(Exception_context *ctx)
}
extern void connect_rdbg_exception();
extern void disconnect_rdbg_exception();
#endif

View File

@@ -32,6 +32,7 @@ static inline int getExcNum(Exception_context *ctx)
}
extern void connect_rdbg_exception();
extern void disconnect_rdbg_exception();
#endif

View File

@@ -21,6 +21,7 @@ static inline int isRdbgException(Exception_context *ctx)
{
if (
ctx->ctx->_EXC_number != ASM_SYS_VECTOR &&
ctx->ctx->_EXC_number != ASM_PROG_VECTOR &&
ctx->ctx->_EXC_number != ASM_TRACE_VECTOR
) return 0;
else return 1;
@@ -31,6 +32,7 @@ static inline int getExcNum(Exception_context *ctx)
}
extern void connect_rdbg_exception();
extern void disconnect_rdbg_exception();
#endif

View File

@@ -23,7 +23,7 @@ extern int CONN_LIST_INC;
extern int PID_LIST_INC;
extern int TSP_RETRIES;
extern int BackPort;
extern char ActName[];
extern char taskName[];
extern int getId();

View File

@@ -5,16 +5,15 @@
============================================================================
*/
#include <string.h>
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
#include <rdbg/rdbg.h>
#include <rdbg/rdbg_f.h>
#include <rdbg/servrpc.h>
#include <rdbg/servrpc.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <assert.h>
#include <rtems/score/cpu.h>
@@ -29,6 +28,7 @@ extern int errno;
rtems_id eventTaskId;
rtems_id serializeSemId;
rtems_id wakeupEventSemId;
rtems_id debugId;
CPU_Exception_frame Idle_frame;
@@ -36,59 +36,56 @@ CPU_Exception_frame Idle_frame;
TgtRealPtrace - lowest level ptrace() wrapper
----------------------------------------------------------------- */
int
TgtRealPtrace(int req, PID aid, char* addr, int d, void* addr2)
int
TgtRealPtrace (int req, PID aid, char *addr, int d, void *addr2)
{
return ptrace(req, aid, addr, d, addr2);
return ptrace (req, aid, addr, d, addr2);
}
/* -----------------------------------------------------------------------
TgtChange() is called when the system stops.
It informs the generic layers must be informed of
that fact.
----------------------------------------------------------------------- */
static int
TgtChange (PID pid, CPU_Exception_frame* ctx, int status)
static int
TgtChange (PID pid, CPU_Exception_frame * ctx, int status)
{
if (TgtHandleChildChange (pid, &status, NULL, ctx)) {
TgtNotifyWaitChange (pid, status, -1);
}
if (TgtHandleChildChange (pid, &status, NULL, ctx)) {
TgtNotifyWaitChange (pid, status, -1);
}
return 0;
return 0;
}
/* -----------------------------------------------------------------------
eventTask
----------------------------------------------------------------------- */
rtems_task eventTask( rtems_task_argument pid)
rtems_task
eventTask (rtems_task_argument pid)
{
Exception_context *ctx;
DPRINTF (("event task: pid %d\n", pid));
/*
* we spend all our time waiting for a semaphore.
* If wait change, we send info
*/
for (;;){
for (;;) {
DPRINTF (("Event Task: wait event\n"));
rtems_semaphore_obtain(wakeupEventSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (wakeupEventSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
DPRINTF (("Event Task: wake up !!!!!!!!!!!!!\n"));
errno = 0;
ctx = GetExceptCtx(currentTargetThread);
ctx = GetExceptCtx (currentTargetThread);
CheckForSingleStep(ctx->ctx);
CheckForSingleStep (ctx->ctx);
TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx)));
TgtChange (pid, ctx->ctx, STS_MAKESIG (ExcepToSig (ctx)));
}
}
@@ -100,10 +97,11 @@ rtems_task eventTask( rtems_task_argument pid)
only to push a first valid context in the list
---------------------------------------------------------------------*/
rtems_task MyThreadIdle(rtems_task_argument argument)
rtems_task
MyThreadIdle (rtems_task_argument argument)
{
enterRdbg();
rtems_task_delete( RTEMS_SELF );
enterRdbg ();
rtems_task_delete (RTEMS_SELF);
}
/* -----------------------------------------------------------------------
@@ -114,192 +112,206 @@ rtems_task MyThreadIdle(rtems_task_argument argument)
process that we do not control now).
----------------------------------------------------------------------- */
Boolean TgtAttach(
int conn_idx, /* client that is requesting */
PID pid) /* process to attach to */
{
Boolean
TgtAttach (int conn_idx, /* client that is requesting */
PID pid)
{ /* process to attach to */
rtems_name task_name;
rtems_status_code status;
rtems_id debugId;
errno = 0;
DPRINTF (("TgtAttach pid=%d\n",pid));
Ptrace(RPT_ATTACH, pid, NULL, 0, NULL);
DPRINTF (("TgtAttach pid=%d\n", pid));
Ptrace (RPT_ATTACH, pid, NULL, 0, NULL);
if (errno)
return(False); /* failed */
return (False); /* failed */
TgtCreateNew(pid, conn_idx, 0, NULL, False);
TgtCreateNew (pid, conn_idx, 0, NULL, False);
connect_rdbg_exception ();
connect_rdbg_exception();
/*
* Create the attach debuger task
* Search for and remove debugging tasks / semaphores left over from
* a previous attach without a detach.
*/
task_name = rtems_build_name( 'E', 'v', 'n', 't' );
if ((status = rtems_task_create( task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES | RTEMS_SYSTEM_TASK,
&eventTaskId ))
!= RTEMS_SUCCESSFUL){
printf("status = %d\n",status);
if (rtems_task_ident (rtems_build_name ('E', 'v', 'n', 't'),
RTEMS_SEARCH_ALL_NODES,
&eventTaskId) == RTEMS_SUCCESSFUL)
rtems_task_delete (eventTaskId);
if (rtems_semaphore_ident (rtems_build_name ('D', 'B', 'G', 's'),
RTEMS_SEARCH_ALL_NODES,
&serializeSemId) == RTEMS_SUCCESSFUL)
rtems_semaphore_delete (serializeSemId);
if (rtems_semaphore_ident (rtems_build_name ('D', 'B', 'G', 'w'),
RTEMS_SEARCH_ALL_NODES,
&wakeupEventSemId) == RTEMS_SUCCESSFUL)
rtems_semaphore_delete (wakeupEventSemId);
/*
* Create the attach debugger task
*/
task_name = rtems_build_name ('E', 'v', 'n', 't');
if ((status = rtems_task_create (task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL (0),
RTEMS_DEFAULT_ATTRIBUTES |
RTEMS_SYSTEM_TASK, &eventTaskId))
!= RTEMS_SUCCESSFUL) {
printf ("status = %d\n", status);
rtems_panic ("Can't create task.\n");
}
status = rtems_task_start(eventTaskId, eventTask, pid);
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 's'),
1,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&serializeSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create serialize semaphore: `%s'\n",rtems_status_text(status));
status = rtems_task_start (eventTaskId, eventTask, pid);
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'w'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&wakeupEventSemId);
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 's'),
1,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL, 0, &serializeSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create wakeup semaphore: `%s'\n",rtems_status_text(status));
rtems_panic ("Can't create serialize semaphore: `%s'\n",
rtems_status_text (status));
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'w'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL, 0, &wakeupEventSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create wakeup semaphore: `%s'\n",
rtems_status_text (status));
/*
* Create the MyThreadIdle task to init Exception mechanism
*/
task_name = rtems_build_name( 'R', 'i', 'n', 'i' );
if ((status = rtems_task_create( task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&debugId ))
!= RTEMS_SUCCESSFUL){
printf("status = %d (%s)\n",status,rtems_status_text(status));
task_name = rtems_build_name ('R', 'i', 'n', 'i');
if ((status = rtems_task_create (task_name, 10, 24576,
RTEMS_INTERRUPT_LEVEL (0),
RTEMS_DEFAULT_ATTRIBUTES, &debugId))
!= RTEMS_SUCCESSFUL) {
printf ("status = %d (%s)\n", status, rtems_status_text (status));
rtems_panic ("Can't create task.\n");
}
status = rtems_task_start(debugId, MyThreadIdle, pid);
status = rtems_task_start (debugId, MyThreadIdle, pid);
return(True);
return (True);
}
/* -----------------------------------------------------------------------
TgtPtrace - handle ptrace requests for server.
----------------------------------------------------------------------- */
int TgtPtrace(
int req,
PID pid,
char *addr,
int data,
void *addr2)
int
TgtPtrace (int req, PID pid, char *addr, int data, void *addr2)
{
if ((req == RPT_SINGLESTEP || req == RPT_CONT)
&& addr2) /* clear then step */
{ /* addr2 is the old value */
int ret;
&& addr2) { /* clear then step *//* addr2 is the old value */
int ret;
errno = 0;
TgtBreakRestoreOrig (pid, addr, addr2);
ret = Ptrace(RPT_SINGLESTEP, pid, addr, data, NULL); /* step over */
if (ret) /* error, cannot single-step */
{
ret = Ptrace (RPT_SINGLESTEP, pid, addr, data, NULL); /* step over */
if (ret) { /* error, cannot single-step */
int pid_idx = FindPidEntry (pid);
TgtBreakCancelStep (&pid_list [pid_idx]);
TgtBreakCancelStep (&pid_list[pid_idx]);
}
return(ret); /* failed or done */
}
else
return(Ptrace(req, pid, addr, data, addr2)); /* normal call */
return (ret); /* failed or done */
} else
return (Ptrace (req, pid, addr, data, addr2)); /* normal call */
}
/* -----------------------------------------------------------------
TgtGetThreadName - get thread name
--------------------------------------------------------------- */
int TgtGetThreadName (
PID_LIST *plst, /* Process entry */
unsigned Id, /* Thread ID */
char *ThrName) /* Thread name */
{
int index;
unsigned name;
if ( Id <_Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
int
TgtGetThreadName (PID_LIST * plst, /* Process entry */
unsigned Id, /* Thread ID */
char *ThrName)
{ /* Thread name */
int index;
unsigned name;
index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
name = *(unsigned*)(_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index]->name);
ThrName[0] = (char)((name >> 24) & 0xFF );
ThrName[1] = (char)((name >> 16) & 0xFF );
ThrName[2] = (char)((name >> 8) & 0xFF );
ThrName[3] = (char)( name & 0xFF );
ThrName[4] = 0x0;
return 0;
}
if ( Id <_Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
if (Id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id > _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
index = Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
name = *(unsigned*)(_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index]->name);
ThrName[0] = (char)((name >> 24) & 0xFF );
ThrName[1] = (char)((name >> 16) & 0xFF );
ThrName[2] = (char)((name >> 8) & 0xFF );
ThrName[3] = (char)( name & 0xFF );
ThrName[4] = 0x0;
return 0;
}
return -1;
index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
name =
*(unsigned *) (_Objects_Information_table[OBJECTS_RTEMS_TASKS]->
local_table[1 + index]->name);
ThrName[0] = (char) ((name >> 24) & 0xFF);
ThrName[1] = (char) ((name >> 16) & 0xFF);
ThrName[2] = (char) ((name >> 8) & 0xFF);
ThrName[3] = (char) (name & 0xFF);
ThrName[4] = 0x0;
return 0;
}
if (Id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id > _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
index =
Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
name =
*(unsigned *) (_Objects_Information_table[OBJECTS_POSIX_THREADS]->
local_table[1 + index]->name);
ThrName[0] = (char) ((name >> 24) & 0xFF);
ThrName[1] = (char) ((name >> 16) & 0xFF);
ThrName[2] = (char) ((name >> 8) & 0xFF);
ThrName[3] = (char) (name & 0xFF);
ThrName[4] = 0x0;
return 0;
}
return -1;
}
/* -----------------------------------------------------------------
TgtThreadList - return all the threads in the system
----------------------------------------------------------------- */
int
TgtThreadList (
PID_LIST* plst, /* Process entry */
unsigned* threads, /* Output buffer */
unsigned size) /* Output buffer size */
{
int curr = 0;
Objects_Id id;
unsigned index;
int
TgtThreadList (PID_LIST * plst, /* Process entry */
unsigned *threads, /* Output buffer */
unsigned size)
{ /* Output buffer size */
int curr = 0;
Objects_Id id;
unsigned index;
id = _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
id = _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
while (id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id){
index = id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index] != NULL){
while (id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id) {
index = id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
if (_Objects_Information_table[OBJECTS_RTEMS_TASKS]->
local_table[1 + index] != NULL) {
threads[curr] = (unsigned) id;
curr++;
}
id ++;
}
id = _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
id++;
}
while (id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id){
index = id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index] != NULL){
id = _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
while (id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id) {
index =
id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
if (_Objects_Information_table[OBJECTS_POSIX_THREADS]->
local_table[1 + index] != NULL) {
threads[curr] = (unsigned) id;
curr++;
}
id ++;
}
return curr;
id++;
}
return curr;
}

View File

@@ -26,7 +26,7 @@ $1 ~ /^\/\*HEADER_START\*\/$/ {
printf("#include <bsp.h>\n");
printf("#include <rdbg/servrpc.h>\n");
printf("#include <rdbg/%s>\n", THEPROG);
printf("#define fprintf(a,b) printf(b)\n");
printf("#define fprintf(a,b,c) printf(b,c)\n");
}
$1 ~ /^\/\*HEADER_END\*\/$/ {

View File

@@ -24,30 +24,32 @@ Exception_context *LastCtx = NULL;
CPU_Exception_frame SavedContext;
/*
* Save an exception context at the end of a list
*/
/********* Save an exception context at the end of a list *****/
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
int
PushExceptCtx (Objects_Id Id, Objects_Id semId, CPU_Exception_frame * ctx)
{
Exception_context *SaveCtx;
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
SaveCtx = (Exception_context *) malloc (sizeof (Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
rtems_panic ("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
if (FirstCtx == NULL) { /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
} else {
NbExceptCtx++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
@@ -55,36 +57,41 @@ int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx )
return 0;
}
/********* Save an temporary exception context in a ******/
/********* global variable ******/
/*
* Save an temporary exception context in a global variable
*/
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
int
PushSavedExceptCtx (Objects_Id Id, CPU_Exception_frame * ctx)
{
memcpy (&(SavedContext), ctx, sizeof (CPU_Exception_frame));
return 0;
}
/*
* Remove the context of the specified Id thread.
* If Id = -1, then return the first context
*/
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
int PopExceptCtx ( Objects_Id Id ) {
int
PopExceptCtx (Objects_Id Id)
{
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
if (FirstCtx == NULL)
return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
free (ExtractCtx);
NbExceptCtx--;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
@@ -92,37 +99,40 @@ int PopExceptCtx ( Objects_Id Id ) {
if (ExtractCtx == NULL)
return -1;
if ( ExtractCtx->previous != NULL)
if (ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
if ( ExtractCtx->next != NULL)
if (ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
else if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
free (ExtractCtx);
NbExceptCtx--;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
/*
* Return the context of the specified Id thread.
* If Id = -1, then return the first context.
*/
Exception_context *GetExceptCtx ( Objects_Id Id ) {
Exception_context *
GetExceptCtx (Objects_Id Id)
{
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
if (FirstCtx == NULL)
return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {

View File

@@ -71,6 +71,8 @@ if RPCTOOLS
-o i386/any/tmpSvc.c remdeb.x; \
$(AWK) -f ./awk.svc THEPROG="remdeb.h" i386/any/tmpSvc.c \
> i386/any/remdeb_svc.c; \
$(SED) -e 's/fprintf.*,/printf(/' i386/any/remdeb_svc.c > i386/any/remdeb_svc.tmp; \
mv i386/any/remdeb_svc.tmp i386/any/remdeb_svc.c; \
rm -f i386/any/tmpSvc.c )
endif

View File

@@ -8,7 +8,6 @@
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -18,85 +17,84 @@ extern "C" {
#ifndef REMDEB_H
#define RPCGENSRVNAME(a) a
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
#define NET_SAFE 1400
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
/*
* Sun request values for the remote ptrace system call
*/
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
struct xdr_regs {
u_int tabreg[19];
};
typedef struct xdr_regs xdr_regs;
struct xdr_regs {
u_int tabreg[19];
};
typedef struct xdr_regs xdr_regs;
/* now define register macros to apply to xdr_reg struct */
#define GS 0
@@ -119,16 +117,16 @@ typedef struct xdr_regs xdr_regs;
#define UESP 17
#define SS 18
#define REG_PC tabreg[EIP] /* PC (eip) register offset */
#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
#define REG_PC tabreg[EIP] /* PC (eip) register offset */
#define REG_SP tabreg[UESP] /* SP (uesp) register offset */
#define REG_FP tabreg[EBP] /* FP (ebp) register offset */
/* now define the BREAKPOINT mask technique to a long word */
#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
#define SET_BREAK(l) ((l&0xFFFFFF00) | 0xCC)
#define IS_BREAK(l) (((l) & 0xFF) == 0xCC)
#define ORG_BREAK(c,p) (((c) & 0xFFFFFF00) | ((p) & 0xFF))
#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
#define BREAK_ADJ 1 /* must subtract one from address after bp */
#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
#define IS_STEP(regs) (regs.tabreg[TRAPNO] == 1) /* was step and not break */
#define BREAK_ADJ 1 /* must subtract one from address after bp */
#define BREAK_SIZE 1 /* Breakpoint occupies one byte */
#define TARGET_PROC_TYPE 0
#define MAXDEBUGGEE 150
#define NAMEMAX 17
@@ -141,286 +139,298 @@ typedef struct xdr_regs xdr_regs;
*/
#define MEM_DATA_MAX 256
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
#define MAX_THRD_BRK 4
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
#define UTHREAD_MAX 64
#define THREADNAMEMAX 16
typedef char *thread_name;
typedef char *thread_name;
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
#define XRY_MAX_INST_BUFF 128
#define XRY_MAX_INSTANCES 16
#ifndef XRY_MAX_CMD_STR
#define XRY_MAX_CMD_STR 320
#endif /* REMDEB_H */
#endif /* REMDEB_H */
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
typedef char *one_arg;
typedef char *one_arg;
#define XRY_MAX_OBJ_NAME 32
/* now open_connex() routine which establishes a connection to server */
/*
* now open_connex() routine which establishes a connection to server
*/
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/* now close_connex() routine which detaches from server */
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/*
* now close_connex() routine which detaches from server
*/
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/* now send_signal() routine which sends signals to processes like kill(2) */
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/*
* now send_signal() routine which sends signals to processes like kill(2)
*/
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/*
* now wait_info() routine which returns results of polling the wait status
* of a process/actor. It may return 0 if running, else pid or -1
*/
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/*
* now ptrace() routine. This matches the Sun UNIX ptrace as well as
* some additions
*/
#define PTRFLG_FORCE 1
#define PTRFLG_NON_OWNER 2
#define PTRFLG_FREE 4
#define PTRDET_UNOWN 0x100
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/* now define the actual calls we support */
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/*
* now define the actual calls we support
*/
#define REMDEB_H
#endif
@@ -429,131 +439,131 @@ typedef struct get_signal_names_out get_signal_names_out;
#if defined(__STDC__) || defined(__cplusplus)
#define OPEN_CONNEX 1
extern open_out * open_connex_2(open_in *, CLIENT *);
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
extern open_out *open_connex_2 (open_in *, CLIENT *);
extern open_out *open_connex_2_svc (open_in *, struct svc_req *);
#define SEND_SIGNAL 2
extern signal_out * send_signal_2(signal_in *, CLIENT *);
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
extern signal_out *send_signal_2 (signal_in *, CLIENT *);
extern signal_out *send_signal_2_svc (signal_in *, struct svc_req *);
#define CLOSE_CONNEX 10
extern void * close_connex_2(close_in *, CLIENT *);
extern void * close_connex_2_svc(close_in *, struct svc_req *);
extern void *close_connex_2 (close_in *, CLIENT *);
extern void *close_connex_2_svc (close_in *, struct svc_req *);
#define PTRACE 11
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
extern ptrace_out *ptrace_2 (ptrace_in *, CLIENT *);
extern ptrace_out *ptrace_2_svc (ptrace_in *, struct svc_req *);
#define WAIT_INFO 13
extern wait_out * wait_info_2(wait_in *, CLIENT *);
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
extern wait_out *wait_info_2 (wait_in *, CLIENT *);
extern wait_out *wait_info_2_svc (wait_in *, struct svc_req *);
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
extern get_signal_names_out *get_signal_names_2 (void *, CLIENT *);
extern get_signal_names_out *get_signal_names_2_svc (void *,
struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#else /* K&R C */
#define OPEN_CONNEX 1
extern open_out * open_connex_2();
extern open_out * open_connex_2_svc();
extern open_out *open_connex_2 ();
extern open_out *open_connex_2_svc ();
#define SEND_SIGNAL 2
extern signal_out * send_signal_2();
extern signal_out * send_signal_2_svc();
extern signal_out *send_signal_2 ();
extern signal_out *send_signal_2_svc ();
#define CLOSE_CONNEX 10
extern void * close_connex_2();
extern void * close_connex_2_svc();
extern void *close_connex_2 ();
extern void *close_connex_2_svc ();
#define PTRACE 11
extern ptrace_out * ptrace_2();
extern ptrace_out * ptrace_2_svc();
extern ptrace_out *ptrace_2 ();
extern ptrace_out *ptrace_2_svc ();
#define WAIT_INFO 13
extern wait_out * wait_info_2();
extern wait_out * wait_info_2_svc();
extern wait_out *wait_info_2 ();
extern wait_out *wait_info_2_svc ();
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2();
extern get_signal_names_out * get_signal_names_2_svc();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
extern get_signal_names_out *get_signal_names_2 ();
extern get_signal_names_out *get_signal_names_2_svc ();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
extern bool_t xdr_break_type (XDR *, break_type*);
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
extern bool_t xdr_thread_name (XDR *, thread_name*);
extern bool_t xdr_KernThread (XDR *, KernThread*);
extern bool_t xdr_thread_list (XDR *, thread_list*);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
extern bool_t xdr_xry_inst (XDR *, xry_inst*);
extern bool_t xdr_instance (XDR *, instance*);
extern bool_t xdr_instance_union (XDR *, instance_union*);
extern bool_t xdr_one_arg (XDR *, one_arg*);
extern bool_t xdr_debug_type (XDR *, debug_type*);
extern bool_t xdr_open_in (XDR *, open_in*);
extern bool_t xdr_open_out (XDR *, open_out*);
extern bool_t xdr_close_control (XDR *, close_control*);
extern bool_t xdr_close_in (XDR *, close_in*);
extern bool_t xdr_signal_in (XDR *, signal_in*);
extern bool_t xdr_signal_out (XDR *, signal_out*);
extern bool_t xdr_stop_code (XDR *, stop_code*);
extern bool_t xdr_wait_in (XDR *, wait_in*);
extern bool_t xdr_wait_out (XDR *, wait_out*);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
extern bool_t xdr_one_signal (XDR *, one_signal*);
extern bool_t xdr_all_signals (XDR *, all_signals*);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
extern bool_t xdr_rpc_type (XDR *, rpc_type *);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG *);
extern bool_t xdr_ptracereq (XDR *, ptracereq *);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs *);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem *);
extern bool_t xdr_break_type (XDR *, break_type *);
extern bool_t xdr_xdr_break (XDR *, xdr_break *);
extern bool_t xdr_thread_name (XDR *, thread_name *);
extern bool_t xdr_KernThread (XDR *, KernThread *);
extern bool_t xdr_thread_list (XDR *, thread_list *);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in *);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out *);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA *);
extern bool_t xdr_xry_inst (XDR *, xry_inst *);
extern bool_t xdr_instance (XDR *, instance *);
extern bool_t xdr_instance_union (XDR *, instance_union *);
extern bool_t xdr_one_arg (XDR *, one_arg *);
extern bool_t xdr_debug_type (XDR *, debug_type *);
extern bool_t xdr_open_in (XDR *, open_in *);
extern bool_t xdr_open_out (XDR *, open_out *);
extern bool_t xdr_close_control (XDR *, close_control *);
extern bool_t xdr_close_in (XDR *, close_in *);
extern bool_t xdr_signal_in (XDR *, signal_in *);
extern bool_t xdr_signal_out (XDR *, signal_out *);
extern bool_t xdr_stop_code (XDR *, stop_code *);
extern bool_t xdr_wait_in (XDR *, wait_in *);
extern bool_t xdr_wait_out (XDR *, wait_out *);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in *);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out *);
extern bool_t xdr_one_symbol (XDR *, one_symbol *);
extern bool_t xdr_all_symbols (XDR *, all_symbols *);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out *);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in *);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out *);
extern bool_t xdr_one_signal (XDR *, one_signal *);
extern bool_t xdr_all_signals (XDR *, all_signals *);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out *);
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
#endif /* K&R C */
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_REMDEB_H_RPCGEN */
#endif /* !_REMDEB_H_RPCGEN */

View File

@@ -22,101 +22,112 @@
* become too small if this value gets incremented.
*/
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
const char* names [] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
#endif /* REMDEB_H */
/*
* now open_connex() routine which establishes a connection to server
*/
#define DEBUGGER_IS_GDB 0x2 /* */
/*
* now close_connex() routine which detaches from server
*/
/*
* now send_signal() routine which sends signals to processes like kill(2)
*/
/*
* now wait_info() routine which returns results of polling the wait status
* of a process/actor. It may return 0 if running, else pid or -1
*/
/*
* now ptrace() routine. This matches the Sun UNIX ptrace as well as
* some additions
*/
/*
* now define the actual calls we support
*/
const char *names[] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
};
void
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
remotedeb_2 (struct svc_req *rqstp, register SVCXPRT * transp)
{
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local) (char *, struct svc_req *);
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names [rqstp->rq_proc] : "???",
(int) rqstp->rq_proc));
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names[rqstp->rq_proc] : "???", (int) rqstp->rq_proc));
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
return;
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
default:
svcerr_noproc (transp);
return;
}
memset ((char *) &argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) & argument)) {
svcerr_decode (transp);
return;
}
result = (*local) ((char *) &argument, rqstp);
if (result != NULL && !svc_sendreply (transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) & argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -22,43 +22,41 @@
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
int
ExcepToSig (Exception_context *ctx)
int
ExcepToSig (Exception_context * ctx)
{
int excep = getExcNum (ctx);
int excep = getExcNum (ctx);
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
switch (excep) {
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
default:
break;
}
return SIGKILL;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
@@ -66,88 +64,81 @@ ExcepToSig (Exception_context *ctx)
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
void
BreakPointExcHdl (CPU_Exception_frame * ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
if ((justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG)) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
} else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG) {
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
printk ("----------------------------------------------------------\n");
printk ("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex, ctx->eip, _Thread_Executing->Object.id);
printk ("----------------------------------------------------------\n");
printk ("Processor execution context at time of the fault was :\n");
printk ("----------------------------------------------------------\n");
printk (" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk (" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk ("----------------------------------------------------------\n");
printk ("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk ("----------------------------------------------------------\n\n");
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL, 0, &continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
rtems_panic ("Can't create continue semaphore: `%s'\n",
rtems_status_text (status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
switch (ctx->idtIndex) {
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
DPRINTF ((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
ExitForSingleStep--;
rtems_semaphore_release (wakeupEventSemId);
break;
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
DPRINTF ((" ENTER RDBG !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
DPRINTF ((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
rtems_semaphore_delete (continueSemId);
}
}

View File

@@ -12,144 +12,157 @@
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
void
CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
{
regs->tabreg [GS] = 0;
regs->tabreg [FS] = 0;
regs->tabreg [ES] = 0;
regs->tabreg [DS] = 0;
regs->tabreg [EDI] = ctx->edi;
regs->tabreg [ESI] = ctx->esi;
regs->tabreg [EBP] = ctx->ebp;
regs->tabreg [ESP] = ctx->esp0;
regs->tabreg [EBX] = ctx->ebx;
regs->tabreg [EDX] = ctx->edx;
regs->tabreg [ECX] = ctx->ecx;
regs->tabreg [EAX] = ctx->eax;
regs->tabreg [TRAPNO] = ctx->idtIndex;
regs->tabreg [ERR] = ctx->faultCode;
regs->tabreg [EIP] = ctx->eip;
regs->tabreg [CS] = ctx->cs & 0xFFFF;
regs->tabreg [EFL] = ctx->eflags;
regs->tabreg[GS] = 0;
regs->tabreg[FS] = 0;
regs->tabreg[ES] = 0;
regs->tabreg[DS] = 0;
regs->tabreg[EDI] = ctx->edi;
regs->tabreg[ESI] = ctx->esi;
regs->tabreg[EBP] = ctx->ebp;
regs->tabreg[ESP] = ctx->esp0;
regs->tabreg[EBX] = ctx->ebx;
regs->tabreg[EDX] = ctx->edx;
regs->tabreg[ECX] = ctx->ecx;
regs->tabreg[EAX] = ctx->eax;
regs->tabreg[TRAPNO] = ctx->idtIndex;
regs->tabreg[ERR] = ctx->faultCode;
regs->tabreg[EIP] = ctx->eip;
regs->tabreg[CS] = ctx->cs & 0xFFFF;
regs->tabreg[EFL] = ctx->eflags;
}
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
void
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
{
ctx->edi = regs->tabreg [EDI];
ctx->esi = regs->tabreg [ESI];
ctx->ebp = regs->tabreg [EBP];
ctx->esp0 = regs->tabreg [ESP];
ctx->ebx = regs->tabreg [EBX];
ctx->edx = regs->tabreg [EDX];
ctx->ecx = regs->tabreg [ECX];
ctx->eax = regs->tabreg [EAX];
ctx->idtIndex = regs->tabreg [TRAPNO];
ctx->faultCode = regs->tabreg [ERR];
ctx->eip = regs->tabreg [EIP];
ctx->cs = regs->tabreg [CS];
ctx->eflags = regs->tabreg [EFL];
ctx->edi = regs->tabreg[EDI];
ctx->esi = regs->tabreg[ESI];
ctx->ebp = regs->tabreg[EBP];
ctx->esp0 = regs->tabreg[ESP];
ctx->ebx = regs->tabreg[EBX];
ctx->edx = regs->tabreg[EDX];
ctx->ecx = regs->tabreg[ECX];
ctx->eax = regs->tabreg[EAX];
ctx->idtIndex = regs->tabreg[TRAPNO];
ctx->faultCode = regs->tabreg[ERR];
ctx->eip = regs->tabreg[EIP];
ctx->cs = regs->tabreg[CS];
ctx->eflags = regs->tabreg[EFL];
}
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
ctx->edi = thread->Registers.edi;
ctx->esi = thread->Registers.esi;
ctx->ebp = (unsigned32)(thread->Registers.ebp);
ctx->esp0 = (unsigned32)(thread->Registers.esp);
ctx->ebx = thread->Registers.ebx;
ctx->edx = 0;
ctx->ecx = 0;
ctx->eax = 0;
ctx->idtIndex = 0;
ctx->faultCode = 0;
ctx->eip = *(unsigned int*)(thread->Registers.esp);
ctx->cs = 0;
ctx->eflags = thread->Registers.eflags;
ctx->edi = thread->Registers.edi;
ctx->esi = thread->Registers.esi;
ctx->ebp = (unsigned32) (thread->Registers.ebp);
ctx->esp0 = (unsigned32) (thread->Registers.esp);
ctx->ebx = thread->Registers.ebx;
ctx->edx = 0;
ctx->ecx = 0;
ctx->eax = 0;
ctx->idtIndex = 0;
ctx->faultCode = 0;
ctx->eip = *(unsigned int *) (thread->Registers.esp);
ctx->cs = 0;
ctx->eflags = thread->Registers.eflags;
}
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
thread->Registers.edi = ctx->edi;
thread->Registers.esi = ctx->esi;
thread->Registers.ebp = (void*)(ctx->ebp);
thread->Registers.esp = (void*)(ctx->esp0);
thread->Registers.ebx = ctx->ebx;
thread->Registers.eflags = ctx->eflags;
thread->Registers.esi = ctx->esi;
thread->Registers.ebp = (void *) (ctx->ebp);
thread->Registers.esp = (void *) (ctx->esp0);
thread->Registers.ebx = ctx->ebx;
thread->Registers.eflags = ctx->eflags;
}
int
Single_Step(CPU_Exception_frame* ctx)
int
Single_Step (CPU_Exception_frame * ctx)
{
/* Check if not already set */
if ((ctx->eflags & EFLAGS_TF) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
/*
* Check if not already set
*/
if ((ctx->eflags & EFLAGS_TF) != 0 || ExitForSingleStep != 0) {
/*
* Check coherency
*/
assert ((ctx->eflags & EFLAGS_TF) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->eflags |= EFLAGS_TF; /* eflags */
ctx->eflags |= EFLAGS_TF; /* eflags */
++ExitForSingleStep;
return 0;
}
int
CheckForSingleStep (CPU_Exception_frame* ctx)
int
CheckForSingleStep (CPU_Exception_frame * ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
void
CancelSingleStep (CPU_Exception_frame* ctx)
{
/* Cancel scheduled SS */
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
cpuExcHandlerType old_currentExcHandler;
extern void rtems_exception_prologue_50();
void connect_rdbg_exception()
void
CancelSingleStep (CPU_Exception_frame * ctx)
{
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
/*
* Cancel scheduled SS
*/
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep--;
}
static cpuExcHandlerType old_currentExcHandler;
extern void rtems_exception_prologue_50 ();
void
connect_rdbg_exception ()
{
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
/*
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
_CPU_ISR_Disable (level);
create_interrupt_gate_descriptor (&currentIdtEntry[50],
rtems_exception_prologue_50);
_CPU_ISR_Enable (level);
if (_currentExcHandler != BreakPointExcHdl) {
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl;
}
}
void
disconnect_rdbg_exception ()
{
if (_currentExcHandler == BreakPointExcHdl) {
_currentExcHandler = old_currentExcHandler;
}
}

View File

@@ -71,6 +71,8 @@ if RPCTOOLS
-o m68k/any/tmpSvc.c remdeb.x; \
$(AWK) -f ./awk.svc THEPROG="remdeb.h" m68k/any/tmpSvc.c \
> m68k/any/remdeb_svc.c; \
$(SED) -e 's/fprintf.*,/printf(/' m68k/any/remdeb_svc.c > m68k/any/remdeb_svc.tmp; \
mv m68k/any/remdeb_svc.tmp m68k/any/remdeb_svc.c; \
rm -f m68k/any/tmpSvc.c )
endif

View File

@@ -8,7 +8,6 @@
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -18,99 +17,98 @@ extern "C" {
#ifndef REMDEB_H
#define RPCGENSRVNAME(a) a
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
enum rpc_type {
SUNRPC = 0,
BADRPCTYPE = 25,
};
typedef enum rpc_type rpc_type;
#define NET_SAFE 1400
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
struct UDP_MSG {
u_char type;
u_char msg_num;
u_short spec;
long pid;
u_long context;
};
typedef struct UDP_MSG UDP_MSG;
/*
* Sun request values for the remote ptrace system call
*/
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
enum ptracereq {
RPT_TRACEME = 0,
RPT_CHILDDONE = 0,
RPT_PEEKTEXT = 0 + 1,
RPT_PEEKDATA = 0 + 2,
RPT_PEEKUSER = 0 + 3,
RPT_POKETEXT = 0 + 4,
RPT_POKEDATA = 0 + 5,
RPT_POKEUSER = 0 + 6,
RPT_CONT = 0 + 7,
RPT_KILL = 0 + 8,
RPT_SINGLESTEP = 0 + 9,
RPT_ATTACH = 0 + 10,
RPT_DETACH = 0 + 11,
RPT_GETREGS = 0 + 12,
RPT_SETREGS = 0 + 13,
RPT_GETFPREGS = 0 + 14,
RPT_SETFPREGS = 0 + 15,
RPT_READDATA = 0 + 16,
RPT_WRITEDATA = 0 + 17,
RPT_READTEXT = 0 + 18,
RPT_WRITETEXT = 0 + 19,
RPT_GETFPAREGS = 0 + 20,
RPT_SETFPAREGS = 0 + 21,
RPT_22 = 0 + 22,
RPT_23 = 0 + 23,
RPT_SYSCALL = 0 + 24,
RPT_DUMPCORE = 0 + 25,
RPT_26 = 0 + 26,
RPT_27 = 0 + 27,
RPT_28 = 0 + 28,
RPT_GETUCODE = 0 + 29,
RPT_GETTARGETTHREAD = 50,
RPT_SETTARGETTHREAD = 51,
RPT_THREADSUSPEND = 52,
RPT_THREADRESUME = 53,
RPT_THREADLIST = 54,
RPT_GETTHREADNAME = 55,
RPT_SETTHREADNAME = 56,
RPT_SETTHREADREGS = 57,
RPT_GETTHREADREGS = 58,
RPT_STEPRANGE = 75,
RPT_CONTTO = 76,
RPT_SETBREAK = 77,
RPT_CLRBREAK = 78,
RPT_GETBREAK = 79,
RPT_GETNAME = 80,
RPT_STOP = 81,
RPT_PGETREGS = 82,
RPT_PSETREGS = 83,
RPT_PSETTHREADREGS = 84,
RPT_PGETTHREADREGS = 85,
};
typedef enum ptracereq ptracereq;
struct xdr_regs {
int r_dreg[8];
int r_areg[8];
int r_sr;
int r_pc;
int r_vec;
};
typedef struct xdr_regs xdr_regs;
struct xdr_regs {
int r_dreg[8];
int r_areg[8];
int r_sr;
int r_pc;
int r_vec;
};
typedef struct xdr_regs xdr_regs;
/* now define register macros to apply to xdr_reg struct */
#define r_r0 r_dreg[0] /* r0 for portability */
#define r_sp r_areg[7] /* user stack pointer */
#define r_r0 r_dreg[0] /* r0 for portability */
#define r_sp r_areg[7] /* user stack pointer */
#define r_ps r_sr
#define REG_PC r_pc /* PC register offset */
#define REG_SP r_areg[7] /* SP register offset */
#define REG_FP r_areg[6] /* FP register offset */
#define REG_PC r_pc /* PC register offset */
#define REG_SP r_areg[7] /* SP register offset */
#define REG_FP r_areg[6] /* FP register offset */
/* now define the BREAKPOINT mask technique to a long word */
#define SET_BREAK(l) ((l&0x0000FFFF) | 0x4E4F0000) /* TRAP 15 */
#define SET_BREAK(l) ((l&0x0000FFFF) | 0x4E4F0000) /* TRAP 15 */
#define IS_BREAK(l) (((l) & 0xFFFF0000) == 0x4E4F0000)
#define ORG_BREAK(c,p) (((c) & 0x0000FFFF) | ((p) & 0xFFFF0000))
#define IS_STEP(regs) ((regs).r_vec == 9)
@@ -128,286 +126,298 @@ typedef struct xdr_regs xdr_regs;
*/
#define MEM_DATA_MAX 256
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
struct xdr_mem {
u_long addr;
u_int dataNb;
u_char data[MEM_DATA_MAX];
};
typedef struct xdr_mem xdr_mem;
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
enum break_type {
BRKT_NONE = 0,
BRKT_INSTR = 1,
BRKT_READ = 2,
BRKT_WRITE = 3,
BRKT_ACCESS = 4,
BRKT_EXEC = 5,
BRKT_OS_CALL = 6,
BRKT_OS_SWITCH = 7,
BRKT_STEPEMUL = 8,
};
typedef enum break_type break_type;
#define MAX_THRD_BRK 4
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
struct xdr_break {
u_char type;
u_char thread_spec;
u_short handle;
u_long ee_loc;
u_long ee_type;
u_short length;
u_char pass_count;
u_char curr_pass;
u_long thread_list[MAX_THRD_BRK];
};
typedef struct xdr_break xdr_break;
#define UTHREAD_MAX 64
#define THREADNAMEMAX 16
typedef char *thread_name;
typedef char *thread_name;
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
struct KernThread {
u_int threadLi;
};
typedef struct KernThread KernThread;
typedef KernThread *ptThreadList;
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
struct thread_list {
u_int nbThread;
ptThreadList threads;
};
typedef struct thread_list thread_list;
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
struct ptrace_addr_data_in {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int address;
} ptrace_addr_data_in_u;
};
typedef struct ptrace_addr_data_in ptrace_addr_data_in;
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
struct ptrace_addr_data_out {
ptracereq req;
union {
xdr_regs regs;
struct {
u_int pregs_len;
u_int *pregs_val;
} pregs;
thread_list threads;
thread_name name;
xdr_mem mem;
xdr_break breakp;
u_int addr;
} ptrace_addr_data_out_u;
};
typedef struct ptrace_addr_data_out ptrace_addr_data_out;
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
#define XRY_MAX_INST_BUFF 128
#define XRY_MAX_INSTANCES 16
#ifndef XRY_MAX_CMD_STR
#define XRY_MAX_CMD_STR 320
#endif /* REMDEB_H */
#endif /* REMDEB_H */
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
typedef char *one_arg;
typedef char *one_arg;
#define XRY_MAX_OBJ_NAME 32
/* now open_connex() routine which establishes a connection to server */
/*
* now open_connex() routine which establishes a connection to server
*/
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
enum debug_type {
DEBTYP_PROCESS = 0,
DEBTYP_C_ACTOR = 1,
DEBTYP_KERNEL = 2,
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
struct open_in {
u_char back_port[16];
u_short debug_type;
u_short flags;
u_char destination[16];
one_arg user_name;
};
typedef struct open_in open_in;
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/* now close_connex() routine which detaches from server */
struct open_out {
u_long port;
u_int pad[4];
u_int fp;
u_char cmd_table_num;
u_char cmd_table_vers;
u_short server_vers;
};
typedef struct open_out open_out;
/*
* now close_connex() routine which detaches from server
*/
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
enum close_control {
CLOSE_IGNORE = 0,
CLOSE_KILL = 1,
CLOSE_DETACH = 2,
};
typedef enum close_control close_control;
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/* now send_signal() routine which sends signals to processes like kill(2) */
struct close_in {
close_control control;
};
typedef struct close_in close_in;
/*
* now send_signal() routine which sends signals to processes like kill(2)
*/
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
struct signal_in {
int pid;
int sig;
};
typedef struct signal_in signal_in;
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
struct signal_out {
int kill_return;
int errNo;
};
typedef struct signal_out signal_out;
/*
* now wait_info() routine which returns results of polling the wait status
* of a process/actor. It may return 0 if running, else pid or -1
*/
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
enum stop_code {
STOP_ERROR = 0,
STOP_NONE = 1,
STOP_UNKNOWN = 2,
STOP_BREAK = 3,
STOP_STEP = 4,
STOP_SIGNAL = 5,
STOP_TERM_EXIT = 6,
STOP_TERM_SIG = 7,
STOP_DETACHED = 8,
STOP_KILLED = 9,
STOP_SPAWN_FAILED = 10,
};
typedef enum stop_code stop_code;
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
struct wait_in {
int pid;
};
typedef struct wait_in wait_in;
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
struct wait_out {
int wait_return;
int errNo;
int status;
stop_code reason;
int handle;
u_long PC;
u_long SP;
u_long FP;
u_long thread;
};
typedef struct wait_out wait_out;
/*
* now ptrace() routine. This matches the Sun UNIX ptrace as well as
* some additions
*/
#define PTRFLG_FORCE 1
#define PTRFLG_NON_OWNER 2
#define PTRFLG_FREE 4
#define PTRDET_UNOWN 0x100
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
struct ptrace_in {
int pid;
ptrace_addr_data_in addr;
u_int data;
u_int flags;
};
typedef struct ptrace_in ptrace_in;
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
struct ptrace_out {
ptrace_addr_data_out addr;
int result;
int errNo;
};
typedef struct ptrace_out ptrace_out;
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
struct one_symbol {
char *symbolName;
long symbolValue;
};
typedef struct one_symbol one_symbol;
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
typedef struct {
u_int all_symbols_len;
one_symbol *all_symbols_val;
} all_symbols;
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
struct get_global_symbols_out {
all_symbols symbols;
};
typedef struct get_global_symbols_out get_global_symbols_out;
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
struct get_text_data_in {
int pid;
char *actorName;
};
typedef struct get_text_data_in get_text_data_in;
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
struct get_text_data_out {
int result;
int errNo;
u_long textStart;
u_long textSize;
u_long dataStart;
u_long dataSize;
};
typedef struct get_text_data_out get_text_data_out;
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
struct one_signal {
u_int number;
char *name;
};
typedef struct one_signal one_signal;
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
typedef struct {
u_int all_signals_len;
one_signal *all_signals_val;
} all_signals;
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/* now define the actual calls we support */
struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/*
* now define the actual calls we support
*/
#define REMDEB_H
#endif
@@ -416,131 +426,131 @@ typedef struct get_signal_names_out get_signal_names_out;
#if defined(__STDC__) || defined(__cplusplus)
#define OPEN_CONNEX 1
extern open_out * open_connex_2(open_in *, CLIENT *);
extern open_out * open_connex_2_svc(open_in *, struct svc_req *);
extern open_out *open_connex_2 (open_in *, CLIENT *);
extern open_out *open_connex_2_svc (open_in *, struct svc_req *);
#define SEND_SIGNAL 2
extern signal_out * send_signal_2(signal_in *, CLIENT *);
extern signal_out * send_signal_2_svc(signal_in *, struct svc_req *);
extern signal_out *send_signal_2 (signal_in *, CLIENT *);
extern signal_out *send_signal_2_svc (signal_in *, struct svc_req *);
#define CLOSE_CONNEX 10
extern void * close_connex_2(close_in *, CLIENT *);
extern void * close_connex_2_svc(close_in *, struct svc_req *);
extern void *close_connex_2 (close_in *, CLIENT *);
extern void *close_connex_2_svc (close_in *, struct svc_req *);
#define PTRACE 11
extern ptrace_out * ptrace_2(ptrace_in *, CLIENT *);
extern ptrace_out * ptrace_2_svc(ptrace_in *, struct svc_req *);
extern ptrace_out *ptrace_2 (ptrace_in *, CLIENT *);
extern ptrace_out *ptrace_2_svc (ptrace_in *, struct svc_req *);
#define WAIT_INFO 13
extern wait_out * wait_info_2(wait_in *, CLIENT *);
extern wait_out * wait_info_2_svc(wait_in *, struct svc_req *);
extern wait_out *wait_info_2 (wait_in *, CLIENT *);
extern wait_out *wait_info_2_svc (wait_in *, struct svc_req *);
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2(void *, CLIENT *);
extern get_signal_names_out * get_signal_names_2_svc(void *, struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
extern get_signal_names_out *get_signal_names_2 (void *, CLIENT *);
extern get_signal_names_out *get_signal_names_2_svc (void *,
struct svc_req *);
extern int remotedeb_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#else /* K&R C */
#define OPEN_CONNEX 1
extern open_out * open_connex_2();
extern open_out * open_connex_2_svc();
extern open_out *open_connex_2 ();
extern open_out *open_connex_2_svc ();
#define SEND_SIGNAL 2
extern signal_out * send_signal_2();
extern signal_out * send_signal_2_svc();
extern signal_out *send_signal_2 ();
extern signal_out *send_signal_2_svc ();
#define CLOSE_CONNEX 10
extern void * close_connex_2();
extern void * close_connex_2_svc();
extern void *close_connex_2 ();
extern void *close_connex_2_svc ();
#define PTRACE 11
extern ptrace_out * ptrace_2();
extern ptrace_out * ptrace_2_svc();
extern ptrace_out *ptrace_2 ();
extern ptrace_out *ptrace_2_svc ();
#define WAIT_INFO 13
extern wait_out * wait_info_2();
extern wait_out * wait_info_2_svc();
extern wait_out *wait_info_2 ();
extern wait_out *wait_info_2_svc ();
#define GET_SIGNAL_NAMES 17
extern get_signal_names_out * get_signal_names_2();
extern get_signal_names_out * get_signal_names_2_svc();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
extern get_signal_names_out *get_signal_names_2 ();
extern get_signal_names_out *get_signal_names_2_svc ();
extern int remotedeb_2_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_rpc_type (XDR *, rpc_type*);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG*);
extern bool_t xdr_ptracereq (XDR *, ptracereq*);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs*);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem*);
extern bool_t xdr_break_type (XDR *, break_type*);
extern bool_t xdr_xdr_break (XDR *, xdr_break*);
extern bool_t xdr_thread_name (XDR *, thread_name*);
extern bool_t xdr_KernThread (XDR *, KernThread*);
extern bool_t xdr_thread_list (XDR *, thread_list*);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
extern bool_t xdr_xry_inst (XDR *, xry_inst*);
extern bool_t xdr_instance (XDR *, instance*);
extern bool_t xdr_instance_union (XDR *, instance_union*);
extern bool_t xdr_one_arg (XDR *, one_arg*);
extern bool_t xdr_debug_type (XDR *, debug_type*);
extern bool_t xdr_open_in (XDR *, open_in*);
extern bool_t xdr_open_out (XDR *, open_out*);
extern bool_t xdr_close_control (XDR *, close_control*);
extern bool_t xdr_close_in (XDR *, close_in*);
extern bool_t xdr_signal_in (XDR *, signal_in*);
extern bool_t xdr_signal_out (XDR *, signal_out*);
extern bool_t xdr_stop_code (XDR *, stop_code*);
extern bool_t xdr_wait_in (XDR *, wait_in*);
extern bool_t xdr_wait_out (XDR *, wait_out*);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in*);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out*);
extern bool_t xdr_one_symbol (XDR *, one_symbol*);
extern bool_t xdr_all_symbols (XDR *, all_symbols*);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out*);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in*);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out*);
extern bool_t xdr_one_signal (XDR *, one_signal*);
extern bool_t xdr_all_signals (XDR *, all_signals*);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out*);
extern bool_t xdr_rpc_type (XDR *, rpc_type *);
extern bool_t xdr_UDP_MSG (XDR *, UDP_MSG *);
extern bool_t xdr_ptracereq (XDR *, ptracereq *);
extern bool_t xdr_xdr_regs (XDR *, xdr_regs *);
extern bool_t xdr_xdr_mem (XDR *, xdr_mem *);
extern bool_t xdr_break_type (XDR *, break_type *);
extern bool_t xdr_xdr_break (XDR *, xdr_break *);
extern bool_t xdr_thread_name (XDR *, thread_name *);
extern bool_t xdr_KernThread (XDR *, KernThread *);
extern bool_t xdr_thread_list (XDR *, thread_list *);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in *);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out *);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA *);
extern bool_t xdr_xry_inst (XDR *, xry_inst *);
extern bool_t xdr_instance (XDR *, instance *);
extern bool_t xdr_instance_union (XDR *, instance_union *);
extern bool_t xdr_one_arg (XDR *, one_arg *);
extern bool_t xdr_debug_type (XDR *, debug_type *);
extern bool_t xdr_open_in (XDR *, open_in *);
extern bool_t xdr_open_out (XDR *, open_out *);
extern bool_t xdr_close_control (XDR *, close_control *);
extern bool_t xdr_close_in (XDR *, close_in *);
extern bool_t xdr_signal_in (XDR *, signal_in *);
extern bool_t xdr_signal_out (XDR *, signal_out *);
extern bool_t xdr_stop_code (XDR *, stop_code *);
extern bool_t xdr_wait_in (XDR *, wait_in *);
extern bool_t xdr_wait_out (XDR *, wait_out *);
extern bool_t xdr_ptrace_in (XDR *, ptrace_in *);
extern bool_t xdr_ptrace_out (XDR *, ptrace_out *);
extern bool_t xdr_one_symbol (XDR *, one_symbol *);
extern bool_t xdr_all_symbols (XDR *, all_symbols *);
extern bool_t xdr_get_global_symbols_out (XDR *, get_global_symbols_out *);
extern bool_t xdr_get_text_data_in (XDR *, get_text_data_in *);
extern bool_t xdr_get_text_data_out (XDR *, get_text_data_out *);
extern bool_t xdr_one_signal (XDR *, one_signal *);
extern bool_t xdr_all_signals (XDR *, all_signals *);
extern bool_t xdr_get_signal_names_out (XDR *, get_signal_names_out *);
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
#else /* K&R C */
extern bool_t xdr_rpc_type ();
extern bool_t xdr_UDP_MSG ();
extern bool_t xdr_ptracereq ();
extern bool_t xdr_xdr_regs ();
extern bool_t xdr_xdr_mem ();
extern bool_t xdr_break_type ();
extern bool_t xdr_xdr_break ();
extern bool_t xdr_thread_name ();
extern bool_t xdr_KernThread ();
extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();
extern bool_t xdr_open_out ();
extern bool_t xdr_close_control ();
extern bool_t xdr_close_in ();
extern bool_t xdr_signal_in ();
extern bool_t xdr_signal_out ();
extern bool_t xdr_stop_code ();
extern bool_t xdr_wait_in ();
extern bool_t xdr_wait_out ();
extern bool_t xdr_ptrace_in ();
extern bool_t xdr_ptrace_out ();
extern bool_t xdr_one_symbol ();
extern bool_t xdr_all_symbols ();
extern bool_t xdr_get_global_symbols_out ();
extern bool_t xdr_get_text_data_in ();
extern bool_t xdr_get_text_data_out ();
extern bool_t xdr_one_signal ();
extern bool_t xdr_all_signals ();
extern bool_t xdr_get_signal_names_out ();
#endif /* K&R C */
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_REMDEB_H_RPCGEN */
#endif /* !_REMDEB_H_RPCGEN */

View File

@@ -22,101 +22,112 @@
* become too small if this value gets incremented.
*/
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
const char* names [] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
#endif /* REMDEB_H */
/*
* now open_connex() routine which establishes a connection to server
*/
#define DEBUGGER_IS_GDB 0x2 /* */
/*
* now close_connex() routine which detaches from server
*/
/*
* now send_signal() routine which sends signals to processes like kill(2)
*/
/*
* now wait_info() routine which returns results of polling the wait status
* of a process/actor. It may return 0 if running, else pid or -1
*/
/*
* now ptrace() routine. This matches the Sun UNIX ptrace as well as
* some additions
*/
/*
* now define the actual calls we support
*/
const char *names[] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
};
void
remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
remotedeb_2 (struct svc_req *rqstp, register SVCXPRT * transp)
{
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
union {
open_in open_connex_2_arg;
signal_in send_signal_2_arg;
close_in close_connex_2_arg;
ptrace_in ptrace_2_arg;
wait_in wait_info_2_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local) (char *, struct svc_req *);
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names [rqstp->rq_proc] : "???",
(int) rqstp->rq_proc));
DPRINTF (("remotedeb_2: %s (%d)\n",
(unsigned) rqstp->rq_proc <
(unsigned) (sizeof names / sizeof names[0]) ?
names[rqstp->rq_proc] : "???", (int) rqstp->rq_proc));
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
return;
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
case OPEN_CONNEX:
_xdr_argument = (xdrproc_t) xdr_open_in;
_xdr_result = (xdrproc_t) xdr_open_out;
local = (char *(*)(char *, struct svc_req *)) open_connex_2_svc;
break;
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
case SEND_SIGNAL:
_xdr_argument = (xdrproc_t) xdr_signal_in;
_xdr_result = (xdrproc_t) xdr_signal_out;
local = (char *(*)(char *, struct svc_req *)) send_signal_2_svc;
break;
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
case CLOSE_CONNEX:
_xdr_argument = (xdrproc_t) xdr_close_in;
_xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) close_connex_2_svc;
break;
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
case PTRACE:
_xdr_argument = (xdrproc_t) xdr_ptrace_in;
_xdr_result = (xdrproc_t) xdr_ptrace_out;
local = (char *(*)(char *, struct svc_req *)) ptrace_2_svc;
break;
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
case WAIT_INFO:
_xdr_argument = (xdrproc_t) xdr_wait_in;
_xdr_result = (xdrproc_t) xdr_wait_out;
local = (char *(*)(char *, struct svc_req *)) wait_info_2_svc;
break;
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
case GET_SIGNAL_NAMES:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_get_signal_names_out;
local = (char *(*)(char *, struct svc_req *)) get_signal_names_2_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
default:
svcerr_noproc (transp);
return;
}
memset ((char *) &argument, 0, sizeof (argument));
if (!svc_getargs (transp, _xdr_argument, (caddr_t) & argument)) {
svcerr_decode (transp);
return;
}
result = (*local) ((char *) &argument, rqstp);
if (result != NULL && !svc_sendreply (transp, _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) & argument)) {
fprintf (stderr, "unable to free arguments");
exit (1);
}
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,54 +17,107 @@
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
int
ExcepToSig (Exception_context *ctx)
int
ExcepToSig (Exception_context * ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case 2 : return 10; break; /* bus error */
case 3 : return 10; break; /* address error */
case 4 : return 4; break; /* illegal instruction */
case 5 : return 8; break; /* zero divide */
case 6 : return 8; break; /* chk instruction */
case 7 : return 8; break; /* trapv instruction */
case 8 : return 11; break; /* privilege violation */
case 9 : return 5; break; /* trace trap */
case 10: return 4; break; /* line 1010 emulator */
case 11: return 4; break; /* line 1111 emulator */
case 2:
return 10;
break; /* bus error */
case 3:
return 10;
break; /* address error */
case 4:
return 4;
break; /* illegal instruction */
case 5:
return 8;
break; /* zero divide */
case 6:
return 8;
break; /* chk instruction */
case 7:
return 8;
break; /* trapv instruction */
case 8:
return 11;
break; /* privilege violation */
case 9:
return 5;
break; /* trace trap */
case 10:
return 4;
break; /* line 1010 emulator */
case 11:
return 4;
break; /* line 1111 emulator */
/* Coprocessor protocol violation. Using a standard MMU or FPU
this cannot be triggered by software. Call it a SIGBUS. */
case 13: return 10; break;
/*
* Coprocessor protocol violation. Using a standard MMU or FPU
* this cannot be triggered by software. Call it a SIGBUS.
*/
case 13:
return 10;
break;
case 31: return 2; break; /* interrupt */
case 33: return 5; break; /* monitor breakpoint */
case 34: return 2; break; /* lets use this for SCC1 interrupt */
case 35: return 5; break; /* rdbg breakpoint */
case 36: return 2; break; /* enter RDBG */
/* This is a trap #8 instruction. Apparently it is someone's software
convention for some sort of SIGFPE condition. Whose? How many
people are being screwed by having this code the way it is?
Is there a clean solution? */
case 40: return 8; break; /* floating point err */
case 31:
return 2;
break; /* interrupt */
case 33:
return 5;
break; /* monitor breakpoint */
case 34:
return 2;
break; /* lets use this for SCC1 interrupt */
case 35:
return 5;
break; /* rdbg breakpoint */
case 36:
return 2;
break; /* enter RDBG */
/*
* This is a trap #8 instruction. Apparently it is someone's software
* convention for some sort of SIGFPE condition. Whose? How many
* people are being screwed by having this code the way it is?
* Is there a clean solution?
*/
case 40:
return 8;
break; /* floating point err */
case 47: return 5; break; /* rdbg breakpoint */
case 47:
return 5;
break; /* rdbg breakpoint */
case 48: return 8; break; /* floating point err */
case 49: return 8; break; /* floating point err */
case 50: return 8; break; /* zero divide */
case 51: return 8; break; /* underflow */
case 52: return 8; break; /* operand error */
case 53: return 8; break; /* overflow */
case 54: return 8; break; /* NAN */
default:
return 7; /* "software generated"*/
}
return SIGKILL;
case 48:
return 8;
break; /* floating point err */
case 49:
return 8;
break; /* floating point err */
case 50:
return 8;
break; /* zero divide */
case 51:
return 8;
break; /* underflow */
case 52:
return 8;
break; /* operand error */
case 53:
return 8;
break; /* overflow */
case 54:
return 8;
break; /* NAN */
default:
return 7; /* "software generated" */
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
@@ -72,101 +125,93 @@ ExcepToSig (Exception_context *ctx)
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
void
BreakPointExcHdl (CPU_Exception_frame * ctx)
{
rtems_status_code status;
rtems_id continueSemId;
connect_rdbg_exception(); /* monitor stub changes trace vector */
if ( (justSaveContext) && (ctx->vecnum == 47) ) { /* break */
connect_rdbg_exception (); /* monitor stub changes trace vector */
if ((justSaveContext) && (ctx->vecnum == 47)) { /* break */
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->vecnum != 9) { /* trace */
} else {
if (ctx->vecnum != 9) { /* trace */
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->vecnum,
ctx->pc,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk("\t A0 = %x\n", ctx->a0);
printk("\t A1 = %x\n", ctx->a1);
printk("\t A2 = %x\n", ctx->a2);
printk("\t A3 = %x\n", ctx->a3);
printk("\t A4 = %x\n", ctx->a4);
printk("\t A5 = %x\n", ctx->a5);
printk("\t A6 = %x\n", ctx->a6);
printk("\t A7 = %x\n", ctx->a7);
printk("\t D0 = %x\n", ctx->d0);
printk("\t D1 = %x\n", ctx->d1);
printk("\t D2 = %x\n", ctx->d2);
printk("\t D3 = %x\n", ctx->d3);
printk("\t D4 = %x\n", ctx->d4);
printk("\t D5 = %x\n", ctx->d5);
printk("\t D6 = %x\n", ctx->d6);
printk("\t D7 = %x\n", ctx->d7);
printk("\t SR = %x\n", ctx->sr);
printk ("----------------------------------------------------------\n");
printk ("Exception %d caught at PC %x by thread %d\n",
ctx->vecnum, ctx->pc, _Thread_Executing->Object.id);
printk ("----------------------------------------------------------\n");
printk ("Processor execution context at time of the fault was :\n");
printk ("----------------------------------------------------------\n");
printk ("\t A0 = %x\n", ctx->a0);
printk ("\t A1 = %x\n", ctx->a1);
printk ("\t A2 = %x\n", ctx->a2);
printk ("\t A3 = %x\n", ctx->a3);
printk ("\t A4 = %x\n", ctx->a4);
printk ("\t A5 = %x\n", ctx->a5);
printk ("\t A6 = %x\n", ctx->a6);
printk ("\t A7 = %x\n", ctx->a7);
printk ("\t D0 = %x\n", ctx->d0);
printk ("\t D1 = %x\n", ctx->d1);
printk ("\t D2 = %x\n", ctx->d2);
printk ("\t D3 = %x\n", ctx->d3);
printk ("\t D4 = %x\n", ctx->d4);
printk ("\t D5 = %x\n", ctx->d5);
printk ("\t D6 = %x\n", ctx->d6);
printk ("\t D7 = %x\n", ctx->d7);
printk ("\t SR = %x\n", ctx->sr);
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL, 0, &continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",
rtems_status_text(status));
rtems_status_text (status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->vecnum){
case 9 : /* trace */
DPRINTF((" TRACE EXCEPTION !!!\n"));
switch (ctx->vecnum) {
case 9: /* trace */
DPRINTF ((" TRACE EXCEPTION !!!\n"));
ctx->sr &= ~(1 << 15);
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
ExitForSingleStep--;
rtems_semaphore_release (wakeupEventSemId);
break;
case 47 : /* trap #15 */
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case 47: /* trap #15 */
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
case 36 : /* trap #4 */
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
case 36: /* trap #4 */
DPRINTF ((" ENTER RDBG !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
DPRINTF ((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
rtems_semaphore_delete (continueSemId);
}
connect_rdbg_exception(); /* monitor stub changes trace vector */
connect_rdbg_exception (); /* monitor stub changes trace vector */
}

View File

@@ -12,14 +12,14 @@
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
void
CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
{
regs->r_dreg[0] = ctx->d0;
regs->r_dreg[1] = ctx->d1;
@@ -44,8 +44,8 @@ CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
regs->r_vec = ctx->vecnum;
}
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
void
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
{
ctx->d0 = regs->r_dreg[0];
ctx->d1 = regs->r_dreg[1];
@@ -70,97 +70,107 @@ RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
ctx->vecnum = regs->r_vec;
}
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
unsigned int *ptr;
unsigned int i;
/*
/*
* ISR stores d0-d1/a0-a1, calls _Thread_Dispatch
* _Thread_Dispatch calls _Context_Switch == _CPU_Context_switch
* _CPU_Context_switch stores/restores sr,d2-d7,a2-a7
* so if my reasoning is correct, *sp points to a location in
* _Thread_Dispatch
*/
ctx->vecnum = 0xdeadbeef;
ctx->sr = thread->Registers.sr;
ctx->pc = *(unsigned32 *)thread->Registers.a7_msp;
ctx->d0 = 0xdeadbeef;
ctx->d1 = 0xdeadbeef;
ctx->a0 = 0xdeadbeef;
ctx->a1 = 0xdeadbeef;
ctx->a2 = (unsigned32)thread->Registers.a2;
ctx->a3 = (unsigned32)thread->Registers.a3;
ctx->a4 = (unsigned32)thread->Registers.a4;
ctx->a5 = (unsigned32)thread->Registers.a5;
ctx->a6 = (unsigned32)thread->Registers.a6;
ctx->a7 = (unsigned32)thread->Registers.a7_msp;
ctx->d2 = thread->Registers.d2;
ctx->d3 = thread->Registers.d3;
ctx->d4 = thread->Registers.d4;
ctx->d5 = thread->Registers.d5;
ctx->d6 = thread->Registers.d6;
ctx->d7 = thread->Registers.d7;
ctx->vecnum = 0xdeadbeef;
ctx->sr = thread->Registers.sr;
ctx->pc = *(unsigned32 *) thread->Registers.a7_msp;
ctx->d0 = 0xdeadbeef;
ctx->d1 = 0xdeadbeef;
ctx->a0 = 0xdeadbeef;
ctx->a1 = 0xdeadbeef;
ctx->a2 = (unsigned32) thread->Registers.a2;
ctx->a3 = (unsigned32) thread->Registers.a3;
ctx->a4 = (unsigned32) thread->Registers.a4;
ctx->a5 = (unsigned32) thread->Registers.a5;
ctx->a6 = (unsigned32) thread->Registers.a6;
ctx->a7 = (unsigned32) thread->Registers.a7_msp;
ctx->d2 = thread->Registers.d2;
ctx->d3 = thread->Registers.d3;
ctx->d4 = thread->Registers.d4;
ctx->d5 = thread->Registers.d5;
ctx->d6 = thread->Registers.d6;
ctx->d7 = thread->Registers.d7;
}
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
thread->Registers.sr = ctx->sr;
thread->Registers.d2 = ctx->d2;
thread->Registers.d3 = ctx->d3;
thread->Registers.d4 = ctx->d4;
thread->Registers.d5 = ctx->d5;
thread->Registers.d6 = ctx->d6;
thread->Registers.d7 = ctx->d7;
thread->Registers.a2 = (void *)ctx->a2;
thread->Registers.a3 = (void *)ctx->a3;
thread->Registers.a4 = (void *)ctx->a4;
thread->Registers.a5 = (void *)ctx->a5;
thread->Registers.a6 = (void *)ctx->a6;
thread->Registers.a7_msp = (void *)ctx->a7;
thread->Registers.sr = ctx->sr;
thread->Registers.d2 = ctx->d2;
thread->Registers.d3 = ctx->d3;
thread->Registers.d4 = ctx->d4;
thread->Registers.d5 = ctx->d5;
thread->Registers.d6 = ctx->d6;
thread->Registers.d7 = ctx->d7;
thread->Registers.a2 = (void *) ctx->a2;
thread->Registers.a3 = (void *) ctx->a3;
thread->Registers.a4 = (void *) ctx->a4;
thread->Registers.a5 = (void *) ctx->a5;
thread->Registers.a6 = (void *) ctx->a6;
thread->Registers.a7_msp = (void *) ctx->a7;
}
int
Single_Step(CPU_Exception_frame* ctx)
int
Single_Step (CPU_Exception_frame * ctx)
{
if ((ctx->sr & (1<<15)) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
assert ((ctx->sr & (1<<15)) != 0);
if ((ctx->sr & (1 << 15)) != 0 || ExitForSingleStep != 0) {
/*
* Check coherency
*/
assert ((ctx->sr & (1 << 15)) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->sr |= 1<<15;
ctx->sr |= 1 << 15;
++ExitForSingleStep;
return 0;
}
int
CheckForSingleStep (CPU_Exception_frame* ctx)
int
CheckForSingleStep (CPU_Exception_frame * ctx)
{
if (ExitForSingleStep) {
ctx->sr &= ~(1<<15);
ExitForSingleStep = 0;
return 1;
}
return 0;
if (ExitForSingleStep) {
ctx->sr &= ~(1 << 15);
ExitForSingleStep = 0;
return 1;
}
return 0;
}
void
CancelSingleStep (CPU_Exception_frame * ctx)
{
/*
* Cancel scheduled SS
*/
ctx->sr &= ~(1 << 15);
ExitForSingleStep--;
}
extern rtems_isr excHandler ();
void
connect_rdbg_exception (void)
{
set_vector (excHandler, 9, 0);
set_vector (excHandler, 47, 0);
set_vector (excHandler, 36, 0);
}
void
CancelSingleStep (CPU_Exception_frame* ctx)
disconnect_rdbg_exception (void)
{
/* Cancel scheduled SS */
ctx->sr &= ~(1<<15);
ExitForSingleStep-- ;
}
rtems_isr excHandler();
void connect_rdbg_exception(void)
{
set_vector(excHandler, 9, 0);
set_vector(excHandler, 47, 0);
set_vector(excHandler, 36, 0);
}

View File

@@ -17,32 +17,35 @@
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
int
ExcepToSig (Exception_context *ctx)
int
ExcepToSig (Exception_context * ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case ASM_FLOAT_VECTOR : return SIGFPE;
case ASM_TRACE_VECTOR :
case ASM_PROG_VECTOR :
case ASM_SYS_VECTOR : return SIGTRAP;
case ASM_ISI_VECTOR : return SIGSEGV;
case ASM_RESET_VECTOR :
case ASM_MACH_VECTOR :
case ASM_EXT_VECTOR :
case ASM_ALIGN_VECTOR : return SIGILL;
default:
break;
}
return SIGKILL;
case ASM_FLOAT_VECTOR:
return SIGFPE;
case ASM_TRACE_VECTOR:
case ASM_PROG_VECTOR:
case ASM_SYS_VECTOR:
return SIGTRAP;
case ASM_ISI_VECTOR:
return SIGSEGV;
case ASM_RESET_VECTOR:
case ASM_MACH_VECTOR:
case ASM_EXT_VECTOR:
case ASM_ALIGN_VECTOR:
return SIGILL;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
@@ -51,134 +54,124 @@ ExcepToSig (Exception_context *ctx)
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
BreakPointExcHdl (CPU_Exception_frame * ctx)
{
rtems_status_code status;
rtems_id continueSemId;
/* T. Straumann, 1/16/2002: we must re-enable the floating point engine
* if the interrupted thread is FP. Otherwise,
* the semaphore primitives may crash when they
* try to save FP context while switching this
* thread...
/*
* we must re-enable the floating point engine
* if the interrupted thread is FP. Otherwise,
* the semaphore primitives may crash when they
* try to save FP context while switching this
* thread... NB : deferred fp context switching
* would 1) avoid to have to save FP, make this code
* obsolete.
*/
if (ctx->EXC_SRR1 & 0x2000) {
register unsigned long msr;
__asm__ __volatile__("mfmsr %0":"=r"(msr));
__asm__ __volatile__("mtmsr %0"::"r"(msr|MSR_FP));
if (ctx->EXC_SRR1 & MSR_FP) {
register unsigned long msr;
__asm__ __volatile__ ("mfmsr %0":"=r" (msr));
__asm__ __volatile__ ("mtmsr %0"::"r" (msr | MSR_FP));
}
if ( (justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR) ) {
if ((justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR)) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->_EXC_number != ASM_TRACE_VECTOR){
} else {
if (ctx->_EXC_number != ASM_TRACE_VECTOR) {
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->_EXC_number,
ctx->EXC_SRR0,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk("\t R0 = %x\n", ctx->GPR0);
printk("\t R1 = %x\n", ctx->GPR1);
printk("\t R2 = %x\n", ctx->GPR2);
printk("\t R3 = %x\n", ctx->GPR3);
printk("\t R4 = %x\n", ctx->GPR4);
printk("\t R5 = %x\n", ctx->GPR5);
printk("\t R6 = %x\n", ctx->GPR6);
printk("\t R7 = %x\n", ctx->GPR7);
printk("\t R8 = %x\n", ctx->GPR8);
printk("\t R9 = %x\n", ctx->GPR9);
printk("\t R10 = %x\n", ctx->GPR10);
printk("\t R11 = %x\n", ctx->GPR11);
printk("\t R12 = %x\n", ctx->GPR12);
printk("\t R13 = %x\n", ctx->GPR13);
printk("\t R14 = %x\n", ctx->GPR14);
printk("\t R15 = %x\n", ctx->GPR15);
printk("\t R16 = %x\n", ctx->GPR16);
printk("\t R17 = %x\n", ctx->GPR17);
printk("\t R18 = %x\n", ctx->GPR18);
printk("\t R19 = %x\n", ctx->GPR19);
printk("\t R20 = %x\n", ctx->GPR20);
printk("\t R21 = %x\n", ctx->GPR21);
printk("\t R22 = %x\n", ctx->GPR22);
printk("\t R23 = %x\n", ctx->GPR23);
printk("\t R24 = %x\n", ctx->GPR24);
printk("\t R25 = %x\n", ctx->GPR25);
printk("\t R26 = %x\n", ctx->GPR26);
printk("\t R27 = %x\n", ctx->GPR27);
printk("\t R28 = %x\n", ctx->GPR28);
printk("\t R29 = %x\n", ctx->GPR29);
printk("\t R30 = %x\n", ctx->GPR30);
printk("\t R31 = %x\n", ctx->GPR31);
printk("\t CR = %x\n", ctx->EXC_CR);
printk("\t CTR = %x\n", ctx->EXC_CTR);
printk("\t XER = %x\n", ctx->EXC_XER);
printk("\t LR = %x\n", ctx->EXC_LR);
printk("\t MSR = %x\n", ctx->EXC_SRR1);
printk ("----------------------------------------------------------\n");
printk ("Exception %d caught at PC %x by thread %d\n",
ctx->_EXC_number, ctx->EXC_SRR0, _Thread_Executing->Object.id);
printk ("----------------------------------------------------------\n");
printk ("Processor execution context at time of the fault was :\n");
printk ("----------------------------------------------------------\n");
printk ("\t R0 = %x\n", ctx->GPR0);
printk ("\t R1 = %x\n", ctx->GPR1);
printk ("\t R2 = %x\n", ctx->GPR2);
printk ("\t R3 = %x\n", ctx->GPR3);
printk ("\t R4 = %x\n", ctx->GPR4);
printk ("\t R5 = %x\n", ctx->GPR5);
printk ("\t R6 = %x\n", ctx->GPR6);
printk ("\t R7 = %x\n", ctx->GPR7);
printk ("\t R8 = %x\n", ctx->GPR8);
printk ("\t R9 = %x\n", ctx->GPR9);
printk ("\t R10 = %x\n", ctx->GPR10);
printk ("\t R11 = %x\n", ctx->GPR11);
printk ("\t R12 = %x\n", ctx->GPR12);
printk ("\t R13 = %x\n", ctx->GPR13);
printk ("\t R14 = %x\n", ctx->GPR14);
printk ("\t R15 = %x\n", ctx->GPR15);
printk ("\t R16 = %x\n", ctx->GPR16);
printk ("\t R17 = %x\n", ctx->GPR17);
printk ("\t R18 = %x\n", ctx->GPR18);
printk ("\t R19 = %x\n", ctx->GPR19);
printk ("\t R20 = %x\n", ctx->GPR20);
printk ("\t R21 = %x\n", ctx->GPR21);
printk ("\t R22 = %x\n", ctx->GPR22);
printk ("\t R23 = %x\n", ctx->GPR23);
printk ("\t R24 = %x\n", ctx->GPR24);
printk ("\t R25 = %x\n", ctx->GPR25);
printk ("\t R26 = %x\n", ctx->GPR26);
printk ("\t R27 = %x\n", ctx->GPR27);
printk ("\t R28 = %x\n", ctx->GPR28);
printk ("\t R29 = %x\n", ctx->GPR29);
printk ("\t R30 = %x\n", ctx->GPR30);
printk ("\t R31 = %x\n", ctx->GPR31);
printk ("\t CR = %x\n", ctx->EXC_CR);
printk ("\t CTR = %x\n", ctx->EXC_CTR);
printk ("\t XER = %x\n", ctx->EXC_XER);
printk ("\t LR = %x\n", ctx->EXC_LR);
printk ("\t MSR = %x\n", ctx->EXC_SRR1);
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL, 0, &continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
rtems_panic ("Can't create continue semaphore: `%s'\n",
rtems_status_text (status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->_EXC_number){
case ASM_TRACE_VECTOR :
DPRINTF((" TRACE EXCEPTION !!!\n"));
switch (ctx->_EXC_number) {
case ASM_TRACE_VECTOR:
DPRINTF ((" TRACE EXCEPTION !!!\n"));
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
ExitForSingleStep--;
rtems_semaphore_release (wakeupEventSemId);
break;
case ASM_PROG_VECTOR :
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case ASM_PROG_VECTOR:
DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
case ASM_SYS_VECTOR :
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
case ASM_SYS_VECTOR:
DPRINTF ((" ENTER RDBG !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
#ifdef DDEBUG
{ extern void BSP_printStackTrace();
BSP_printStackTrace(ctx);
}
#endif
rtems_semaphore_release( wakeupEventSemId );
DPRINTF ((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release (wakeupEventSemId);
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
rtems_semaphore_delete (continueSemId);
}
}

View File

@@ -71,6 +71,8 @@ if RPCTOOLS
-o powerpc/new_exception_processing/tmpSvc.c remdeb.x; \
$(AWK) -f ./awk.svc THEPROG="remdeb.h" powerpc/new_exception_processing/tmpSvc.c \
> powerpc/new_exception_processing/remdeb_svc.c; \
$(SED) -e 's/fprintf.*,/printf(/' powerpc/new_exception_processing/remdeb_svc.c; > powerpc/new_exception_processing/remdeb_svc.tmp; \
mv powerpc/new_exception_processing/remdeb_svc.tmp powerpc/new_exception_processing/remdeb_svc.c; \
rm -f powerpc/new_exception_processing/tmpSvc.c )
endif

View File

@@ -16,7 +16,7 @@ extern "C" {
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
#ifndef REMDEB_H
#define RPCGENSRVNAME(a) a
#define RPCGENSRVNAME(a) a
enum rpc_type {
SUNRPC = 0,
@@ -99,62 +99,62 @@ struct xdr_regs {
typedef struct xdr_regs xdr_regs;
/* now define register macros to apply to xdr_regs struct */
#define R_PC 0
#define R_MSR 1
#define R_EXCEPNB 2
#define R_R0 3
#define R_R1 (R_R0 + 1)
#define R_R2 (R_R0 + 2)
#define R_R3 (R_R0 + 3)
#define R_R4 (R_R0 + 4)
#define R_R5 (R_R0 + 5)
#define R_R6 (R_R0 + 6)
#define R_R7 (R_R0 + 7)
#define R_R8 (R_R0 + 8)
#define R_R9 (R_R0 + 9)
#define R_R10 (R_R0 + 10)
#define R_R11 (R_R0 + 11)
#define R_R12 (R_R0 + 12)
#define R_R13 (R_R0 + 13)
#define R_R14 (R_R0 + 14)
#define R_R15 (R_R0 + 15)
#define R_R16 (R_R0 + 16)
#define R_R17 (R_R0 + 17)
#define R_R18 (R_R0 + 18)
#define R_R19 (R_R0 + 19)
#define R_R20 (R_R0 + 20)
#define R_R21 (R_R0 + 21)
#define R_R22 (R_R0 + 22)
#define R_R23 (R_R0 + 23)
#define R_R24 (R_R0 + 24)
#define R_R25 (R_R0 + 25)
#define R_R26 (R_R0 + 26)
#define R_R27 (R_R0 + 27)
#define R_R28 (R_R0 + 28)
#define R_R29 (R_R0 + 29)
#define R_R30 (R_R0 + 30)
#define R_R31 (R_R0 + 31)
#define R_CR 35
#define R_CTR 36
#define R_XER 37
#define R_LR 38
#define R_MQ 39
#define R_PC 0
#define R_MSR 1
#define R_EXCEPNB 2
#define R_R0 3
#define R_R1 (R_R0 + 1)
#define R_R2 (R_R0 + 2)
#define R_R3 (R_R0 + 3)
#define R_R4 (R_R0 + 4)
#define R_R5 (R_R0 + 5)
#define R_R6 (R_R0 + 6)
#define R_R7 (R_R0 + 7)
#define R_R8 (R_R0 + 8)
#define R_R9 (R_R0 + 9)
#define R_R10 (R_R0 + 10)
#define R_R11 (R_R0 + 11)
#define R_R12 (R_R0 + 12)
#define R_R13 (R_R0 + 13)
#define R_R14 (R_R0 + 14)
#define R_R15 (R_R0 + 15)
#define R_R16 (R_R0 + 16)
#define R_R17 (R_R0 + 17)
#define R_R18 (R_R0 + 18)
#define R_R19 (R_R0 + 19)
#define R_R20 (R_R0 + 20)
#define R_R21 (R_R0 + 21)
#define R_R22 (R_R0 + 22)
#define R_R23 (R_R0 + 23)
#define R_R24 (R_R0 + 24)
#define R_R25 (R_R0 + 25)
#define R_R26 (R_R0 + 26)
#define R_R27 (R_R0 + 27)
#define R_R28 (R_R0 + 28)
#define R_R29 (R_R0 + 29)
#define R_R30 (R_R0 + 30)
#define R_R31 (R_R0 + 31)
#define R_CR 35
#define R_CTR 36
#define R_XER 37
#define R_LR 38
#define R_MQ 39
#include <libcpu/raw_exception.h>
#define REG_PC tabreg[R_PC] /* PC register offset */
#define REG_SP tabreg[R_R1] /* SP register offset */
#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
#define IS_BREAK(l) ((l) == 0x7d8d6808)
#define SET_BREAK(l) (0x7d8d6808)
#define REG_PC tabreg[R_PC] /* PC register offset */
#define REG_SP tabreg[R_R1] /* SP register offset */
#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
#define IS_BREAK(l) ((l) == 0x7d8d6808)
#define SET_BREAK(l) (0x7d8d6808)
#define ORG_BREAK(c,p) (p)
#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
#define TARGET_PROC_TYPE 3
#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
#define TARGET_PROC_TYPE 3
#define MAXDEBUGGEE 150
#define NAMEMAX 17
/*
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
@@ -250,40 +250,9 @@ typedef struct {
u_int CHAR_DATA_len;
char *CHAR_DATA_val;
} CHAR_DATA;
#define XRY_MAX_INST_BUFF 128
#define XRY_MAX_INSTANCES 16
#ifndef XRY_MAX_CMD_STR
#define XRY_MAX_CMD_STR 320
#endif /* REMDEB_H */
struct xry_inst {
u_char flags;
u_char type;
u_char sub_type;
u_char res_type;
u_long value;
u_long value2;
};
typedef struct xry_inst xry_inst;
struct instance {
struct xry_inst instances[XRY_MAX_INSTANCES];
u_char buffer[XRY_MAX_INST_BUFF];
};
typedef struct instance instance;
struct instance_union {
bool_t instances;
union {
instance inst;
char *buffer;
} instance_union_u;
};
typedef struct instance_union instance_union;
typedef char *one_arg;
#define XRY_MAX_OBJ_NAME 32
/* now open_connex() routine which establishes a connection to server */
/* now open_connex() routine which establishes a connection to server */
enum debug_type {
DEBTYP_PROCESS = 0,
@@ -292,7 +261,7 @@ enum debug_type {
DEBTYP_OTHER = 3,
};
typedef enum debug_type debug_type;
#define DEBUGGER_IS_GDB 0x2 /* */
#define DEBUGGER_IS_GDB 0x2 /* */
struct open_in {
u_char back_port[16];
@@ -312,7 +281,7 @@ struct open_out {
u_short server_vers;
};
typedef struct open_out open_out;
/* now close_connex() routine which detaches from server */
/* now close_connex() routine which detaches from server */
enum close_control {
CLOSE_IGNORE = 0,
@@ -325,7 +294,7 @@ struct close_in {
close_control control;
};
typedef struct close_in close_in;
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now send_signal() routine which sends signals to processes like kill(2) */
struct signal_in {
int pid;
@@ -338,7 +307,7 @@ struct signal_out {
int errNo;
};
typedef struct signal_out signal_out;
/* now wait_info() routine which returns results of polling the wait status
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
enum stop_code {
@@ -373,8 +342,8 @@ struct wait_out {
u_long thread;
};
typedef struct wait_out wait_out;
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
#define PTRFLG_FORCE 1
#define PTRFLG_NON_OWNER 2
#define PTRFLG_FREE 4
@@ -442,7 +411,7 @@ struct get_signal_names_out {
all_signals signals;
};
typedef struct get_signal_names_out get_signal_names_out;
/* now define the actual calls we support */
/* now define the actual calls we support */
#define REMDEB_H
#endif
@@ -508,9 +477,6 @@ extern bool_t xdr_thread_list (XDR *, thread_list*);
extern bool_t xdr_ptrace_addr_data_in (XDR *, ptrace_addr_data_in*);
extern bool_t xdr_ptrace_addr_data_out (XDR *, ptrace_addr_data_out*);
extern bool_t xdr_CHAR_DATA (XDR *, CHAR_DATA*);
extern bool_t xdr_xry_inst (XDR *, xry_inst*);
extern bool_t xdr_instance (XDR *, instance*);
extern bool_t xdr_instance_union (XDR *, instance_union*);
extern bool_t xdr_one_arg (XDR *, one_arg*);
extern bool_t xdr_debug_type (XDR *, debug_type*);
extern bool_t xdr_open_in (XDR *, open_in*);
@@ -547,9 +513,6 @@ extern bool_t xdr_thread_list ();
extern bool_t xdr_ptrace_addr_data_in ();
extern bool_t xdr_ptrace_addr_data_out ();
extern bool_t xdr_CHAR_DATA ();
extern bool_t xdr_xry_inst ();
extern bool_t xdr_instance ();
extern bool_t xdr_instance_union ();
extern bool_t xdr_one_arg ();
extern bool_t xdr_debug_type ();
extern bool_t xdr_open_in ();

View File

@@ -6,7 +6,7 @@
#include <bsp.h>
#include <rdbg/servrpc.h>
#include <rdbg/remdeb.h>
#define fprintf(fp, ...) printf(__VA_ARGS__)
#define printf(c)
/*HEADER_START*/
#define RTEMS_PORT 2071
#define RTEMS_BACK_PORT 2073
@@ -14,30 +14,28 @@
* Sun request values for the remote ptrace system call
*/
/*
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
* pipes and is allocated on stack too. Pipes and/or the stack could
* become too small if this value gets incremented.
*/
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
/* now open_connex() routine which establishes a connection to server */
#define DEBUGGER_IS_GDB 0x2 /* */
/* now close_connex() routine which detaches from server */
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now define the actual calls we support */
const char* names [] = {
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
"NULLPROC", "OPEN_CONNEX", "SEND_SIGNAL", "name3",
"name4", "name5", "name6", "name7",
"name8", "name9", "CLOSE_CONNEX", "PTRACE",
"name12", "WAIT_INFO", "name14", "name15",
"name16", "GET_SIGNAL_NAMES", "name18"
};
void
@@ -115,7 +113,7 @@ remotedeb_2(struct svc_req *rqstp, register SVCXPRT *transp)
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
printf( "unable to free arguments");
exit (1);
}
return;

View File

@@ -97,7 +97,7 @@ xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
return FALSE;
return TRUE;
}
/*
/*
* Memory data for read/write text or data. The size is in data. The target
* addr is in the addr field.
* Be careful before modifying because this value goes into internal
@@ -105,16 +105,16 @@ xdr_xdr_regs (XDR *xdrs, xdr_regs *objp)
* become too small if this value gets incremented.
*/
bool_t xdr_xdr_mem(xdrs, objp)
XDR *xdrs;
struct xdr_mem *objp;
XDR *xdrs;
struct xdr_mem *objp;
{
if (!xdr_u_long(xdrs, &objp->addr)) {
return (FALSE);
}
if (!xdr_u_int(xdrs, &objp->dataNb)) {
return(FALSE);
}
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
if (!xdr_u_long(xdrs, &objp->addr)) {
return (FALSE);
}
if (!xdr_u_int(xdrs, &objp->dataNb)) {
return(FALSE);
}
return (xdr_opaque(xdrs, objp->data, objp->dataNb));
}
bool_t
@@ -262,11 +262,11 @@ xdr_KernThread (XDR *xdrs, KernThread *objp)
return TRUE;
}
bool_t xdr_thread_list(xdrs, objp)
XDR *xdrs;
struct thread_list *objp;
XDR *xdrs;
struct thread_list *objp;
{
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
return (xdr_array(xdrs, (char**)&objp->threads, &objp->nbThread,
UTHREAD_MAX, sizeof(KernThread), xdr_KernThread));
}
bool_t
@@ -386,65 +386,6 @@ xdr_CHAR_DATA (XDR *xdrs, CHAR_DATA *objp)
return FALSE;
return TRUE;
}
#ifndef XRY_MAX_CMD_STR
#endif /* REMDEB_H */
bool_t
xdr_xry_inst (XDR *xdrs, xry_inst *objp)
{
register int32_t *buf;
if (!xdr_u_char (xdrs, &objp->flags))
return FALSE;
if (!xdr_u_char (xdrs, &objp->type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->sub_type))
return FALSE;
if (!xdr_u_char (xdrs, &objp->res_type))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value))
return FALSE;
if (!xdr_u_long (xdrs, &objp->value2))
return FALSE;
return TRUE;
}
bool_t
xdr_instance (XDR *xdrs, instance *objp)
{
register int32_t *buf;
int i;
if (!xdr_vector (xdrs, (char *)objp->instances, XRY_MAX_INSTANCES,
sizeof (xry_inst), (xdrproc_t) xdr_xry_inst))
return FALSE;
if (!xdr_vector (xdrs, (char *)objp->buffer, XRY_MAX_INST_BUFF,
sizeof (u_char), (xdrproc_t) xdr_u_char))
return FALSE;
return TRUE;
}
bool_t
xdr_instance_union (XDR *xdrs, instance_union *objp)
{
register int32_t *buf;
if (!xdr_bool (xdrs, &objp->instances))
return FALSE;
switch (objp->instances) {
case TRUE:
if (!xdr_instance (xdrs, &objp->instance_union_u.inst))
return FALSE;
break;
case FALSE:
if (!xdr_string (xdrs, &objp->instance_union_u.buffer, XRY_MAX_CMD_STR))
return FALSE;
break;
default:
return FALSE;
}
return TRUE;
}
bool_t
xdr_one_arg (XDR *xdrs, one_arg *objp)
@@ -455,7 +396,7 @@ xdr_one_arg (XDR *xdrs, one_arg *objp)
return FALSE;
return TRUE;
}
/* now open_connex() routine which establishes a connection to server */
/* now open_connex() routine which establishes a connection to server */
bool_t
xdr_debug_type (XDR *xdrs, debug_type *objp)
@@ -466,7 +407,7 @@ xdr_debug_type (XDR *xdrs, debug_type *objp)
return FALSE;
return TRUE;
}
#define DEBUGGER_IS_GDB 0x2 /* */
#define DEBUGGER_IS_GDB 0x2 /* */
bool_t
xdr_open_in (XDR *xdrs, open_in *objp)
@@ -573,7 +514,7 @@ xdr_open_out (XDR *xdrs, open_out *objp)
return FALSE;
return TRUE;
}
/* now close_connex() routine which detaches from server */
/* now close_connex() routine which detaches from server */
bool_t
xdr_close_control (XDR *xdrs, close_control *objp)
@@ -594,7 +535,7 @@ xdr_close_in (XDR *xdrs, close_in *objp)
return FALSE;
return TRUE;
}
/* now send_signal() routine which sends signals to processes like kill(2) */
/* now send_signal() routine which sends signals to processes like kill(2) */
bool_t
xdr_signal_in (XDR *xdrs, signal_in *objp)
@@ -619,7 +560,7 @@ xdr_signal_out (XDR *xdrs, signal_out *objp)
return FALSE;
return TRUE;
}
/* now wait_info() routine which returns results of polling the wait status
/* now wait_info() routine which returns results of polling the wait status
of a process/actor. It may return 0 if running, else pid or -1 */
bool_t
@@ -744,8 +685,8 @@ xdr_wait_out (XDR *xdrs, wait_out *objp)
return FALSE;
return TRUE;
}
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
/* now ptrace() routine. This matches the Sun UNIX ptrace as well as
some additions */
bool_t
xdr_ptrace_in (XDR *xdrs, ptrace_in *objp)
@@ -925,4 +866,4 @@ xdr_get_signal_names_out (XDR *xdrs, get_signal_names_out *objp)
return FALSE;
return TRUE;
}
/* now define the actual calls we support */
/* now define the actual calls we support */

View File

@@ -12,109 +12,108 @@
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <libcpu/cpu.h>
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
void
CtxToRegs (const CPU_Exception_frame * ctx, xdr_regs * regs)
{
* ((CPU_Exception_frame*) regs) = *ctx;
*((CPU_Exception_frame *) regs) = *ctx;
}
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
void
RegsToCtx (const xdr_regs * regs, CPU_Exception_frame * ctx)
{
*ctx = * ((CPU_Exception_frame*) regs);
*ctx = *((CPU_Exception_frame *) regs);
}
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
get_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
unsigned int *ptr;
unsigned int i;
ctx->EXC_SRR0 = thread->Registers.pc;
ctx->EXC_SRR1 = thread->Registers.msr;
ctx->EXC_SRR0 = thread->Registers.pc;
ctx->EXC_SRR1 = thread->Registers.msr;
ctx->_EXC_number = 0xdeadbeef;
ctx->GPR1 = thread->Registers.gpr1;
ctx->GPR2 = thread->Registers.gpr2;
ctx->GPR1 = thread->Registers.gpr1;
ctx->GPR2 = thread->Registers.gpr2;
/*
* Fill with dummy values...
*/
ptr = &ctx->GPR3;
for (i = 0; i < 10; i++)
ptr [i] = 0xdeadbeef;
ctx->GPR13 = thread->Registers.gpr13;
ctx->GPR14 = thread->Registers.gpr14;
ctx->GPR15 = thread->Registers.gpr15;
ctx->GPR16 = thread->Registers.gpr16;
ctx->GPR17 = thread->Registers.gpr17;
ctx->GPR18 = thread->Registers.gpr18;
ctx->GPR19 = thread->Registers.gpr19;
ctx->GPR20 = thread->Registers.gpr20;
ctx->GPR21 = thread->Registers.gpr21;
ctx->GPR22 = thread->Registers.gpr22;
ctx->GPR23 = thread->Registers.gpr23;
ctx->GPR24 = thread->Registers.gpr24;
ctx->GPR25 = thread->Registers.gpr25;
ctx->GPR26 = thread->Registers.gpr26;
ctx->GPR27 = thread->Registers.gpr27;
ctx->GPR28 = thread->Registers.gpr28;
ctx->GPR29 = thread->Registers.gpr29;
ctx->GPR30 = thread->Registers.gpr30;
ctx->GPR31 = thread->Registers.gpr31;
ctx->EXC_CR = thread->Registers.cr;
ctx->EXC_CTR = 0xdeadbeef;
ctx->EXC_XER = 0xdeadbeef;
ctx->EXC_LR = 0xdeadbeef;
ctx->EXC_MSR = 0xdeadbeef;
ctx->EXC_DAR = 0xdeadbeef;
ptr[i] = 0xdeadbeef;
ctx->GPR13 = thread->Registers.gpr13;
ctx->GPR14 = thread->Registers.gpr14;
ctx->GPR15 = thread->Registers.gpr15;
ctx->GPR16 = thread->Registers.gpr16;
ctx->GPR17 = thread->Registers.gpr17;
ctx->GPR18 = thread->Registers.gpr18;
ctx->GPR19 = thread->Registers.gpr19;
ctx->GPR20 = thread->Registers.gpr20;
ctx->GPR21 = thread->Registers.gpr21;
ctx->GPR22 = thread->Registers.gpr22;
ctx->GPR23 = thread->Registers.gpr23;
ctx->GPR24 = thread->Registers.gpr24;
ctx->GPR25 = thread->Registers.gpr25;
ctx->GPR26 = thread->Registers.gpr26;
ctx->GPR27 = thread->Registers.gpr27;
ctx->GPR28 = thread->Registers.gpr28;
ctx->GPR29 = thread->Registers.gpr29;
ctx->GPR30 = thread->Registers.gpr30;
ctx->GPR31 = thread->Registers.gpr31;
ctx->EXC_CR = thread->Registers.cr;
ctx->EXC_CTR = 0xdeadbeef;
ctx->EXC_XER = 0xdeadbeef;
ctx->EXC_LR = 0xdeadbeef;
ctx->EXC_MSR = 0xdeadbeef;
ctx->EXC_DAR = 0xdeadbeef;
}
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
void
set_ctx_thread (Thread_Control * thread, CPU_Exception_frame * ctx)
{
thread->Registers.gpr1 = ctx->GPR1;
thread->Registers.gpr2 = ctx->GPR2;
thread->Registers.gpr1 = ctx->GPR1;
thread->Registers.gpr2 = ctx->GPR2;
thread->Registers.gpr13 = ctx->GPR13;
thread->Registers.gpr14 = ctx->GPR14;
thread->Registers.gpr15 = ctx->GPR15;
thread->Registers.gpr16 = ctx->GPR16;
thread->Registers.gpr17 = ctx->GPR17;
thread->Registers.gpr18 = ctx->GPR18;
thread->Registers.gpr19 = ctx->GPR19;
thread->Registers.gpr20 = ctx->GPR20;
thread->Registers.gpr21 = ctx->GPR21;
thread->Registers.gpr22 = ctx->GPR22;
thread->Registers.gpr23 = ctx->GPR23;
thread->Registers.gpr24 = ctx->GPR24;
thread->Registers.gpr25 = ctx->GPR25;
thread->Registers.gpr26 = ctx->GPR26;
thread->Registers.gpr27 = ctx->GPR27;
thread->Registers.gpr28 = ctx->GPR28;
thread->Registers.gpr29 = ctx->GPR29;
thread->Registers.gpr30 = ctx->GPR30;
thread->Registers.gpr31 = ctx->GPR31;
thread->Registers.cr = ctx->EXC_CR;
thread->Registers.pc = ctx->EXC_SRR0;
thread->Registers.msr = ctx->EXC_SRR1;
thread->Registers.gpr13 = ctx->GPR13;
thread->Registers.gpr14 = ctx->GPR14;
thread->Registers.gpr15 = ctx->GPR15;
thread->Registers.gpr16 = ctx->GPR16;
thread->Registers.gpr17 = ctx->GPR17;
thread->Registers.gpr18 = ctx->GPR18;
thread->Registers.gpr19 = ctx->GPR19;
thread->Registers.gpr20 = ctx->GPR20;
thread->Registers.gpr21 = ctx->GPR21;
thread->Registers.gpr22 = ctx->GPR22;
thread->Registers.gpr23 = ctx->GPR23;
thread->Registers.gpr24 = ctx->GPR24;
thread->Registers.gpr25 = ctx->GPR25;
thread->Registers.gpr26 = ctx->GPR26;
thread->Registers.gpr27 = ctx->GPR27;
thread->Registers.gpr28 = ctx->GPR28;
thread->Registers.gpr29 = ctx->GPR29;
thread->Registers.gpr30 = ctx->GPR30;
thread->Registers.gpr31 = ctx->GPR31;
thread->Registers.cr = ctx->EXC_CR;
thread->Registers.pc = ctx->EXC_SRR0;
thread->Registers.msr = ctx->EXC_SRR1;
}
int
Single_Step(CPU_Exception_frame* ctx)
int
Single_Step (CPU_Exception_frame * ctx)
{
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
/*
* Check coherency
*/
assert ((ctx->EXC_SRR1 & MSR_SE) != 0);
assert (ExitForSingleStep != 0);
return 0;
@@ -124,33 +123,54 @@ Single_Step(CPU_Exception_frame* ctx)
return 0;
}
int
CheckForSingleStep (CPU_Exception_frame* ctx)
int
CheckForSingleStep (CPU_Exception_frame * ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep = 0;
return 1;
}
return 0;
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
void
CancelSingleStep (CPU_Exception_frame* ctx)
void
CancelSingleStep (CPU_Exception_frame * ctx)
{
/* Cancel scheduled SS */
/*
* Cancel scheduled SS
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
ExitForSingleStep--;
}
cpuExcHandlerType oldExcHandler;
void connect_rdbg_exception()
static cpuExcHandlerType oldExcHandler;
void
connect_rdbg_exception ()
{
oldExcHandler = globalExceptHdl;
globalExceptHdl = BreakPointExcHdl ;
/*
* test if rdbg already connected its exception handler
*/
if (globalExceptHdl != BreakPointExcHdl) {
oldExcHandler = globalExceptHdl;
globalExceptHdl = BreakPointExcHdl;
}
}
void
disconnect_rdbg_exception ()
{
/*
* test if current execption handler is rdbg's one
* and restore the original one in this case.
*/
if (globalExceptHdl == BreakPointExcHdl) {
globalExceptHdl = oldExcHandler;
}
}

View File

@@ -19,52 +19,47 @@
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
extern rtems_id eventTaskId;
extern rtems_id debugId;
extern Exception_context *FirstCtx;
extern Exception_context *LastCtx;
extern CPU_Exception_frame SavedContext;
extern unsigned int NbExceptCtx;
/*
* return a pointer to the Thread Control structure of the specified
* Id
*/
/* --------------------------------------------------------------------
return a pointer to the Thread Control structure of the specified
Id
-------------------------------------------------------------------- */
Thread_Control *Thread_Get_RDBG (
Objects_Id Id
)
Thread_Control *
Thread_Get_RDBG (Objects_Id Id)
{
unsigned index;
if ( Id <_Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
if (Id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
Id > _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index] != NULL) {
return (Thread_Control *)(_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index]);
if (_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1 + index] != NULL) {
return (Thread_Control*) (_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1 + index]);
}
}
if ( Id <_Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id >_Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
if (Id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
Id > _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
index = Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
if ( _Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index] != NULL)
return (Thread_Control *)(_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index]);
if (_Objects_Information_table[OBJECTS_POSIX_THREADS]->
local_table[1 + index] != NULL)
return (Thread_Control*) (_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1 + index]);
}
return 0;
}
/* --------------------------------------------------------------------
Memory read
-------------------------------------------------------------------- */
int
safeMemRead(void *src, void *dest, int nbBytes){
int
safeMemRead (void *src, void *dest, int nbBytes)
{
/*
* safe because if it generates an exception,
@@ -72,261 +67,261 @@ safeMemRead(void *src, void *dest, int nbBytes){
* TBD
*/
memcpy(dest, src, nbBytes);
memcpy (dest, src, nbBytes);
return 0;
}
/* --------------------------------------------------------------------
Memory write
-------------------------------------------------------------------- */
int
safeMemWrite(void *src, void * dest, int nbBytes){
int
safeMemWrite (void *src, void *dest, int nbBytes)
{
/*
* safe because if it generates an exception,
* it must return normally
* TBD
*/
memcpy(dest, src, nbBytes);
return 0;
memcpy (dest, src, nbBytes);
return 0;
}
/* --------------------------------------------------------------------
Ptrace
-------------------------------------------------------------------- */
int
ptrace (int request, int pid, char *addr, int data, char *addr2)
{
int diag;
errno = 0;
if (pid != 1) {
errno = ESRCH;
return -1;
}
switch (request) {
int
ptrace (int request, int pid, char* addr, int data, char* addr2)
{
int diag;
errno = 0 ;
if (pid != 1) {
errno = ESRCH;
return -1;
}
switch (request) {
case RPT_SINGLESTEP:{
Exception_context *ctx;
case RPT_SINGLESTEP:{
Exception_context *ctx;
if (CannotRestart == 1) {
setErrno (EIO);
return -1;
}
if (CannotRestart == 1){
setErrno(EIO);
return -1;
}
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
Single_Step(ctx->ctx);
rtems_semaphore_release( ctx->semaphoreId );
return 0;
}
break;
}
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
Single_Step (ctx->ctx);
rtems_semaphore_release (ctx->semaphoreId);
return 0;
}
break;
}
case RPT_PEEKTEXT:
case RPT_PEEKDATA: {
diag = safeMemRead(addr, &data, sizeof data);
if (diag == 0) return data;
mem_error:
return -1;
}
case RPT_PEEKTEXT:
case RPT_PEEKDATA:{
diag = safeMemRead (addr, &data, sizeof data);
if (diag == 0)
return data;
mem_error:
return -1;
}
case RPT_POKETEXT: {
diag = safeMemWrite(&data, addr, sizeof data);
case RPT_POKETEXT:{
diag = safeMemWrite (&data, addr, sizeof data);
/*
* We must flush the INSTR and DATA cache to be sure the
* opcode modification is taken into account, because
* the breakpoint opcode is written via the data cache
* while execution code is fetched via the instruction
* cache
*/
if (diag == 0) {
copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
return 0;
}
goto mem_error;
}
case RPT_POKEDATA: {
diag = safeMemWrite(&data, addr, sizeof data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_CONT: {
Exception_context *ctx;
/*
* We must flush the INSTR and DATA cache to be sure the
* opcode modification is taken into account, because
* the breakpoint opcode is written via the data cache
* while execution code is fetched via the instruction
* cache
*/
if (CannotRestart == 1){
setErrno (EIO);
return -1;
}
ctx = GetExceptCtx (currentTargetThread);
if (diag == 0) {
copyback_data_cache_and_invalidate_instr_cache (addr, sizeof data);
return 0;
}
goto mem_error;
}
case RPT_POKEDATA:{
diag = safeMemWrite (&data, addr, sizeof data);
if (diag == 0)
return 0;
goto mem_error;
}
case RPT_CONT:{
Exception_context *ctx;
if (!isRdbgException(ctx)) {
CannotRestart = 1;
setErrno (EIO);
return -1;
}
if (CannotRestart == 1) {
setErrno (EIO);
return -1;
}
assert (data == 0);
assert (ExitForSingleStep == 0);
ctx = GetExceptCtx (currentTargetThread);
if (ctx == NULL)
ctx = GetExceptCtx (debugId);
rtems_semaphore_release( serializeSemId );
if (ctx != NULL) {
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
rtems_semaphore_release( ctx->semaphoreId );
}
return 0;
}
case RPT_ATTACH:
return 0;
case RPT_DETACH:{
Exception_context *ctx;
if (NbExceptCtx || NbSerializedCtx) {
ctx = FirstCtx;
rtems_task_delete(eventTaskId);
rtems_semaphore_delete(serializeSemId);
rtems_semaphore_delete(wakeupEventSemId);
}
return 0;
}
case RPT_GETREGS:{
Exception_context *ctx;
if (!isRdbgException (ctx)) {
CannotRestart = 1;
setErrno (EIO);
return -1;
}
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs*) addr);
return 0;
}
break;
}
assert (data == 0);
assert (ExitForSingleStep == 0);
case RPT_SETREGS:{
Exception_context *ctx;
rtems_semaphore_release (ctx->semaphoreId);
}
rtems_semaphore_release (serializeSemId);
return 0;
}
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
RegsToCtx ((xdr_regs*) addr, ctx->ctx);
return 0;
}
break;
}
case RPT_READTEXT:
case RPT_READDATA: {
diag = safeMemRead(addr, addr2, data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_WRITETEXT:
case RPT_WRITEDATA: {
diag = safeMemWrite(addr2, addr, data);
if (diag == 0) return 0;
goto mem_error;
}
case RPT_GETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
return currentTargetThread;
case RPT_ATTACH:
return 0;
case RPT_SETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
currentTargetThread = data;
return 0;
case RPT_GETTHREADNAME: {
return TgtGetThreadName (NULL, (unsigned)(data), (char *) addr);
}
case RPT_THREADLIST: {
int count = TgtThreadList (NULL, (unsigned*) addr, UTHREAD_MAX
* sizeof (unsigned));
if (count < 0) {
errno = EINVAL;
return -1;
}
return count;
}
case RPT_DETACH:{
Exception_context *ctx;
case RPT_SETTHREADREGS: {
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned)id)
break;
if ((ctx = GetExceptCtx (data)) != NULL) {
RegsToCtx ((xdr_regs*) addr, ctx->ctx);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id)(data));
if (thread != NULL) {
RegsToCtx ((xdr_regs*) addr, &Ectx);
set_ctx_thread (thread, &Ectx);
return 0;
}
break;
}
if (NbExceptCtx || NbSerializedCtx) {
ctx = FirstCtx;
rtems_task_delete (eventTaskId);
rtems_semaphore_delete (serializeSemId);
rtems_semaphore_delete (wakeupEventSemId);
}
return 0;
}
case RPT_GETTHREADREGS: {
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned)id){
justSaveContext = 1;
enterRdbg();
CtxToRegs (&(SavedContext), (xdr_regs*) addr);
return 0;
}
if ((ctx = GetExceptCtx (data)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs*) addr);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id)(data));
if (thread != NULL) {
get_ctx_thread (thread, &Ectx);
CtxToRegs (&Ectx, (xdr_regs*) addr);
return 0;
}
break;
}
case RPT_KILL:
TotalReboot = 1;
return 0;
case RPT_GETREGS:{
Exception_context *ctx;
case RPT_TRACEME:
case RPT_PEEKUSER:
case RPT_POKEUSER:
case RPT_GETFPREGS:
case RPT_SETFPREGS:
case RPT_GETFPAREGS:
case RPT_SETFPAREGS:
case RPT_SYSCALL:
case RPT_DUMPCORE:
case RPT_GETUCODE:
case RPT_THREADSUSPEND:
case RPT_THREADRESUME:
case RPT_SETTHREADNAME:
default:
break;
}
errno = EINVAL;
return -1;
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs *) addr);
return 0;
}
break;
}
case RPT_SETREGS:{
Exception_context *ctx;
if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
RegsToCtx ((xdr_regs *) addr, ctx->ctx);
return 0;
}
break;
}
case RPT_READTEXT:
case RPT_READDATA:{
diag = safeMemRead (addr, addr2, data);
if (diag == 0)
return 0;
goto mem_error;
}
case RPT_WRITETEXT:
case RPT_WRITEDATA:{
diag = safeMemWrite (addr2, addr, data);
if (diag == 0)
return 0;
goto mem_error;
}
case RPT_GETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
return currentTargetThread;
case RPT_SETTARGETTHREAD:
if (!NbExceptCtx) {
errno = EBUSY;
return -1;
}
currentTargetThread = data;
return 0;
case RPT_GETTHREADNAME:{
return TgtGetThreadName (NULL, (unsigned) (data), (char *) addr);
}
case RPT_THREADLIST:{
int count = TgtThreadList (NULL, (unsigned *) addr, UTHREAD_MAX
* sizeof (unsigned));
if (count < 0) {
errno = EINVAL;
return -1;
}
return count;
}
case RPT_SETTHREADREGS:{
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned) id)
break;
if ((ctx = GetExceptCtx (data)) != NULL) {
RegsToCtx ((xdr_regs *) addr, ctx->ctx);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id) (data));
if (thread != NULL) {
RegsToCtx ((xdr_regs *) addr, &Ectx);
set_ctx_thread (thread, &Ectx);
return 0;
}
break;
}
case RPT_GETTHREADREGS:{
Exception_context *ctx;
CPU_Exception_frame Ectx;
Thread_Control *thread;
rtems_id id;
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
if (data == (unsigned) id) {
justSaveContext = 1;
enterRdbg ();
CtxToRegs (&(SavedContext), (xdr_regs *) addr);
return 0;
}
if ((ctx = GetExceptCtx (data)) != NULL) {
CtxToRegs (ctx->ctx, (xdr_regs *) addr);
return 0;
}
thread = Thread_Get_RDBG ((Objects_Id) (data));
if (thread != NULL) {
get_ctx_thread (thread, &Ectx);
CtxToRegs (&Ectx, (xdr_regs *) addr);
return 0;
}
break;
}
case RPT_KILL:
TotalReboot = 1;
return 0;
case RPT_TRACEME:
case RPT_PEEKUSER:
case RPT_POKEUSER:
case RPT_GETFPREGS:
case RPT_SETFPREGS:
case RPT_GETFPAREGS:
case RPT_SETFPAREGS:
case RPT_SYSCALL:
case RPT_DUMPCORE:
case RPT_GETUCODE:
case RPT_THREADSUSPEND:
case RPT_THREADRESUME:
case RPT_SETTHREADNAME:
default:
break;
}
errno = EINVAL;
return -1;
}

View File

@@ -3,7 +3,7 @@
*
* Component =
*
* Synopsis = rkdb/rkdb.c
* Synopsis = rdbg.c
*
* $Id$
*
@@ -21,131 +21,128 @@
#include <sys/socket.h>
#include <netinet/in.h>
u_short rtemsPort = RTEMS_PORT;
int BackPort = RTEMS_BACK_PORT;
int rtemsActive = 0;
SVCXPRT* rtemsXprt;
int rtemsSock;
char ActName[] = "RTEMS";
volatile int ExitForSingleStep = 0 ;
volatile int Continue;
volatile int justSaveContext;
volatile Objects_Id currentTargetThread;
volatile int CannotRestart = 0;
volatile int TotalReboot = 0;
u_short rtemsPort = RTEMS_PORT;
int BackPort = RTEMS_BACK_PORT;
int rtemsActive = 0;
SVCXPRT *rtemsXprt;
int rtemsSock;
char taskName[] = "RTEMS rdbg daemon";
volatile int ExitForSingleStep = 0;
volatile int Continue;
volatile int justSaveContext;
volatile Objects_Id currentTargetThread;
volatile int CannotRestart = 0;
volatile int TotalReboot = 0;
int CONN_LIST_INC = 3;
int PID_LIST_INC = 1;
int TSP_RETRIES = 10;
int PID_LIST_INC = 1;
int TSP_RETRIES = 10;
int
getId()
int
getId ()
{
rtems_id id;
rtems_task_ident(RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
return (int)(id) ;
rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
return (int) (id);
}
static void
remotedeb_2_hook(struct svc_req *rqstp, register SVCXPRT *transp)
{
connect_rdbg_exception(); /* monitor stub changes trace vector */
remotedeb_2(rqstp, transp);
connect_rdbg_exception();
}
static int
static int
rdbgInit (void)
{
int sock;
struct sockaddr_in addr;
int sock;
struct sockaddr_in addr;
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
printf("%s: rkdbInit: cannot allocate socket\n", ActName);
return -1;
}
sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
printf ("%s: rdbgInit: cannot allocate socket\n", taskName);
return -1;
}
bzero( (void *)&addr, sizeof(struct sockaddr_in));
addr.sin_port = htons(rtemsPort);
if ((bind(sock, (struct sockaddr*) &addr, sizeof(addr))) == -1) {
printf("%s: rkdbInit: cannot bind socket\n", ActName);
return -2;
}
rtemsXprt = svcudp_create(sock);
if (svcudp_enablecache(rtemsXprt, 1) == 0) {
printf("%s: rkdbInit: cannot enable rpc cache\n", ActName);
return -3;
}
rtemsSock = sock;
if (!svc_register(rtemsXprt, REMOTEDEB, REMOTEVERS, remotedeb_2, 0)) {
printf(stderr, "unable to register (REMOTEDEB, REMOTEVERS, udp).");
return -4;
}
bzero ((void *) &addr, sizeof (struct sockaddr_in));
addr.sin_port = htons (rtemsPort);
if ((bind (sock, (struct sockaddr *) &addr, sizeof (addr))) == -1) {
printf ("%s: rdbgInit: cannot bind socket\n", taskName);
return -2;
}
rtemsXprt = svcudp_create (sock);
if (svcudp_enablecache (rtemsXprt, 1) == 0) {
printf ("%s: rdbgInit: cannot enable rpc cache\n", taskName);
return -3;
}
rtemsSock = sock;
if (!svc_register (rtemsXprt, REMOTEDEB, REMOTEVERS, remotedeb_2, 0)) {
printf (stderr, "unable to register (REMOTEDEB, REMOTEVERS, udp).");
return -4;
}
connect_rdbg_exception ();
return 0;
return 0;
}
rtems_task
rtems_task
rdbgDaemon (rtems_task_argument argument)
{
svc_run();
svc_run ();
}
void
void
rtems_rdbg_initialize (void)
{
rtems_name task_name;
rtems_id tid;
rtems_name task_name;
rtems_id tid;
rtems_status_code status;
#ifdef DDEBUG
rdb_debug = 1; /* DPRINTF now will display */
rdb_debug = 1; /* DPRINTF now will display */
#endif
DPRINTF (("%s init starting\n", ActName));
DPRINTF (("%s init starting\n", taskName));
/* Print version string */
/*
* Print version string
*/
#ifdef DDEBUG
printk ("RDBG v.%d built on [%s %s]\n", SERVER_VERS, __DATE__, __TIME__);
printk ("RDBG v.%d built on [%s %s]\n", SERVER_VERS, __DATE__, __TIME__);
#else
printk ("RDBG v.%d\n", SERVER_VERS);
printk ("RDBG v.%d\n", SERVER_VERS);
#endif
/* Create socket and init UDP RPC server */
if (rdbgInit() != 0) goto error;
/*
* Create socket and init UDP RPC server
*/
if (rdbgInit () != 0)
goto error;
Continue = 1;
justSaveContext = 0;
currentTargetThread = 0;
task_name = rtems_build_name( 'R', 'D', 'B', 'G' );
if ((status = rtems_task_create( task_name, 5, 24576,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES | RTEMS_SYSTEM_TASK
, &tid ))
!= RTEMS_SUCCESSFUL){
printf("status = %d\n",status);
rtems_panic ("Can't create task.\n");
}
Continue = 1;
justSaveContext = 0;
currentTargetThread = 0;
status = rtems_task_start(tid, rdbgDaemon, 0);
task_name = rtems_build_name ('R', 'D', 'B', 'G');
if ((status = rtems_task_create (task_name, 5, 24576,
RTEMS_INTERRUPT_LEVEL (0),
RTEMS_DEFAULT_ATTRIBUTES |
RTEMS_SYSTEM_TASK, &tid))
!= RTEMS_SUCCESSFUL) {
printf ("status = %d\n", status);
rtems_panic ("Can't create task.\n");
}
return;
status = rtems_task_start (tid, rdbgDaemon, 0);
return;
error:
printf ("initialization failed.\n");
printf ("initialization failed.\n");
}
void
void
setErrno (int error)
{
errno = error;
errno = error;
}
int
getErrno()
int
getErrno ()
{
return errno;
return errno;
}

View File

@@ -291,43 +291,8 @@ union ptrace_addr_data_out switch (ptracereq req) {
typedef opaque CHAR_DATA <NET_SAFE>; /* variable sized data */
const XRY_MAX_INST_BUFF = 128;
const XRY_MAX_INSTANCES = 16;
%#ifndef XRY_MAX_CMD_STR
const XRY_MAX_CMD_STR = 320; /* XRY_MAX_INST_BUFF+(XRY_MAX_INSTANCES*12) */
%#endif /* REMDEB_H */
struct xry_inst
{
unsigned char flags; /* value2 interp, etc. INFL_xxx */
unsigned char type; /* base type of data (str, val, etc) INST_xxx */
unsigned char sub_type; /* specific type (task, res, etc). This is
set and defined by the user defined instance
processor and not the auto-processor */
unsigned char res_type;
u_long value; /* pointer to value or value itself */
u_long value2; /* second value (optional - based on flags) */
};
struct instance
{
struct xry_inst instances[XRY_MAX_INSTANCES];
unsigned char buffer[XRY_MAX_INST_BUFF];
};
union instance_union switch (bool instances)
{
case TRUE:
instance inst;
case FALSE:
string buffer <XRY_MAX_CMD_STR>;
};
typedef string one_arg <NET_SAFE>;
const XRY_MAX_OBJ_NAME = 32; /* objname in some commands */
% /* now open_connex() routine which establishes a connection to server */
enum debug_type

View File

@@ -12,14 +12,14 @@
*/
#include <sys/errno.h>
#include <assert.h>
#include <assert.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
/*----- Macros -----*/
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
#define BKPT_INCR 5 /* how many bkpt slots alloc at a time */
#define BKPT_INCR 5 /* how many bkpt slots alloc at a time */
#define BKPT_OVER(plst,idx,addr,size) \
((plst)->break_list[idx].ee_loc + BREAK_SIZE > (UINT32) (addr) \
@@ -29,7 +29,6 @@
(sizeof ((xdr_break*) 0)->thread_list / \
sizeof ((xdr_break*) 0)->thread_list [0])
/*
* BreakAlloc - alloc a breakpoint entry.
*
@@ -38,45 +37,51 @@
* created. It returns -1 if failed.
*/
static int
BreakAlloc (PID_LIST* plst, Boolean normal)
static int
BreakAlloc (PID_LIST * plst, Boolean normal)
{
int idx, len;
xdr_break* blst;
int idx, len;
xdr_break *blst;
if (!normal) { /* want 0 entry */
if (plst->break_list) {
return(0); /* already there */
}
idx = 1; /* force alloc below */
} else {
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type == BRKT_NONE) {
/* got a free one */
memset(&plst->break_list[idx], 0, sizeof(xdr_break));
return(idx); /* found one */
}
}
if (!normal) { /* want 0 entry */
if (plst->break_list) {
return (0); /* already there */
}
/* idx is the requested entry */
if (idx >= (int)plst->break_alloc) { /* need more space */
len = plst->break_alloc + BKPT_INCR;
blst = (xdr_break*)Realloc(plst->break_list, len*sizeof(xdr_break));
if (!blst) {
return(-1); /* failed, no space */
}
plst->break_alloc = len; /* got more */
plst->break_list = blst;
/* Clear new space */
memset(blst + len - BKPT_INCR, 0, BKPT_INCR * sizeof(xdr_break));
idx = len - BKPT_INCR; /* next available */
if (!idx) {
idx = 1; /* for normal cases */
}
idx = 1; /* force alloc below */
} else {
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
if (plst->break_list[idx].type == BRKT_NONE) {
/*
* got a free one
*/
memset (&plst->break_list[idx], 0, sizeof (xdr_break));
return (idx); /* found one */
}
}
return(normal ? idx : 0); /* return it */
}
/*
* idx is the requested entry
*/
if (idx >= (int) plst->break_alloc) { /* need more space */
len = plst->break_alloc + BKPT_INCR;
blst = (xdr_break *) Realloc (plst->break_list, len * sizeof (xdr_break));
if (!blst) {
return (-1); /* failed, no space */
}
plst->break_alloc = len; /* got more */
plst->break_list = blst;
/*
* Clear new space
*/
memset (blst + len - BKPT_INCR, 0, BKPT_INCR * sizeof (xdr_break));
idx = len - BKPT_INCR; /* next available */
if (!idx) {
idx = 1; /* for normal cases */
}
}
return (normal ? idx : 0); /* return it */
}
/*
@@ -86,237 +91,259 @@ BreakAlloc (PID_LIST* plst, Boolean normal)
*/
#ifdef DDEBUG
static const char* BreakTypes[] = {
"NONE", "INSTR", "READ", "WRITE",
"ACCESS", "EXEC", "OS_CALL", "OS_SWITCH",
"STEPEMUL"
static const char *BreakTypes[] = {
"NONE", "INSTR", "READ", "WRITE",
"ACCESS", "EXEC", "OS_CALL", "OS_SWITCH",
"STEPEMUL"
};
#define BN_MAX (sizeof BreakTypes / sizeof BreakTypes[0])
#define BREAK_NAME(t) ((unsigned) (t) < BN_MAX ? BreakTypes[t] : "???")
#endif
int
BreakSet (PID_LIST* plst, int conn_idx, xdr_break* bkpt)
int
BreakSet (PID_LIST * plst, int conn_idx, xdr_break * bkpt)
{
int pid = plst->pid;
int type = bkpt->type;
void* addr = (void *) bkpt->ee_loc;
int idx;
int data;
DPRINTF(("BreakSet: type %d (%s) at 0x%x th %d ee_type %d len %d "
"pass %d curr %d list %d %d %d %d\n", type, BREAK_NAME(type),
(int) addr,
bkpt->thread_spec, bkpt->ee_type, bkpt->length, bkpt->pass_count,
bkpt->curr_pass, bkpt->thread_list [0], bkpt->thread_list [1],
bkpt->thread_list [2], bkpt->thread_list [3]));
int pid = plst->pid;
int type = bkpt->type;
void *addr = (void *) bkpt->ee_loc;
int idx;
int data;
idx = BreakAlloc(plst, True); /* get entry */
if (idx < 0) { /* no memory */
setErrno(ENOMEM); /* set for safety */
return -1; /* return the error */
}
DPRINTF (("BreakSet: type %d (%s) at 0x%x th %d ee_type %d len %d "
"pass %d curr %d list %d %d %d %d\n", type, BREAK_NAME (type),
(int) addr,
bkpt->thread_spec, bkpt->ee_type, bkpt->length, bkpt->pass_count,
bkpt->curr_pass, bkpt->thread_list[0], bkpt->thread_list[1],
bkpt->thread_list[2], bkpt->thread_list[3]));
data = TgtPtrace(RPT_PEEKTEXT, pid, addr, 0, NULL); /* current */
if (getErrno()) {
return -1; /* failed, return the error */
}
if (IS_BREAK(data)) { /* There is already a break here */
DPRINTF(("BreakSet: already have soft bkpt at %x\n", addr));
if (type == BRKT_STEPEMUL) {
++BKPT0 (plst)->pad1;
return 1; /* Any non-error value is OK */
}
setErrno(EBUSY);
return -1;
}
idx = BreakAlloc (plst, True); /* get entry */
if (idx < 0) { /* no memory */
setErrno (ENOMEM); /* set for safety */
return -1; /* return the error */
}
TgtPtrace(RPT_POKETEXT, pid, addr, SET_BREAK(data), NULL);
if (getErrno()) {
return -1;
data = TgtPtrace (RPT_PEEKTEXT, pid, addr, 0, NULL); /* current */
if (getErrno ()) {
return -1; /* failed, return the error */
}
if (IS_BREAK (data)) { /* There is already a break here */
DPRINTF (("BreakSet: already have soft bkpt at %x\n", addr));
if (type == BRKT_STEPEMUL) {
++BKPT0 (plst)->pad1;
return 1; /* Any non-error value is OK */
}
setErrno (EBUSY);
return -1;
}
plst->break_list[idx] = *bkpt;
plst->break_list[idx].ee_type = data; /* saved data */
/* Inform other owners */
if (type != BRKT_STEPEMUL) {
TgtNotifyAll (plst - pid_list, BMSG_BREAK, 1 /*added*/, idx,
conn_idx, False);
} else {
++BKPT0 (plst)->pad1;
}
/* Return the number */
setErrno(0); /* Just in case */
return idx;
TgtPtrace (RPT_POKETEXT, pid, addr, SET_BREAK (data), NULL);
if (getErrno ()) {
return -1;
}
plst->break_list[idx] = *bkpt;
plst->break_list[idx].ee_type = data; /* saved data */
/*
* Inform other owners
*/
if (type != BRKT_STEPEMUL) {
TgtNotifyAll (plst - pid_list, BMSG_BREAK, 1 /*added */ , idx,
conn_idx, False);
} else {
++BKPT0 (plst)->pad1;
}
/*
* Return the number
*/
setErrno (0); /* Just in case */
return idx;
}
int
BreakSetAt (PID_LIST* plst, int conn_idx, unsigned long addr, break_type type)
int
BreakSetAt (PID_LIST * plst, int conn_idx, unsigned long addr,
break_type type)
{
xdr_break xb;
xdr_break xb;
memset (&xb, 0, sizeof xb);
xb.type = type;
xb.ee_loc = addr;
return BreakSet (plst, conn_idx, &xb);
memset (&xb, 0, sizeof xb);
xb.type = type;
xb.ee_loc = addr;
return BreakSet (plst, conn_idx, &xb);
}
/*----- Find a breakpoint by address -----*/
int
BreakGetIndex(PID_LIST* plst, void* addr)
int
BreakGetIndex (PID_LIST * plst, void *addr)
{
int idx;
int data = -1;
int idx;
int data = -1;
if (!plst->break_alloc) {
setErrno(EFAULT);
return -1;
if (!plst->break_alloc) {
setErrno (EFAULT);
return -1;
}
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
if ((u_long) addr == plst->break_list[idx].ee_loc) {
data = idx;
break;
}
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if ((u_long) addr == plst->break_list [idx].ee_loc) {
data = idx;
break;
}
}
return data;
}
return data;
}
/*----- Getting information about breakpoint -----*/
/*
* If data > 0, fill "bkpt" with information about breakpoint
* If data > 0, fill "bkpt" with information about breakpoint
* and return the number of the next one.
* If data == 0, return the count of breakpoints.
*/
int
BreakGet (const PID_LIST* plst, int data, xdr_break* bkpt)
int
BreakGet (const PID_LIST * plst, int data, xdr_break * bkpt)
{
int idx;
int idx;
if (!data) { /* just count them */
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
data++;
}
}
return data; /* count */
if (!data) { /* just count them */
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
data++;
}
}
if ((unsigned) data >= plst->break_alloc) {
/* out of range */
setErrno(EFAULT); /* closest match */
return -1;
return data; /* count */
}
if ((unsigned) data >= plst->break_alloc) {
/*
* out of range
*/
setErrno (EFAULT); /* closest match */
return -1;
}
/*
* get it and say which is next
*/
*bkpt = plst->break_list[data];
for (idx = (int) data + 1; idx < (int) plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
return idx;
}
/* get it and say which is next */
*bkpt = plst->break_list[data];
for (idx = (int)data+1; idx < (int)plst->break_alloc; idx++) {
if (plst->break_list[idx].type != BRKT_NONE) {
return idx;
}
}
return 0; /* otherwise returns 0 for no more */
}
return 0; /* otherwise returns 0 for no more */
}
/*----- Clearing bkpts -----*/
/*
* BreakClear - clear one (if data != 0) or all breakpoints
* BreakClear - clear one (if data != 0) or all breakpoints
* (if data == 0). Return the number of bkpts cleared.
* If (data == -1), remove step-emulation breakpoints.
*/
int
BreakClear (PID_LIST* plst, int conn_idx, int data)
int
BreakClear (PID_LIST * plst, int conn_idx, int data)
{
int pid_idx = plst - pid_list;
int idx;
int cleared = 0;
int clearStepEmul = 0;
int terminated = PROC_TERMINATED (plst);
int stepEmulCount = 0;
int pid_idx = plst - pid_list;
int idx;
int cleared = 0;
int clearStepEmul = 0;
int terminated = PROC_TERMINATED (plst);
int stepEmulCount = 0;
/* break handle in data */
if (!plst->break_alloc) { /* there are no breaks */
DPRINTF (("BreakClear: no bkpts defined.\n"));
setErrno(EFAULT); /* closest match */
return -1; /* return error */
/*
* break handle in data
*/
if (!plst->break_alloc) { /* there are no breaks */
DPRINTF (("BreakClear: no bkpts defined.\n"));
setErrno (EFAULT); /* closest match */
return -1; /* return error */
}
if (!data) { /* clear all */
idx = 1;
data = plst->break_alloc - 1;
/*
* Inform other owners
*/
DPRINTF (("BreakClear: clearing all bkpts.\n"));
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , 0, conn_idx, False);
} else if (data == -1) { /* clear all step-emul bkpts */
DPRINTF (("BreakClear: removing %d step-emul bkpts\n",
BKPT0 (plst)->pad1));
stepEmulCount = BKPT0 (plst)->pad1;
BKPT0 (plst)->pad1 = 0;
clearStepEmul = 1;
idx = 1;
data = plst->break_alloc - 1;
} else if ((unsigned) data >= plst->break_alloc
|| plst->break_list[data].type == BRKT_NONE) {
/*
* out of range
*/
DPRINTF (("BreakClear: invalid bkpt %d\n", data));
setErrno (EFAULT); /* closest match */
return -1; /* return error */
} else {
idx = data;
/*
* Inform other owners
*/
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , idx, conn_idx, False);
DPRINTF (("BreakClear: clearing bkpt %d\n", data));
}
for (; idx <= data; idx++) { /* clear each one */
int type = plst->break_list[idx].type;
if (clearStepEmul && type != BRKT_STEPEMUL)
continue;
if (type == BRKT_INSTR || (clearStepEmul && type == BRKT_STEPEMUL)) {
/*
* just patch back
*/
char *addr = (char *) plst->break_list[idx].ee_loc;
int val;
if (BKPT0 (plst)->clr_step && BKPT0 (plst)->last_break == idx) {
BKPT0 (plst)->clr_step = 0; /* not needed */
}
/*
* Neighboring bytes can have breakpoints too...
*/
if (!terminated) {
setErrno (0);
val = TgtPtrace (RPT_PEEKTEXT, plst->pid, addr, 0, NULL);
if (getErrno ()) {
DPRINTF (("BreakClear: addr %x not readable!\n", addr));
setErrno (0); /* Forget bkpt */
} else {
assert (IS_BREAK (val));
val = ORG_BREAK (val, (int) plst->break_list[idx].ee_type);
TgtPtrace (RPT_POKETEXT, plst->pid, addr, val, NULL);
if (getErrno ()) {
DPRINTF (("BreakClear: addr %x not writable!\n", addr));
setErrno (0);
}
}
}
++cleared; /* indicate cleared */
}
if (!data) { /* clear all */
idx = 1;
data = plst->break_alloc-1;
/* Inform other owners */
DPRINTF (("BreakClear: clearing all bkpts.\n"));
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr*/, 0, conn_idx, False);
} else if (data == -1) { /* clear all step-emul bkpts */
DPRINTF(("BreakClear: removing %d step-emul bkpts\n",
BKPT0 (plst)->pad1));
stepEmulCount = BKPT0 (plst)->pad1;
BKPT0 (plst)->pad1 = 0;
clearStepEmul = 1;
idx = 1;
data = plst->break_alloc-1;
} else if ((unsigned) data >= plst->break_alloc
|| plst->break_list[data].type == BRKT_NONE) {
/* out of range */
DPRINTF (("BreakClear: invalid bkpt %d\n", data));
setErrno(EFAULT); /* closest match */
return -1; /* return error */
} else {
idx = data;
/* Inform other owners */
TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr*/, idx, conn_idx, False);
DPRINTF (("BreakClear: clearing bkpt %d\n", data));
}
for (; idx <= data; idx++) { /* clear each one */
int type = plst->break_list[idx].type;
if (clearStepEmul && type != BRKT_STEPEMUL) continue;
if (type == BRKT_INSTR || (clearStepEmul && type == BRKT_STEPEMUL)) {
/* just patch back */
char* addr = (char *)plst->break_list[idx].ee_loc;
int val;
if (BKPT0 (plst)->clr_step && BKPT0 (plst)->last_break == idx) {
BKPT0 (plst)->clr_step = 0; /* not needed */
}
/* Neighboring bytes can have breakpoints too... */
if (! terminated) {
setErrno (0);
val = TgtPtrace(RPT_PEEKTEXT, plst->pid, addr, 0, NULL);
if (getErrno()) {
DPRINTF (("BreakClear: addr %x not readable!\n", addr));
setErrno (0); /* Forget bkpt */
} else {
assert (IS_BREAK (val));
val = ORG_BREAK (val, (int)plst->break_list[idx].ee_type);
TgtPtrace(RPT_POKETEXT, plst->pid, addr, val, NULL);
if (getErrno()) {
DPRINTF (("BreakClear: addr %x not writable!\n", addr));
setErrno (0);
}
}
}
++cleared; /* indicate cleared */
}
memset(&plst->break_list[idx], 0, sizeof(xdr_break));
}
assert (!clearStepEmul || cleared <= stepEmulCount);
if (stepEmulCount && cleared == 0) {
DPRINTF (("BreakClear: all STEPEMUL bkpts were shared\n"));
return 1;
}
return cleared;
memset (&plst->break_list[idx], 0, sizeof (xdr_break));
}
assert (!clearStepEmul || cleared <= stepEmulCount);
if (stepEmulCount && cleared == 0) {
DPRINTF (("BreakClear: all STEPEMUL bkpts were shared\n"));
return 1;
}
return cleared;
}
/*----- Hiding of breakpoints -----*/
@@ -329,70 +356,84 @@ BreakClear (PID_LIST* plst, int conn_idx, int data)
* buffer from a ptrace read/peek.
*/
static void
PatchBreak (char* buff, UINT32 bstart, int bsize, UINT32 dstart, char* dvalue)
static void
PatchBreak (char *buff, UINT32 bstart, int bsize, UINT32 dstart, char *dvalue)
{
int size = BREAK_SIZE; /* default size */
int size = BREAK_SIZE; /* default size */
/* Must deal with all sorts of unalignments
* (3 full overlaps, 3 unaligns)
*/
if (bsize < BREAK_SIZE) {
/* case where buffer is smaller than data */
memcpy(buff, dvalue+(bstart-dstart), bsize); /* copy over */
return;
}
/* buffer larger than data.
* we need to see where break fits in buffer and whether
* we have part of it off the end. We set bstart to be the
* buffer offset, dtart to be the break data offset, and
* size to be the amount to copy
*/
if (dstart < bstart) {
/* break before actual buffer */
dstart = bstart-dstart; /* offset in data */
size -= dstart; /* amount to copy */
bstart = 0; /* offset in buffer */
/*
* Must deal with all sorts of unalignments
* * (3 full overlaps, 3 unaligns)
*/
if (bsize < BREAK_SIZE) {
/*
* case where buffer is smaller than data
*/
memcpy (buff, dvalue + (bstart - dstart), bsize); /* copy over */
return;
}
/*
* buffer larger than data.
* * we need to see where break fits in buffer and whether
* * we have part of it off the end. We set bstart to be the
* * buffer offset, dtart to be the break data offset, and
* * size to be the amount to copy
*/
if (dstart < bstart) {
/*
* break before actual buffer
*/
dstart = bstart - dstart; /* offset in data */
size -= dstart; /* amount to copy */
bstart = 0; /* offset in buffer */
} else if (dstart + size > bstart + bsize) {
/* off end */
bstart += bsize; /* end of buffer */
size -= (dstart + size) - bstart;
bstart = bsize - size; /* come back into buffer enough */
dstart = 0; /* start of data */
} else if (dstart + size > bstart + bsize) {
/*
* off end
*/
bstart += bsize; /* end of buffer */
size -= (dstart + size) - bstart;
bstart = bsize - size; /* come back into buffer enough */
dstart = 0; /* start of data */
} else { /* normal case */
bstart = dstart - bstart; /* offset in buffer */
dstart = 0;
}
memcpy(buff+bstart, dvalue+dstart, size);
} else { /* normal case */
bstart = dstart - bstart; /* offset in buffer */
dstart = 0;
}
memcpy (buff + bstart, dvalue + dstart, size);
}
void
BreakHide (const PID_LIST* plst, void* addr, int data, void* addr2)
void
BreakHide (const PID_LIST * plst, void *addr, int data, void *addr2)
{
int idx;
int idx;
if (!plst->break_list) /* no breaks exist, so skip this */
return;
if (!plst->break_list) /* no breaks exist, so skip this */
return;
/* if breakpoints, replace */
/*
* if breakpoints, replace
*/
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
/* break, see if overlaps */
if (BKPT_OVER (plst, idx, addr, data)) {
/* overlaps, patch in old value */
PatchBreak((char *)addr2, (UINT32)addr, data,
plst->break_list[idx].ee_loc,
(char *)&plst->break_list[idx].ee_type);
}
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
/*
* break, see if overlaps
*/
if (BKPT_OVER (plst, idx, addr, data)) {
/*
* overlaps, patch in old value
*/
PatchBreak ((char *) addr2, (UINT32) addr, data,
plst->break_list[idx].ee_loc,
(char *) &plst->break_list[idx].ee_type);
}
}
}
/*----- Checking of breakpoint overwrites -----*/
@@ -402,27 +443,29 @@ BreakHide (const PID_LIST* plst, void* addr, int data, void* addr2)
* having software breakpoints.
*/
int
BreakOverwrite (const PID_LIST* plst, const char* addr, unsigned int size)
int
BreakOverwrite (const PID_LIST * plst, const char *addr, unsigned int size)
{
int idx;
int idx;
if (!plst->break_list) { /* No breaks exist */
return 0;
}
for (idx = 1; idx < (int)plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
/* Consider only breakpoints involving modified memory */
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
if (BKPT_OVER (plst, idx, addr, size)) {
return -1; /* overlaps */
}
}
if (!plst->break_list) { /* No breaks exist */
return 0;
}
for (idx = 1; idx < (int) plst->break_alloc; idx++) {
int type = plst->break_list[idx].type;
/*
* Consider only breakpoints involving modified memory
*/
if (type != BRKT_INSTR && type != BRKT_STEPEMUL) {
continue;
}
if (BKPT_OVER (plst, idx, addr, size)) {
return -1; /* overlaps */
}
}
return 0;
}
/*----- Execution support -----*/
@@ -433,19 +476,21 @@ BreakOverwrite (const PID_LIST* plst, const char* addr, unsigned int size)
* Range is saved in breakpoint 0.
*/
int
BreakStepRange (PID_LIST* plst, void* addr, int len)
int
BreakStepRange (PID_LIST * plst, void *addr, int len)
{
if (!plst->break_list) {
/* get list */
if (BreakAlloc (plst, False) == -1) { /* must not be any memory */
setErrno(ENOMEM); /* to be safe */
return -1; /* fails */
}
if (!plst->break_list) {
/*
* get list
*/
if (BreakAlloc (plst, False) == -1) { /* must not be any memory */
setErrno (ENOMEM); /* to be safe */
return -1; /* fails */
}
BKPT0 (plst)->range_start = (UINT32)addr;
BKPT0 (plst)->range_end = (UINT32)addr+(len-1);
return 0;
}
BKPT0 (plst)->range_start = (UINT32) addr;
BKPT0 (plst)->range_end = (UINT32) addr + (len - 1);
return 0;
}
/*
@@ -453,137 +498,147 @@ BreakStepRange (PID_LIST* plst, void* addr, int len)
* current breakpoint has not been reached yet.
*/
void
BreakPcChanged (PID_LIST* plst)
void
BreakPcChanged (PID_LIST * plst)
{
if (plst->break_list) {
/* clear break stuff */
BKPT0 (plst)->clr_step = False;
}
if (plst->break_list) {
/*
* clear break stuff
*/
BKPT0 (plst)->clr_step = False;
}
}
/*
* BreakStepOff - prepare stepping off a breakpoint.
*/
int
BreakStepOff (const PID_LIST* plst, void** paddr2)
int
BreakStepOff (const PID_LIST * plst, void **paddr2)
{
if (plst->break_list && BKPT0 (plst)->clr_step) {
if (plst->break_list && BKPT0 (plst)->clr_step) {
/* need clear then step off break */
int last = BKPT0 (plst)->last_break;
/*
* need clear then step off break
*/
int last = BKPT0 (plst)->last_break;
/* clear break, step, then do exec */
/*
* clear break, step, then do exec
*/
*paddr2 = (void*) plst->break_list[last].ee_type;
*paddr2 = (void *) plst->break_list[last].ee_type;
/* Need to clr_step after TgtPtrace() when wait() returns */
return 1;
}
return 0;
/*
* Need to clr_step after TgtPtrace() when wait() returns
*/
return 1;
}
return 0;
}
/*
* BreakSteppedOff - check if just stepped off a breakpoint
* BreakSteppedOff - check if just stepped off a breakpoint
* and re-insert it into the code.
*/
void
BreakSteppedOff (PID_LIST* plst)
void
BreakSteppedOff (PID_LIST * plst)
{
if (plst->break_list && BKPT0 (plst)->clr_step) {
int idx = BKPT0 (plst)->last_break;
int data;
if (plst->break_list && BKPT0 (plst)->clr_step) {
int idx = BKPT0 (plst)->last_break;
int data;
BKPT0 (plst)->clr_step = 0;
BKPT0 (plst)->clr_step = 0;
/*
* Re-insert the breakpoint.
*/
data = TgtPtrace (RPT_PEEKTEXT, plst->pid,
(char *)plst->break_list [idx].ee_loc, 0, NULL);
assert (! IS_BREAK (data));
TgtPtrace (RPT_POKETEXT, plst->pid,
(char *)plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
}
/*
* Re-insert the breakpoint.
*/
data = TgtPtrace (RPT_PEEKTEXT, plst->pid,
(char *) plst->break_list[idx].ee_loc, 0, NULL);
assert (!IS_BREAK (data));
TgtPtrace (RPT_POKETEXT, plst->pid,
(char *) plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
}
}
/*
* Returns whether a thread matches a breakpoint.
*/
static int
BreakThreadMatch (xdr_break* xb, int thread)
static int
BreakThreadMatch (xdr_break * xb, int thread)
{
int slot;
int slot;
if (thread < 0) return 1; /* Break existence check only */
if (thread < 0)
return 1; /* Break existence check only */
if (xb->thread_list [0] == 0) return 1; /* Universal break */
if (xb->thread_list[0] == 0)
return 1; /* Universal break */
for (slot = 0; slot < BKPT_SLOTS; ++slot) {
if (xb->thread_list [slot] == 0) return 0; /* End of list */
if (xb->thread_list [slot] == thread) return 1; /* Match */
}
return 0; /* No matches found */
for (slot = 0; slot < BKPT_SLOTS; ++slot) {
if (xb->thread_list[slot] == 0)
return 0; /* End of list */
if (xb->thread_list[slot] == thread)
return 1; /* Match */
}
return 0; /* No matches found */
}
int
BreakAdjustPC (PID_LIST* plst)
int
BreakAdjustPC (PID_LIST * plst)
{
/*
* BREAK_ADJ is the value by which the Program Counter
* has to be decremented after a software breakpoint
* is hit. It must be defined and can be zero.
*/
/*
* BREAK_ADJ is the value by which the Program Counter
* has to be decremented after a software breakpoint
* is hit. It must be defined and can be zero.
*/
#if BREAK_ADJ
/* subtract back if necessary */
plst->regs.REG_PC -= BREAK_ADJ; /* now write back */
TgtPtrace(RPT_SETREGS, plst->pid, (char *)&plst->regs, 0, NULL);
/*
* subtract back if necessary
*/
plst->regs.REG_PC -= BREAK_ADJ; /* now write back */
TgtPtrace (RPT_SETREGS, plst->pid, (char *) &plst->regs, 0, NULL);
#else
(void) plst;
(void) plst;
#endif
return 0;
return 0;
}
/*
* Identify the current breakpoint. The process just stopped.
*/
int
BreakIdentify (PID_LIST* plst, int adjust, int thread)
int
BreakIdentify (PID_LIST * plst, int adjust, int thread)
{
int foreignBkpt = 0;
int bidx;
int foreignBkpt = 0;
int bidx;
for (bidx = 1; bidx < (int) plst->break_alloc; bidx++) {
int type = plst->break_list[bidx].type;
for (bidx = 1; bidx < (int) plst->break_alloc; bidx++) {
int type = plst->break_list[bidx].type;
if ((type == BRKT_INSTR || type == BRKT_STEPEMUL)
&& plst->regs.REG_PC - BREAK_ADJ
== plst->break_list[bidx].ee_loc) { /* found matching */
if (!BreakThreadMatch (&plst->break_list[bidx], thread)) {
if (foreignBkpt == 0) {
foreignBkpt = bidx;
}
continue;
}
if (adjust) {
BreakAdjustPC (plst);
}
return bidx;
}
if ((type == BRKT_INSTR || type == BRKT_STEPEMUL)
&& plst->regs.REG_PC - BREAK_ADJ == plst->break_list[bidx].ee_loc) { /* found matching */
if (!BreakThreadMatch (&plst->break_list[bidx], thread)) {
if (foreignBkpt == 0) {
foreignBkpt = bidx;
}
continue;
}
if (adjust) {
BreakAdjustPC (plst);
}
return bidx;
}
if (foreignBkpt) {
if (adjust) {
BreakAdjustPC (plst);
}
return -foreignBkpt;
}
if (foreignBkpt) {
if (adjust) {
BreakAdjustPC (plst);
}
return 0;
return -foreignBkpt;
}
return 0;
}

View File

@@ -11,10 +11,10 @@
**************************************************************************
*/
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
/*
* ConnCreate - create a new connection entry for a client.
*
@@ -25,66 +25,74 @@
* the caller.
*/
int
ConnCreate (struct svc_req* rqstp, open_in* in)
int
ConnCreate (struct svc_req *rqstp, open_in * in)
{
NET_OPAQUE sender;
int idx;
CONN_LIST* clst;
setErrno (0);
NET_OPAQUE sender;
int idx;
CONN_LIST *clst;
/* Convert to valid Net address */
if (! TspTranslateRpcAddr (rqstp, &sender)) {
DPRINTF (("ConnCreate: TspTranslateRpcAddr failed\n"));
return -1;
}
if (! TspValidateAddr ((NET_OPAQUE*) in->back_port, &sender)) {
DPRINTF (("ConnCreate: TspValidateAddr failed\n"));
return -1; /* errno now setup with error */
setErrno (0);
/*
* Convert to valid Net address
*/
if (!TspTranslateRpcAddr (rqstp, &sender)) {
DPRINTF (("ConnCreate: TspTranslateRpcAddr failed\n"));
return -1;
}
if (!TspValidateAddr ((NET_OPAQUE *) in->back_port, &sender)) {
DPRINTF (("ConnCreate: TspValidateAddr failed\n"));
return -1; /* errno now setup with error */
}
/*
* look for an empty connection entry
*/
for (idx = 0; idx < conn_list_cnt; idx++) {
if (!conn_list[idx].in_use)
break; /* an empty one found */
}
if (idx >= conn_list_cnt) { /* no empties, create space */
CONN_LIST *tmp_conn_list = conn_list;
conn_list_cnt += CONN_LIST_INC;
if (conn_list) {
conn_list = (CONN_LIST *) Realloc (conn_list, /* extend */
conn_list_cnt * sizeof (CONN_LIST));
} else {
conn_list = (CONN_LIST *) Malloc (conn_list_cnt * sizeof (CONN_LIST));
}
/* look for an empty connection entry */
for (idx = 0; idx < conn_list_cnt; idx++) {
if (!conn_list[idx].in_use)
break; /* an empty one found */
if (!conn_list) { /* unable to get space */
if ((conn_list_cnt -= CONN_LIST_INC)) {
/*
* was realloc, restore space
*/
conn_list = tmp_conn_list;
}
return -1; /* errno set by failed alloc */
}
/*
* clear newly created memory
*/
memset (conn_list + idx, 0, CONN_LIST_INC * sizeof (CONN_LIST));
} else { /* clear new entry */
memset (conn_list + idx, 0, sizeof (CONN_LIST));
}
clst = conn_list + idx;
if (idx >= conn_list_cnt) { /* no empties, create space */
CONN_LIST* tmp_conn_list = conn_list;
clst->in_use = True; /* now in use */
clst->sender = sender;
memcpy (&clst->back_port, &in->back_port, sizeof (NET_OPAQUE));
memcpy (&clst->route, &in->destination, sizeof (NET_OPAQUE));
clst->debug_type = (UCHAR) in->debug_type;
clst->flags = in->flags;
strncpy (clst->user_name, in->user_name, NAMEMAX - 1);
clst->user_name[NAMEMAX - 1] = 0;
conn_list_cnt += CONN_LIST_INC;
if (conn_list) {
conn_list = (CONN_LIST *) Realloc (conn_list, /* extend */
conn_list_cnt * sizeof (CONN_LIST));
} else {
conn_list = (CONN_LIST *)Malloc(conn_list_cnt * sizeof(CONN_LIST));
}
if (!conn_list) { /* unable to get space */
if ((conn_list_cnt -= CONN_LIST_INC)) {
/* was realloc, restore space */
conn_list = tmp_conn_list;
}
return -1; /* errno set by failed alloc */
}
/* clear newly created memory */
memset (conn_list + idx, 0, CONN_LIST_INC * sizeof (CONN_LIST));
} else { /* clear new entry */
memset (conn_list + idx, 0, sizeof (CONN_LIST));
}
clst = conn_list + idx;
clst->in_use = True; /* now in use */
clst->sender = sender;
memcpy (&clst->back_port, &in->back_port, sizeof (NET_OPAQUE));
memcpy (&clst->route, &in->destination, sizeof (NET_OPAQUE));
clst->debug_type = (UCHAR) in->debug_type;
clst->flags = in->flags;
strncpy (clst->user_name, in->user_name, NAMEMAX-1);
clst->user_name [NAMEMAX-1] = 0;
return idx;
return idx;
}
/*
@@ -92,47 +100,56 @@ ConnCreate (struct svc_req* rqstp, open_in* in)
*
*/
void
ConnDelete (int conn, struct svc_req* rqstp, close_control control)
void
ConnDelete (int conn, struct svc_req *rqstp, close_control control)
{
CONN_LIST* clst = conn_list + conn;
int idx;
Boolean prim;
CONN_LIST *clst = conn_list + conn;
int idx;
Boolean prim;
if (! clst->in_use) return; /* not active */
if (!clst->in_use)
return; /* not active */
for (idx = 0; idx < pid_list_cnt; idx++) {
PID_LIST* plst = pid_list + idx;
for (idx = 0; idx < pid_list_cnt; idx++) {
PID_LIST *plst = pid_list + idx;
if (! PIDMAP_TEST (conn, idx)) continue;
if (!PIDMAP_TEST (conn, idx))
continue;
/* found a controlled pid */
prim = (plst->primary_conn == conn) ? True : False;
TgtDetachCon (conn, idx, True);
/*
* found a controlled pid
*/
prim = (plst->primary_conn == conn) ? True : False;
TgtDetachCon (conn, idx, True);
/* if still running or alive, we use close control on it */
if (! plst->pid)
continue; /* entry gone */
/*
* if still running or alive, we use close control on it
*/
if (!plst->pid)
continue; /* entry gone */
if (prim && control == CLOSE_KILL) {
/* kill off process */
TgtKillAndDelete (plst, rqstp, True);
} else if (! plst->owners) {
/* no owners left */
if (control == CLOSE_DETACH) {
TgtKillAndDelete (plst, rqstp, False);
}
if (control == CLOSE_DETACH || PROC_TERMINATED (plst)) {
TgtDelete (plst, conn, (control==CLOSE_DETACH) ?
BMSG_DETACH : 0);
}
}
if (prim && control == CLOSE_KILL) {
/*
* kill off process
*/
TgtKillAndDelete (plst, rqstp, True);
} else if (!plst->owners) {
/*
* no owners left
*/
if (control == CLOSE_DETACH) {
TgtKillAndDelete (plst, rqstp, False);
}
if (control == CLOSE_DETACH || PROC_TERMINATED (plst)) {
TgtDelete (plst, conn, (control == CLOSE_DETACH) ? BMSG_DETACH : 0);
}
}
if (clst->list) {
Free (clst->list); /* free allocated memory */
}
DPRINTF (("ConnDelete: Connection closed for port %u\n",
HL_W(*((UINT16*) &clst->back_port.c[2]))));
}
if (clst->list) {
Free (clst->list); /* free allocated memory */
}
DPRINTF (("ConnDelete: Connection closed for port %u\n",
HL_W (*((UINT16 *) & clst->back_port.c[2]))));
clst->in_use = False; /* free it back */
clst->in_use = False; /* free it back */
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,12 +9,11 @@
**************************************************************************
*/
#include <string.h>
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <sys/socket.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <sys/socket.h>
#include <assert.h>
#ifdef DDEBUG
@@ -23,229 +22,234 @@
#define Ptrace TgtRealPtrace
#endif
/* ----------------------------------------------------------------
TgtBreakRestoreOrig - Restore original instruction at "addr"
just before single-stepping it.
---------------------------------------------------------------- */
/*
* TgtBreakRestoreOrig - Restore original instruction at "addr"
* just before single-stepping it.
*/
int TgtBreakRestoreOrig (int pid, void *addr, void *addr2)
/* Process identifier */
/* Breakpoint address */
/* Original instruction or bkpt number */
int
TgtBreakRestoreOrig (int pid, void *addr, void *addr2)
/*
* Process identifier
*/
/*
* Breakpoint address
*/
/*
* Original instruction or bkpt number
*/
{
int ret;
int l;
l = (long)Ptrace(RPT_PEEKTEXT, pid, addr, 0, NULL); /* assume ok */
ret = ORG_BREAK (l, (UINT32) addr2); /* reconstruct old instr */
ret = Ptrace(RPT_POKETEXT, pid, addr, ret, NULL); /* poke back old */
l = (long) Ptrace (RPT_PEEKTEXT, pid, addr, 0, NULL); /* assume ok */
ret = ORG_BREAK (l, (UINT32) addr2); /* reconstruct old instr */
ret = Ptrace (RPT_POKETEXT, pid, addr, ret, NULL); /* poke back old */
return ret;
}
/* -----------------------------------------------------------------------
TgtBreakCancelStep - Restore the breakpoint at "addr" if the single-step
has failed at the ptrace level.
----------------------------------------------------------------------- */
/*
*
* TgtBreakCancelStep - Restore the breakpoint at "addr" if the single-step
* has failed at the ptrace level.
*/
#define BKPT0(plst) ((BASE_BREAK*)(plst)->break_list)
void TgtBreakCancelStep (PID_LIST* plst)
void
TgtBreakCancelStep (PID_LIST * plst)
{
assert (plst->break_list);
assert (BKPT0 (plst)->clr_step);
if (plst->break_list && BKPT0 (plst)->clr_step) {
if (plst->break_list && BKPT0 (plst)->clr_step) {
int idx = BKPT0 (plst)->last_break;
int data;
data = Ptrace (RPT_PEEKTEXT, plst->pid,
(char *)plst->break_list [idx].ee_loc, 0, NULL);
assert (! IS_BREAK (data));
(char *) plst->break_list[idx].ee_loc, 0, NULL);
assert (!IS_BREAK (data));
Ptrace (RPT_POKETEXT, plst->pid,
(char *)plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
(char *) plst->break_list[idx].ee_loc,
(int) SET_BREAK (data), NULL);
}
}
/* -----------------------------------------------------------------------
TgtCreateNew - add a new process into the process management lists.
----------------------------------------------------------------------- */
/*
* TgtCreateNew - add a new process into the process management lists.
*/
void
TgtCreateNew(PID pid, int conn, INT32 child, char *name, Boolean spawn)
void
TgtCreateNew (PID pid, int conn, INT32 child, char *name, Boolean spawn)
{
int idx;
int idx;
for (idx = 0; idx < pid_list_cnt; idx++)
if (!pid_list[idx].pid)
break; /* find empty */
break; /* find empty */
if (idx >= pid_list_cnt)
{ /* no empties, add more */
PID_LIST *tmp_pid_list = pid_list;
if (idx >= pid_list_cnt) { /* no empties, add more */
PID_LIST *tmp_pid_list = pid_list;
pid_list_cnt += PID_LIST_INC;
pid_list = (PID_LIST*) Realloc(pid_list, /* get new or extend */
pid_list_cnt * sizeof(PID_LIST));
if (!pid_list)
{ /* out of memory */
pid_list = (PID_LIST *) Realloc (pid_list, /* get new or extend */
pid_list_cnt * sizeof (PID_LIST));
if (!pid_list) { /* out of memory */
pid_list_cnt -= PID_LIST_INC;
if (pid_list_cnt)
{ /* realloc failed - malloc again */
pid_list = tmp_pid_list;
/* above relies on old pointer being valid after failed realloc */
if (pid_list_cnt) { /* realloc failed - malloc again */
pid_list = tmp_pid_list;
/*
* above relies on old pointer being valid after failed realloc
*/
}
return; /* failed */
return; /* failed */
}
/* now clear newly added space */
memset(pid_list+pid_list_cnt-PID_LIST_INC, 0,
PID_LIST_INC * sizeof(PID_LIST));
/*
* now clear newly added space
*/
memset (pid_list + pid_list_cnt - PID_LIST_INC, 0,
PID_LIST_INC * sizeof (PID_LIST));
idx = pid_list_cnt - PID_LIST_INC;
}
else /* clear entry we found */
memset(&pid_list[idx], 0, sizeof(PID_LIST));
} else /* clear entry we found */
memset (&pid_list[idx], 0, sizeof (PID_LIST));
/* now fill in empty entry */
/*
* now fill in empty entry
*/
pid_list[idx].pid = pid;
pid_list[idx].running = 1; /* we have not called wait yet */
pid_list[idx].primary_conn = (UCHAR)conn; /* primary owner */
if (conn != -1)
{ /* found caller */
pid_list[idx].running = 1; /* we have not called wait yet */
pid_list[idx].primary_conn = (UCHAR) conn; /* primary owner */
if (conn != -1) { /* found caller */
pid_list[idx].owners = 1;
PIDMAP_SET (conn, idx); /* mask in */
PIDMAP_SET (conn, idx); /* mask in */
}
pid_list[idx].thread = (UINT32)-1; /* no thread for now */
pid_list[idx].last_start = LAST_START; /* handle MiX bug */
pid_list[idx].thread = (UINT32) - 1; /* no thread for now */
pid_list[idx].last_start = LAST_START; /* handle MiX bug */
pid_list[idx].name = name ? (char *)StrDup(name) : (char *)NULL;
pid_list[idx].name = name ? (char *) StrDup (name) : (char *) NULL;
}
/* -----------------------------------------------------------------------
TgtNotifyWaitChange - send event to clients indicating child changed state.
----------------------------------------------------------------------- */
/*
* TgtNotifyWaitChange - send event to clients indicating child changed state.
*/
void
TgtNotifyWaitChange( PID pid, int status, Boolean exclude)
void
TgtNotifyWaitChange (PID pid, int status, Boolean exclude)
{
int conn, idx;
int conn, idx;
idx = FindPidEntry (pid); /* locate the pid that changed */
if (idx < 0)
{
DPRINTF(("TgtNotifyWaitChange: pid %d not in our list\n",
(int) pid));
return; /* not in our list */
idx = FindPidEntry (pid); /* locate the pid that changed */
if (idx < 0) {
DPRINTF (("TgtNotifyWaitChange: pid %d not in our list\n", (int) pid));
return; /* not in our list */
}
pid_list[idx].running = 0; /* not running */
pid_list[idx].state = status; /* save status of stop/term */
if (!pid_list[idx].owners && !STS_SIGNALLED(status))
TgtDelete(&pid_list[idx], -1, 0); /* terminated and no owners */
else
{ /* normal cases */
for (conn = 0; conn < conn_list_cnt; conn++)
{ /* now find all interested clients */
if (!conn_list[conn].in_use /* free entry */
|| ! PIDMAP_TEST (conn, idx))
continue; /* not using this pid */
pid_list[idx].running = 0; /* not running */
pid_list[idx].state = status; /* save status of stop/term */
if (!pid_list[idx].owners && !STS_SIGNALLED (status))
TgtDelete (&pid_list[idx], -1, 0); /* terminated and no owners */
else { /* normal cases */
for (conn = 0; conn < conn_list_cnt; conn++) { /* now find all interested clients */
if (!conn_list[conn].in_use /* free entry */
|| !PIDMAP_TEST (conn, idx))
continue; /* not using this pid */
if (conn == exclude)
continue; /* do not do this one */
TspSendWaitChange(conn, BMSG_WAIT, 1, pid, 0, False);/* notify of change */
continue; /* do not do this one */
TspSendWaitChange (conn, BMSG_WAIT, 1, pid, 0, False); /* notify of change */
}
}
}
/* -----------------------------------------------------------------------
TgtNotifyAll - send a message to all clients interested in process.
----------------------------------------------------------------------- */
/*
* TgtNotifyAll - send a message to all clients interested in process.
*/
void
TgtNotifyAll( int pid_idx, BACK_MSG msg, UINT16 spec,
UINT32 context, int exclude, Boolean force)
void
TgtNotifyAll (int pid_idx, BACK_MSG msg, UINT16 spec,
UINT32 context, int exclude, Boolean force)
{
int conn;
int conn;
DPRINTF(("TgtNotifyAll: msg %d (%s) for pid_idx=%d (%d,%d)\n",
msg, BmsgNames [msg], pid_idx, exclude, force));
DPRINTF (("TgtNotifyAll: msg %d (%s) for pid_idx=%d (%d,%d)\n",
msg, BmsgNames[msg], pid_idx, exclude, force));
for (conn = 0; conn < conn_list_cnt; conn++)
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, pid_idx))
{
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, pid_idx)) {
if (conn != exclude)
TspSendWaitChange(conn, msg, spec, pid_list[pid_idx].pid, context,
force);
TspSendWaitChange (conn, msg, spec, pid_list[pid_idx].pid, context,
force);
}
}
/* -----------------------------------------------------------------------
TgtDelete - mark process as now uncontrolled.
/*
* TgtDelete - mark process as now uncontrolled.
*
* Notes:
* - this function removes a process from the process list.
* - the notify argument indicates a message to send if needed.
*/
Notes:
- this function removes a process from the process list.
- the notify argument indicates a message to send if needed.
----------------------------------------------------------------------- */
void TgtDelete(PID_LIST *plst, int conn_idx, BACK_MSG notify)
void
TgtDelete (PID_LIST * plst, int conn_idx, BACK_MSG notify)
{
int idx = plst - pid_list, cnt, conn;
int idx = plst - pid_list, cnt, conn;
/* found */
/*
* found
*/
cnt = pid_list[idx].owners;
if (cnt)
{ /* some connections to break */
if (cnt) { /* some connections to break */
for (conn = 0; cnt && conn < conn_list_cnt; conn++)
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, idx))
{ /* found one that uses it */
PIDMAP_CLEAR (conn, idx);
if (notify && conn != conn_idx)
TspSendWaitChange(conn, notify, 0, plst->pid, 0, True);
if (!--cnt)
break;
if (conn_list[conn].in_use /* not free */
&& PIDMAP_TEST (conn, idx)) { /* found one that uses it */
PIDMAP_CLEAR (conn, idx);
if (notify && conn != conn_idx)
TspSendWaitChange (conn, notify, 0, plst->pid, 0, True);
if (!--cnt)
break;
}
}
if (pid_list[idx].name)
Free(pid_list[idx].name); /* free string name back */
/* Free breakpoint list */
if (pid_list [idx].break_list != NULL) {
Free (pid_list [idx].break_list);
Free (pid_list[idx].name); /* free string name back */
/*
* Free breakpoint list
*/
if (pid_list[idx].break_list != NULL) {
Free (pid_list[idx].break_list);
}
pid_list[idx].pid = 0; /* gone */
pid_list[idx].pid = 0; /* gone */
}
/*
* TgtKillAndDelete - kill or detach process and remove entry.
*/
/* -----------------------------------------------------------------------
TgtKillAndDelete - kill or detach process and remove entry.
----------------------------------------------------------------------- */
int
TgtKillAndDelete( PID_LIST *plst, struct svc_req *rqstp, Boolean term)
int
TgtKillAndDelete (PID_LIST * plst, struct svc_req *rqstp, Boolean term)
{
ptrace_in pin; /* used for ptrace call */
ptrace_out *pout;
ptrace_in pin; /* used for ptrace call */
ptrace_out *pout;
/* Remove breakpoints */
/*
* Remove breakpoints
*/
if (plst->break_alloc > 0) {
pin.pid = plst->pid;
pin.addr.req = RPT_CLRBREAK;
pin.data = 0; /* clear all */
pin.data = 0; /* clear all */
pin.flags = PTRFLG_NON_OWNER;
pout = RPCGENSRVNAME(ptrace_2_svc) (&pin, rqstp);
pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp);
if (pout->result < 0) {
DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n",
getErrno()));
DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n", getErrno ()));
return -1;
}
}
if (term)
{ /* kill */
if (term) { /* kill */
pin.addr.ptrace_addr_data_in_u.address = 0;
pin.data = -1; /* Don't want notification from slave */
pin.data = -1; /* Don't want notification from slave */
pin.addr.req = RPT_KILL;
}
else
{ /* detach */
} else { /* detach */
pin.addr.ptrace_addr_data_in_u.address = 1;
pin.data = 0;
pin.addr.req = RPT_DETACH;
@@ -254,26 +258,24 @@ TgtKillAndDelete( PID_LIST *plst, struct svc_req *rqstp, Boolean term)
pin.flags = PTRFLG_FREE | PTRFLG_NON_OWNER;
DPRINTF (("TgtKillAndDelete: ptrace_2_svc (%s (%d), %d)\n",
PtraceName (pin.addr.req), pin.addr.req, pin.pid));
PtraceName (pin.addr.req), pin.addr.req, pin.pid));
pout = RPCGENSRVNAME(ptrace_2_svc) (&pin, rqstp);/* start it */
pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp); /* start it */
if (pout->errNo == ESRCH && plst->pid)
TgtDelete(plst, -1, BMSG_KILLED); /* only entry remains */
TgtDelete (plst, -1, BMSG_KILLED); /* only entry remains */
return 0;
}
/* -----------------------------------------------------------------------
TgtDetachCon - detach a connection's ownership of a process.
----------------------------------------------------------------------- */
/*
* TgtDetachCon - detach a connection's ownership of a process.
*/
void
TgtDetachCon( int conn_idx, int pid_idx, Boolean delete)
void
TgtDetachCon (int conn_idx, int pid_idx, Boolean delete)
{
if ((unsigned) pid_idx >= pid_list_cnt
|| !pid_list[pid_idx].pid)
return; /* not valid */
if (PIDMAP_TEST (conn_idx, pid_idx))
{ /* if an owner, release control */
if ((unsigned) pid_idx >= pid_list_cnt || !pid_list[pid_idx].pid)
return; /* not valid */
if (PIDMAP_TEST (conn_idx, pid_idx)) { /* if an owner, release control */
PIDMAP_CLEAR (conn_idx, pid_idx);
if (pid_list[pid_idx].owners)
@@ -281,9 +283,8 @@ TgtDetachCon( int conn_idx, int pid_idx, Boolean delete)
if (pid_list[pid_idx].primary_conn == conn_idx)
pid_list[pid_idx].primary_conn = NO_PRIMARY;
if (delete
&& !pid_list[pid_idx].owners
&& PROC_TERMINATED (pid_list + pid_idx))
TgtDelete(&pid_list[pid_idx], -1, 0); /* remove entry */
&& !pid_list[pid_idx].owners && PROC_TERMINATED (pid_list + pid_idx))
TgtDelete (&pid_list[pid_idx], -1, 0); /* remove entry */
}
}
@@ -293,231 +294,254 @@ TgtDetachCon( int conn_idx, int pid_idx, Boolean delete)
----------------------------------------------------------------------- */
#ifdef DDEBUG
static char* LastStartNames[] = {
static char *LastStartNames[] = {
"NONE", "STEP", "CONT", "RANGE",
"STEPOFF", "KILLED", "DETACHED"
};
char* GetLastStartName (int last_start)
char *
GetLastStartName (int last_start)
{
static char buf [32];
static char buf[32];
strcpy (buf, LastStartNames [last_start & ~LAST_START]);
if (last_start & LAST_START) {
strcat (buf, "+START");
}
return buf;
strcpy (buf, LastStartNames[last_start & ~LAST_START]);
if (last_start & LAST_START) {
strcat (buf, "+START");
}
return buf;
}
#endif
Boolean TgtHandleChildChange(PID pid, int* status, int *unexp,
CPU_Exception_frame* ctx)
{ /* return False if continue, else stop */
int idx, sig;
int bidx = 0;
PID_LIST *plst;
unsigned long PC;
BASE_BREAK *base = NULL; /* break_list[0] is really BASE_BREAK */
int hadStepEmul;
int origHadStepEmul;
int stopWanted;
Boolean
TgtHandleChildChange (PID pid, int *status, int *unexp,
CPU_Exception_frame * ctx)
{ /* return False if continue, else stop */
int idx, sig;
int bidx = 0;
PID_LIST *plst;
unsigned long PC;
BASE_BREAK *base = NULL; /* break_list[0] is really BASE_BREAK */
int hadStepEmul;
int origHadStepEmul;
int stopWanted;
DPRINTF (("TgtHandleChildChange: pid %d status %x cap\n",
(int) pid, *status));
(int) pid, *status));
if (unexp)
*unexp = 0; /* initialize to ok */
*unexp = 0; /* initialize to ok */
/* first, find pid in question */
/*
* first, find pid in question
*/
idx = FindPidEntry (pid);
if (idx < 0)
{ /* cannot locate this process */
if (idx < 0) { /* cannot locate this process */
DPRINTF (("TgtHandleChildChange: unknown process (%s pid)\n",
FindPidEntry (pid) >= 0 ? "stale" : "unknown"));
FindPidEntry (pid) >= 0 ? "stale" : "unknown"));
if (unexp)
*unexp = 1; /* Unexpected change */
return(False); /* unknown: ignore (used to stop and notify) */
*unexp = 1; /* Unexpected change */
return (False); /* unknown: ignore (used to stop and notify) */
}
/* found */
plst = &pid_list[idx]; /* pointer to entry */
/* first we see if just stopped */
/*
* found
*/
plst = &pid_list[idx]; /* pointer to entry */
/*
* first we see if just stopped
*/
/* copy ctxt */
CtxToRegs(ctx, &(plst->regs));
/*
* copy ctxt
*/
CtxToRegs (ctx, &(plst->regs));
stopWanted = plst->stop_wanted;
plst->stop_wanted = 0; /* For the next time */
plst->stop_wanted = 0; /* For the next time */
hadStepEmul = BreakClear (plst, -1, -1) > 0;
origHadStepEmul = hadStepEmul; /* hadStepEmul is cleared if real bkpt met */
origHadStepEmul = hadStepEmul; /* hadStepEmul is cleared if real bkpt met */
if (STS_SIGNALLED (*status))
{ /* stopped, not terminated */
sig = STS_GETSIG (*status); /* signal that stopped us */
if (STS_SIGNALLED (*status)) { /* stopped, not terminated */
sig = STS_GETSIG (*status); /* signal that stopped us */
/* now, we read the registers and see what to do next */
if (TgtPtrace(RPT_GETREGS, pid, (void *)&plst->regs, 0, NULL) < 0) {
memset (&plst->regs, 0, sizeof plst->regs);
/*
* now, we read the registers and see what to do next
*/
if (TgtPtrace (RPT_GETREGS, pid, (void *) &plst->regs, 0, NULL) < 0) {
memset (&plst->regs, 0, sizeof (plst->regs));
}
/* Get current thread */
plst->thread = TgtPtrace(RPT_GETTARGETTHREAD, pid, NULL, 0, NULL);
/*
* Get current thread
*/
plst->thread = TgtPtrace (RPT_GETTARGETTHREAD, pid, NULL, 0, NULL);
if (sig == SIGTRAP)
{ /* stopped from break/step */
if (sig == SIGTRAP) { /* stopped from break/step */
PC = plst->regs.REG_PC;
/* Must check PC to see whether in situations where we had
step emulation we are on a breakpoint or just
have returned from an emulated single-step */
if (BreakIdentify (plst, 0 /*no adjust*/, -1 /*no thread*/) > 0) {
hadStepEmul = 0;
/*
* Must check PC to see whether in situations where we had
* step emulation we are on a breakpoint or just
* have returned from an emulated single-step
*/
if (BreakIdentify (plst, 0 /*no adjust */ , -1 /*no thread */ ) > 0) {
hadStepEmul = 0;
}
plst->is_step = hadStepEmul || IS_STEP(plst->regs)
|| plst->last_start == LAST_START;
plst->is_step = hadStepEmul || IS_STEP (plst->regs)
|| plst->last_start == LAST_START;
DPRINTF (("TgtHandleChildChange: %s last_start %s\n", plst->is_step
? "step": "break", GetLastStartName (plst->last_start)));
? "step" : "break", GetLastStartName (plst->last_start)));
if ((plst->is_step || origHadStepEmul || stopWanted)
&& (plst->last_start == LAST_STEP
|| plst->last_start == LAST_STEPOFF
|| plst->last_start == LAST_RANGE))
{
DPRINTF (("TgtHandleChildChange: restoring stepped-off bkpt\n"));
BreakSteppedOff (plst);
&& (plst->last_start == LAST_STEP
|| plst->last_start == LAST_STEPOFF
|| plst->last_start == LAST_RANGE)) {
DPRINTF (("TgtHandleChildChange: restoring stepped-off bkpt\n"));
BreakSteppedOff (plst);
}
if (plst->last_start == LAST_STEPOFF && (plst->is_step||origHadStepEmul))
{ /* stepped off break and now need cont */
DPRINTF (("TgtHandleChildChange: auto-resuming after step-off\n"));
plst->last_start = LAST_CONT; /* convert to normal cont */
if (!stopWanted) {
if (TgtPtrace(RPT_CONT, pid, (char *)1, 0, NULL))
return True; /* tell people */
return(False); /* wait for change */
}
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-off\n",
stopWanted));
*status = STS_MAKESIG (stopWanted);
return True; /* Stop and notify */
if (plst->last_start == LAST_STEPOFF && (plst->is_step || origHadStepEmul)) { /* stepped off break and now need cont */
DPRINTF (("TgtHandleChildChange: auto-resuming after step-off\n"));
plst->last_start = LAST_CONT; /* convert to normal cont */
if (!stopWanted) {
if (TgtPtrace (RPT_CONT, pid, (char *) 1, 0, NULL))
return True; /* tell people */
return (False); /* wait for change */
}
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-off\n",
stopWanted));
*status = STS_MAKESIG (stopWanted);
return True; /* Stop and notify */
}
base = plst->break_list ? ((BASE_BREAK*)plst->break_list) :
((BASE_BREAK*)NULL);
/* now see if step in range */
base = plst->break_list ? ((BASE_BREAK *) plst->break_list) :
((BASE_BREAK *) NULL);
/*
* now see if step in range
*/
if (plst->last_start == LAST_RANGE /* step in range */
&& (plst->is_step || origHadStepEmul) /* not a breakpoint */
&& PC >= base->range_start
&& PC <= base->range_end)
{ /* still in range, keep going */
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-range\n",
stopWanted));
} else {
DPRINTF (("TgtHandleChildChange: Reservation at %x\n",
plst->regs.REG_PC));
}
if (plst->last_start == LAST_RANGE /* step in range */
&& (plst->is_step || origHadStepEmul) /* not a breakpoint */
&&PC >= base->range_start && PC <= base->range_end) { /* still in range, keep going */
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-range\n",
stopWanted));
} else {
DPRINTF (("TgtHandleChildChange: Reservation at %x\n",
plst->regs.REG_PC));
}
}
if (!plst->is_step) /* was break */
{
bidx = BreakIdentify (plst, 1 /*adjust*/, plst->thread);
if (bidx == 0) {
DPRINTF (("TgtHandleChildChange: forwarding bkpt to kernel\n"));
if (unexp) {
*unexp = 1;
}
return False;
}
if (bidx < 0) { /* Unwanted breakpoint, must step it off */
ptrace_in pin;
ptrace_out* out;
if (origHadStepEmul)
{
DPRINTF (("TgtHandleChildChange: bkpt %x becomes step\n",
plst->regs.REG_PC));
bidx = -bidx;
plst->is_step = 1;
base->clr_step = plst->break_list [bidx].type == BRKT_INSTR;
base->last_break = bidx;
return True;
}
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d at bkpt %x\n",
stopWanted, plst->regs.REG_PC));
/* The PC has already been adjusted by BreakIdentify */
*status = STS_MAKESIG (stopWanted);
return True;
}
/* All the handling is done in ptrace_2_svc() so call it */
bidx = -bidx;
DPRINTF (("TgtHandleChildChange: last %d (%s) restarting bkpt %d\n",
plst->last_start, GetLastStartName (plst->last_start), bidx));
base->clr_step = 1;
base->last_break = bidx; /* remember which one */
plst->running = 0; /* So that ptrace is accepted */
pin.pid = plst->pid;
if (!plst->is_step) { /* was break */
bidx = BreakIdentify (plst, 1 /*adjust */ , plst->thread);
if (bidx == 0) {
DPRINTF (("TgtHandleChildChange: forwarding bkpt to kernel\n"));
if (unexp) {
*unexp = 1;
}
return False;
}
if (bidx < 0) { /* Unwanted breakpoint, must step it off */
ptrace_in pin;
ptrace_out *out;
if (origHadStepEmul) {
DPRINTF (("TgtHandleChildChange: bkpt %x becomes step\n",
plst->regs.REG_PC));
bidx = -bidx;
plst->is_step = 1;
base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;
base->last_break = bidx;
return True;
}
if (stopWanted) {
DPRINTF (("TgtHandleChildChange: stop_wanted %d at bkpt %x\n",
stopWanted, plst->regs.REG_PC));
/*
* The PC has already been adjusted by BreakIdentify
*/
*status = STS_MAKESIG (stopWanted);
return True;
}
/*
* All the handling is done in ptrace_2_svc() so call it
*/
bidx = -bidx;
DPRINTF (("TgtHandleChildChange: last %d (%s) restarting bkpt %d\n",
plst->last_start, GetLastStartName (plst->last_start),
bidx));
base->clr_step = 1;
base->last_break = bidx; /* remember which one */
plst->running = 0; /* So that ptrace is accepted */
pin.pid = plst->pid;
if (plst->last_start == LAST_STEP) {
pin.addr.req = RPT_SINGLESTEP;
} else {
pin.addr.req = RPT_CONT;
}
pin.addr.ptrace_addr_data_in_u.address = 1;
pin.data = 0;
pin.flags = PTRFLG_NON_OWNER;
out = RPCGENSRVNAME(ptrace_2_svc) (&pin, NULL);
if (out->result == 0) return False; /* Continue waiting */
DPRINTF(("TgtHandleChildChange: failed to restart bkpt!\n"));
/* If something went wrong, just stop on breakpoint */
}
if (plst->last_start == LAST_STEP) {
pin.addr.req = RPT_SINGLESTEP;
} else {
pin.addr.req = RPT_CONT;
}
pin.addr.ptrace_addr_data_in_u.address = 1;
pin.data = 0;
pin.flags = PTRFLG_NON_OWNER;
out = RPCGENSRVNAME (ptrace_2_svc) (&pin, NULL);
if (out->result == 0)
return False; /* Continue waiting */
DPRINTF (("TgtHandleChildChange: failed to restart bkpt!\n"));
/*
* If something went wrong, just stop on breakpoint
*/
}
}
} /* else sig != SIGTRAP */
/* finally, fill in stop info in break point array base */
if (bidx > 0)
{ /* store break info */
/* will need to get off the break for SW breakpoints only */
base->clr_step = plst->break_list [bidx].type == BRKT_INSTR;
base->last_break = bidx; /* remember which one */
}
else if (base)
{ /* clear break info */
base->clr_step = False; /* not stopped on break */
/*
* else sig != SIGTRAP
*/
/*
* finally, fill in stop info in break point array base
*/
if (bidx > 0) { /* store break info */
/*
* will need to get off the break for SW breakpoints only
*/
base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;
base->last_break = bidx; /* remember which one */
} else if (base) { /* clear break info */
base->clr_step = False; /* not stopped on break */
base->last_break = 0;
}
/* decision to notify owner based on last_start */
} /* stopped */
else /* terminated */
{
if (plst->last_start == LAST_START)
{ /* spawn failed */
TgtNotifyAll(idx, BMSG_EXEC_FAIL, 0, 0, -1, True);
plst->running = False; /* not running - dead */
plst->state = *status; /* contains errno in high word */
return(False);
/*
* decision to notify owner based on last_start
*/
} /* stopped */
else { /* terminated */
if (plst->last_start == LAST_START) { /* spawn failed */
TgtNotifyAll (idx, BMSG_EXEC_FAIL, 0, 0, -1, True);
plst->running = False; /* not running - dead */
plst->state = *status; /* contains errno in high word */
return (False);
}
else if ((UCHAR)(plst->last_start & ~LAST_START) < (UCHAR)LAST_KILLED)
else if ((UCHAR) (plst->last_start & ~LAST_START) < (UCHAR) LAST_KILLED)
plst->last_start = LAST_NONE; /* doesn't matter anymore */
else
return(False); /* killed and detach already notified */
return (False); /* killed and detach already notified */
}
return(True); /* stop and notify */
return (True); /* stop and notify */
}
#ifdef DDEBUG
/* -----------------------------------------------------------------------
TgtDbgPtrace - debug version of ptrace.
----------------------------------------------------------------------- */
/*
* TgtDbgPtrace - debug version of ptrace.
*/
int TgtDbgPtrace(int request, PID pid, char *addr, int data, void *addr2)
int
TgtDbgPtrace (int request, PID pid, char *addr, int data, void *addr2)
{
int diag;
int diag;
DPRINTF (("TgtDbgPtrace: entered (%s (%d), %d, %x, %d, %x)\n",
PtraceName (request), request, pid, (int) addr, data,
(int) addr2));
PtraceName (request), request, pid, (int) addr, data,
(int) addr2));
if (request == RPT_WRITETEXT || request == RPT_WRITEDATA) {
int i;
@@ -525,7 +549,7 @@ int TgtDbgPtrace(int request, PID pid, char *addr, int data, void *addr2)
DPRINTF (("TgtDbgPtrace:"));
if (rdb_debug) {
for (i = 0; i < data && i < 16; ++i) {
printf (" %02x", ((char*) addr2) [i] & 0xFF);
printf (" %02x", ((char *) addr2)[i] & 0xFF);
}
printf ("\n");
}
@@ -534,19 +558,19 @@ int TgtDbgPtrace(int request, PID pid, char *addr, int data, void *addr2)
diag = TgtRealPtrace (request, pid, addr, data, addr2);
DPRINTF (("TgtDbgPtrace: returned %d (%x) errno %d\n",
diag, diag, getErrno()));
diag, diag, getErrno ()));
if (request == RPT_GETREGS || request == RPT_GETTHREADREGS
|| request == RPT_SETREGS || request == RPT_SETTHREADREGS)
{
/* Use DPRINTF() so as to have the id prefix */
|| request == RPT_SETREGS || request == RPT_SETTHREADREGS) {
/*
* Use DPRINTF() so as to have the id prefix
*/
DPRINTF (("TgtDbgPtrace: (%s) PC = %x, SP = %x, FP = %x\n",
PtraceName (request),
((xdr_regs*)addr)->REG_PC,
((xdr_regs*)addr)->REG_SP,
((xdr_regs*)addr)->REG_FP));
PtraceName (request),
((xdr_regs *) addr)->REG_PC,
((xdr_regs *) addr)->REG_SP, ((xdr_regs *) addr)->REG_FP));
}
return(diag);
return (diag);
}
#endif /* DDEBUG */
#endif /* DDEBUG */

View File

@@ -12,50 +12,52 @@
*/
#include <sys/errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
#include <signal.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <netinet/in.h>
#include <sys/socket.h>
static int out_sock;
static int warm_test;
static int out_sock;
static int warm_test;
static void TimeTestHandler();
static void TimeTestHandler ();
/*
* TspInit - Initialize the transport system.
*
*/
void
void
TspInit (int id)
{
struct sigaction sa;
struct sigaction sa;
struct sockaddr_in addr;
/* setup a socket to send event messages back through */
out_sock = socket (PF_INET, SOCK_DGRAM, 0);
if (out_sock < 0) {
DPRINTF (("TspInit: socket() failed %d errno %d\n",
out_sock, getErrno()));
return; /* failed to open socket, let caller deal with */
}
{
struct sockaddr_in addr;
/*
* setup a socket to send event messages back through
*/
out_sock = socket (PF_INET, SOCK_DGRAM, 0);
if (out_sock < 0) {
DPRINTF (("TspInit: socket() failed %d errno %d\n",
out_sock, getErrno ()));
return; /* failed to open socket, let caller deal with */
}
bzero ((void *)(&addr), sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = htons (BackPort);
if (bind (out_sock, (struct sockaddr*) &addr, sizeof addr) < 0) {
DPRINTF (("TspInit: bind() failed\n"));
}
}
/* setup alarm timer for warm testing */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = TimeTestHandler;
sigaction (SIGALRM, &sa, 0);
bzero ((void *) (&addr), sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_port = htons (BackPort);
if (bind (out_sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
DPRINTF (("TspInit: bind() failed\n"));
}
/*
* setup alarm timer for warm testing
*/
memset (&sa, 0, sizeof (sa));
sa.sa_handler = TimeTestHandler;
sigaction (SIGALRM, &sa, 0);
}
/*
@@ -67,38 +69,43 @@ TspInit (int id)
* on each call.
*/
Boolean
TspTranslateRpcAddr (struct svc_req* rqstp, NET_OPAQUE* opaque)
Boolean
TspTranslateRpcAddr (struct svc_req *rqstp, NET_OPAQUE * opaque)
{
struct sockaddr_in* addr; /* used as template to extract net info */
unsigned char* up;
struct sockaddr_in *addr; /* used as template to extract net info */
unsigned char *up;
memset (opaque, 0, sizeof (NET_OPAQUE));
/*
* We interpret the remote address as a standard netbuf name.
* The format is 2 bytes of address family (normally AF_INET)
* and then a length (5) and then the IP address.
*/
if (rqstp->rq_xprt->xp_addrlen != 16)
{
DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
setErrno (EPROTONOSUPPORT);
return False; /* invalid, so fails */
}
/* addr = &rqstp->rq_xprt->xp_raddr; */
addr = svc_getcaller (rqstp->rq_xprt);
/* verify it is AF_INET */
if (addr->sin_family != AF_INET) { /* no, error */
DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
setErrno (EAFNOSUPPORT);/* invalid addr family */
return False;
}
/* good address type */
up = (unsigned char *) &addr->sin_addr.s_addr;
DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
up[0], up[1], up[2], up[3], htons (addr->sin_port)));
memcpy (opaque, addr, sizeof (struct sockaddr_in));
return True;
memset (opaque, 0, sizeof (NET_OPAQUE));
/*
* We interpret the remote address as a standard netbuf name.
* The format is 2 bytes of address family (normally AF_INET)
* and then a length (5) and then the IP address.
*/
if (rqstp->rq_xprt->xp_addrlen != 16) {
DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
setErrno (EPROTONOSUPPORT);
return False; /* invalid, so fails */
}
/*
* addr = &rqstp->rq_xprt->xp_raddr;
*/
addr = svc_getcaller (rqstp->rq_xprt);
/*
* verify it is AF_INET
*/
if (addr->sin_family != AF_INET) { /* no, error */
DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
setErrno (EAFNOSUPPORT); /* invalid addr family */
return False;
}
/*
* good address type
*/
up = (unsigned char *) &addr->sin_addr.s_addr;
DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
up[0], up[1], up[2], up[3], htons (addr->sin_port)));
memcpy (opaque, addr, sizeof (struct sockaddr_in));
return True;
}
/*
@@ -108,22 +115,26 @@ TspTranslateRpcAddr (struct svc_req* rqstp, NET_OPAQUE* opaque)
* expected.
*/
Boolean
TspValidateAddr (NET_OPAQUE* opaque, NET_OPAQUE* sender)
Boolean
TspValidateAddr (NET_OPAQUE * opaque, NET_OPAQUE * sender)
{
struct sockaddr_in* addr; /* used as template to extract net info */
struct sockaddr_in *addr; /* used as template to extract net info */
addr = (struct sockaddr_in*) opaque;
/* Verify it is AF_INET. Should check against sender IP address too */
if (addr->sin_family != AF_INET) {
DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
htons (addr->sin_port)));
return False; /* not valid */
}
/* otherwise, we copy in the IP address, since client may not know it */
addr->sin_addr.s_addr = ((struct sockaddr_in*) sender)->sin_addr.s_addr;
DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
return True;
addr = (struct sockaddr_in *) opaque;
/*
* Verify it is AF_INET. Should check against sender IP address too
*/
if (addr->sin_family != AF_INET) {
DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
htons (addr->sin_port)));
return False; /* not valid */
}
/*
* otherwise, we copy in the IP address, since client may not know it
*/
addr->sin_addr.s_addr = ((struct sockaddr_in *) sender)->sin_addr.s_addr;
DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
return True;
}
/*
@@ -133,118 +144,123 @@ TspValidateAddr (NET_OPAQUE* opaque, NET_OPAQUE* sender)
* connection index in our connection array.
*/
int
TspConnGetIndex (struct svc_req* rqstp)
int
TspConnGetIndex (struct svc_req *rqstp)
{
int conn;
/* &rqstp->rq_xprt->xp_raddr; */
struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
int conn;
/*
* &rqstp->rq_xprt->xp_raddr;
*/
struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
for (conn = 0; conn < conn_list_cnt; conn++) {
if (!conn_list[conn].in_use)
continue; /* not used */
for (conn = 0; conn < conn_list_cnt; conn++) {
if (!conn_list[conn].in_use)
continue; /* not used */
if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
&conn_list [conn].sender)->sin_addr.s_addr
&& addr->sin_port == ((struct sockaddr_in *)
&conn_list[conn].sender)->sin_port) {
return conn;
}
if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
&conn_list[conn].sender)->sin_addr.s_addr
&& addr->sin_port == ((struct sockaddr_in *)
&conn_list[conn].sender)->sin_port) {
return conn;
}
return -1;
}
return -1;
}
/*
* TspSendWaitChange - send wait-change message to clients to
* notify change.
*/
void
TspSendWaitChange(
int conn, /* connection to send to */
BACK_MSG msg, /* BMSG type */
UINT16 spec, /* special information */
PID pid, /* pid it refers to */
UINT32 context, /* additional context for message */
Boolean force) /* force into being only message */
{
int idx;
struct SEND_LIST* snd_ptr;
void
TspSendWaitChange (int conn, /* connection to send to */
BACK_MSG msg, /* BMSG type */
UINT16 spec, /* special information */
PID pid, /* pid it refers to */
UINT32 context, /* additional context for message */
Boolean force) /* force into being only message */
{
int idx;
struct SEND_LIST *snd_ptr;
if (force) {
/* force to top, which means others gone */
idx = 0;
conn_list [conn].send_idx = 1;
conn_list[conn].retry = 0;
} else {
for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
if (conn_list[conn].send_list[idx].send_type == msg
&& conn_list[conn].send_list[idx].pid == pid)
return; /* already pended for this pid */
}
idx = conn_list[conn].send_idx;
if (idx+1 > MAX_SEND)
return; /* we lose it, what should we do??? */
conn_list[conn].send_idx++;
if (force) {
/*
* force to top, which means others gone
*/
idx = 0;
conn_list[conn].send_idx = 1;
conn_list[conn].retry = 0;
} else {
for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
if (conn_list[conn].send_list[idx].send_type == msg
&& conn_list[conn].send_list[idx].pid == pid)
return; /* already pended for this pid */
}
snd_ptr = &conn_list[conn].send_list[idx];
snd_ptr->send_type = msg; /* message to send */
snd_ptr->retry = TSP_RETRIES; /* about 1 minute of retries */
snd_ptr->spec = htons ((u_short) spec);
snd_ptr->pid = htonl (pid);
snd_ptr->context = htonl (context);
TspSendMessage (conn, False); /* now do the send */
idx = conn_list[conn].send_idx;
if (idx + 1 > MAX_SEND)
return; /* we lose it, what should we do??? */
conn_list[conn].send_idx++;
}
snd_ptr = &conn_list[conn].send_list[idx];
snd_ptr->send_type = msg; /* message to send */
snd_ptr->retry = TSP_RETRIES; /* about 1 minute of retries */
snd_ptr->spec = htons ((u_short) spec);
snd_ptr->pid = htonl (pid);
snd_ptr->context = htonl (context);
TspSendMessage (conn, False); /* now do the send */
}
/*
* TspSendMessage - send message at top of send list for connection.
*/
void
TspSendMessage( int conn, Boolean resend)
void
TspSendMessage (int conn, Boolean resend)
{
struct sockaddr_in addr;
struct UDP_MSG msg;
int cnt;
struct sockaddr_in addr;
struct UDP_MSG msg;
int cnt;
if (!resend && conn_list[conn].retry)
return; /* already waiting for reply */
if (!resend && conn_list[conn].retry)
return; /* already waiting for reply */
/*
* Note on above: if no back port we can't remove unless
* someone blows off.
*/
if (!resend) {
/* first time, setup. Set retry count: */
conn_list[conn].retry = conn_list[conn].send_list[0].retry;
conn_list[conn].last_msg_num++; /* new sequence number */
if (!warm_test++) { /* starting, so enable timer */
alarm (2); /* resend every 2 seconds as needed */
}
/*
* Note on above: if no back port we can't remove unless
* someone blows off.
*/
if (!resend) {
/*
* first time, setup. Set retry count:
*/
conn_list[conn].retry = conn_list[conn].send_list[0].retry;
conn_list[conn].last_msg_num++; /* new sequence number */
if (!warm_test++) { /* starting, so enable timer */
alarm (2); /* resend every 2 seconds as needed */
}
}
msg.type = conn_list[conn].send_list[0].send_type;
msg.msg_num = conn_list[conn].last_msg_num;
msg.spec = conn_list[conn].send_list[0].spec;
msg.pid = conn_list[conn].send_list[0].pid;
msg.context = conn_list[conn].send_list[0].context;
msg.type = conn_list[conn].send_list[0].send_type;
msg.msg_num = conn_list[conn].last_msg_num;
msg.spec = conn_list[conn].send_list[0].spec;
msg.pid = conn_list[conn].send_list[0].pid;
msg.context = conn_list[conn].send_list[0].context;
memset (&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_port;
addr.sin_addr.s_addr =
((struct sockaddr_in*)&conn_list[conn].back_port)->sin_addr.s_addr;
memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_port =
((struct sockaddr_in *) &conn_list[conn].back_port)->sin_port;
addr.sin_addr.s_addr =
((struct sockaddr_in *) &conn_list[conn].back_port)->sin_addr.s_addr;
DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
msg.type, BmsgNames [msg.type], HL_W (addr.sin_port)));
DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
msg.type, BmsgNames[msg.type], HL_W (addr.sin_port)));
cnt = sendto (out_sock, &msg, sizeof msg, 0, (struct sockaddr*) &addr,
sizeof addr);
if (cnt != sizeof msg) { /* failed on send */
printf ("%s: Failed to send msg %d to conn %d (%d vs. %d)\n",
ActName, msg.type, conn, cnt, sizeof msg);
}
cnt = sendto (out_sock, &msg, sizeof (msg), 0, (struct sockaddr *) &addr,
sizeof (addr));
if (cnt != sizeof (msg)) { /* failed on send */
printf ("%s: Failed to send msg %d to conn %d (%d vs. %d)\n",
taskName, msg.type, conn, cnt, sizeof (msg));
}
}
/*
@@ -255,26 +271,29 @@ TspSendMessage( int conn, Boolean resend)
* next (from ack).
*/
void
void
TspMessageReceive (int conn, PID pid)
{
/* We remove the send list entry and use next if any */
conn_list[conn].retry = 0; /* reset */
if (!warm_test || !--warm_test) {
alarm (0); /* reset timer if not used */
}
/*
* We remove the send list entry and use next if any
*/
conn_list[conn].retry = 0; /* reset */
if (!warm_test || !--warm_test) {
alarm (0); /* reset timer if not used */
}
#ifdef DDEBUG
if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
}
if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
}
#endif
/* Move up by one if needed */
if (!--conn_list[conn].send_idx)
return; /* no more to do */
/*
* Move up by one if needed
*/
if (!--conn_list[conn].send_idx)
return; /* no more to do */
memcpy (conn_list[conn].send_list, conn_list[conn].send_list+1,
conn_list[conn].send_idx * sizeof(struct SEND_LIST)); /* copy down */
TspSendMessage (conn, 0);
memcpy (conn_list[conn].send_list, conn_list[conn].send_list + 1, conn_list[conn].send_idx * sizeof (struct SEND_LIST)); /* copy down */
TspSendMessage (conn, 0);
}
/*
@@ -284,48 +303,53 @@ TspMessageReceive (int conn, PID pid)
* number of unknown.
*/
char*
char *
TspGetHostName (conn_idx)
int conn_idx; /* client connection number */
int conn_idx; /* client connection number */
{
static char buff [30]; /* largest net num */
unsigned char* cp;
static char buff[30]; /* largest net num */
unsigned char *cp;
cp = conn_list[conn_idx].sender.c+4;
sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
return buff;
cp = conn_list[conn_idx].sender.c + 4;
sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
return buff;
}
/*
* TimeTestHandler - alarm timer handler to resend warm/wait test.
*/
static void
TimeTestHandler()
static void
TimeTestHandler ()
{
int conn;
int conn;
if (!warm_test)
return; /* no longer enabled */
if (!warm_test)
return; /* no longer enabled */
for (conn = 0; conn < conn_list_cnt; conn++) {
/* locate all that are using this */
if (!conn_list[conn].in_use)
continue; /* not used */
for (conn = 0; conn < conn_list_cnt; conn++) {
/*
* locate all that are using this
*/
if (!conn_list[conn].in_use)
continue; /* not used */
if (!conn_list[conn].retry) continue;
/* found one that we are testing */
if (!--conn_list[conn].retry) {
/*
* Counted down the retries: blow off.
* Need to have connection flag to indicate not blowing
* off for cases where client is stopped due to being
* debugged.
*/
ConnDelete (conn, NULL, CLOSE_IGNORE);
continue;
}
TspSendMessage (conn, True); /* send another message */
if (!conn_list[conn].retry)
continue;
/*
* found one that we are testing
*/
if (!--conn_list[conn].retry) {
/*
* Counted down the retries: blow off.
* Need to have connection flag to indicate not blowing
* off for cases where client is stopped due to being
* debugged.
*/
ConnDelete (conn, NULL, CLOSE_IGNORE);
continue;
}
alarm (2); /* setup for 2 seconds from now */
TspSendMessage (conn, True); /* send another message */
}
alarm (2); /* setup for 2 seconds from now */
}

View File

@@ -25,30 +25,32 @@
* list. The fields list, list_sz and list_alloc are affected.
*/
Boolean
ListAlloc(buff, clst)
Boolean
ListAlloc (buff, clst)
char *buff;
CONN_LIST *clst; /* place to copy it */
CONN_LIST *clst; /* place to copy it */
{
int tmp;
char* name;
int new_len;
int len;
int tmp;
char *name;
int new_len;
int len;
tmp = strlen(buff);
new_len = (int)clst->list_sz + 1 + tmp;
if (clst->list_alloc < (unsigned)new_len) {
/* need more space */
name = (char *)Realloc(clst->list, len = new_len + MAX_FILENAME);
if (name == NULL) {
return(False); /* failed, no space */
}
clst->list_alloc = len;
clst->list = name;
tmp = strlen (buff);
new_len = (int) clst->list_sz + 1 + tmp;
if (clst->list_alloc < (unsigned) new_len) {
/*
* need more space
*/
name = (char *) Realloc (clst->list, len = new_len + MAX_FILENAME);
if (name == NULL) {
return (False); /* failed, no space */
}
strcpy(clst->list + clst->list_sz, buff);
clst->list_sz += tmp;
return(True);
clst->list_alloc = len;
clst->list = name;
}
strcpy (clst->list + clst->list_sz, buff);
clst->list_sz += tmp;
return (True);
}
/*----- Management of processes -----*/
@@ -57,21 +59,22 @@ ListAlloc(buff, clst)
* FindPidEntry - locate pid_list entry from pid
*/
int
FindPidEntry (pid)
int pid; /* process identifier */
int
FindPidEntry (int pid) /* pid = process identifier */
{
int idx;
int idx;
/* pid 0 is invalid, and signals a free slot */
if (pid_list == NULL || pid == 0) {
return -1;
}
for (idx = 0; idx < pid_list_cnt; idx++) {
if (pid_list [idx].pid == pid )
return idx;
}
/*
* pid 0 is invalid, and signals a free slot
*/
if (pid_list == NULL || pid == 0) {
return -1;
}
for (idx = 0; idx < pid_list_cnt; idx++) {
if (pid_list[idx].pid == pid)
return idx;
}
return -1;
}
/*----- Debug suport -----*/
@@ -82,51 +85,51 @@ FindPidEntry (pid)
* Names of debug primitives
*/
const char* PtraceNames [] = {
const char *PtraceNames[] = {
"RPT_TRACEME", "RPT_PEEKTEXT", "RPT_PEEKDATA", "RPT_PEEKUSER",
"RPT_POKETEXT", "RPT_POKEDATA", "RPT_POKEUSER", "RPT_CONT",
"RPT_KILL", "RPT_SINGLESTEP", "RPT_ATTACH", "RPT_DETACH",
"RPT_GETREGS", "RPT_SETREGS", "RPT_GETFPREGS", "RPT_SETFPREGS",
"RPT_READDATA", "RPT_WRITEDATA", "RPT_READTEXT", "RPT_WRITETEXT",
"RPT_GETFPAREGS", "RPT_SETFPAREGS", "RPT_22", "RPT_23",
"RPT_SYSCALL", "RPT_DUMPCORE", "RPT_26", "RPT_27",
"RPT_28", "RPT_GETUCODE", "RPT_30", "RPT_31",
"RPT_32", "RPT_33", "RPT_34", "RPT_35",
"RPT_36", "RPT_37", "RPT_38", "RPT_39",
"RPT_40", "RPT_41", "RPT_42", "RPT_43",
"RPT_44", "RPT_45", "RPT_46", "RPT_47",
"RPT_48", "RPT_49", "RPT_GETTARGETTHREAD", "RPT_SETTARGETTHREAD",
"RPT_THREADSUSPEND", "RPT_THREADRESUME", "RPT_THREADLIST", "RPT_GETTHREADNAME",
"RPT_SETTHREADNAME", "RPT_SETTHREADREGS", "RPT_GETTHREADREGS",
"RPT_59",
"RPT_60", "RPT_61", "RPT_62", "RPT_63",
"RPT_64", "RPT_65", "RPT_66", "RPT_67",
"RPT_68", "RPT_69", "RPT_70", "RPT_71",
"RPT_72", "RPT_73", "RPT_74", "RPT_STEPRANGE",
"RPT_CONTTO", "RPT_SETBREAK", "RPT_CLRBREAK", "RPT_GETBREAK",
"RPT_GETNAME", "RPT_STOP",
"RPT_PGETREGS", "RPT_PSETREGS",
"RPT_PSETTHREADREGS", "RPT_PGETTHREADREGS"
"RPT_TRACEME", "RPT_PEEKTEXT", "RPT_PEEKDATA", "RPT_PEEKUSER",
"RPT_POKETEXT", "RPT_POKEDATA", "RPT_POKEUSER", "RPT_CONT",
"RPT_KILL", "RPT_SINGLESTEP", "RPT_ATTACH", "RPT_DETACH",
"RPT_GETREGS", "RPT_SETREGS", "RPT_GETFPREGS", "RPT_SETFPREGS",
"RPT_READDATA", "RPT_WRITEDATA", "RPT_READTEXT", "RPT_WRITETEXT",
"RPT_GETFPAREGS", "RPT_SETFPAREGS", "RPT_22", "RPT_23",
"RPT_SYSCALL", "RPT_DUMPCORE", "RPT_26", "RPT_27",
"RPT_28", "RPT_GETUCODE", "RPT_30", "RPT_31",
"RPT_32", "RPT_33", "RPT_34", "RPT_35",
"RPT_36", "RPT_37", "RPT_38", "RPT_39",
"RPT_40", "RPT_41", "RPT_42", "RPT_43",
"RPT_44", "RPT_45", "RPT_46", "RPT_47",
"RPT_48", "RPT_49", "RPT_GETTARGETTHREAD", "RPT_SETTARGETTHREAD",
"RPT_THREADSUSPEND", "RPT_THREADRESUME", "RPT_THREADLIST",
"RPT_GETTHREADNAME",
"RPT_SETTHREADNAME", "RPT_SETTHREADREGS", "RPT_GETTHREADREGS",
"RPT_59",
"RPT_60", "RPT_61", "RPT_62", "RPT_63",
"RPT_64", "RPT_65", "RPT_66", "RPT_67",
"RPT_68", "RPT_69", "RPT_70", "RPT_71",
"RPT_72", "RPT_73", "RPT_74", "RPT_STEPRANGE",
"RPT_CONTTO", "RPT_SETBREAK", "RPT_CLRBREAK", "RPT_GETBREAK",
"RPT_GETNAME", "RPT_STOP",
"RPT_PGETREGS", "RPT_PSETREGS",
"RPT_PSETTHREADREGS", "RPT_PGETTHREADREGS"
};
const char*
PtraceName(req)
int req;
const char *
PtraceName (int req)
{
static char bufret[40];
static char bufret[40];
if ((req < 0) || (req >= sizeof(PtraceNames)/sizeof(char*))) {
sprintf(bufret, "BAD_REQ_%d", req);
return bufret;
}
return PtraceNames[req];
if ((req < 0) || (req >= sizeof (PtraceNames) / sizeof (char *))) {
sprintf (bufret, "BAD_REQ_%d", req);
return bufret;
}
return PtraceNames[req];
}
const char* BmsgNames [] = {
"?", "WARM", "WAIT", "BREAK",
"EXEC_FAIL", "DETACH", "KILLED", "NOT_PRIM",
"NEW_PID"
const char *BmsgNames[] = {
"?", "WARM", "WAIT", "BREAK",
"EXEC_FAIL", "DETACH", "KILLED", "NOT_PRIM",
"NEW_PID"
};
#endif /* DDEBUG */