From 4721cf1ecb949b37c98b6fce79163541711de2e5 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 3 Dec 1998 23:54:14 +0000 Subject: Patch from Emmanuel Raguet to add remote debug server and RPC support to RTEMS. Thanks. :) Email follows: Hello, For Xmas, here is the Remote Debugger on RTEMS ! Here are 2 patches for the Remote Debugger on RTEMS for pc386 from Linux host : - one for RTEMS it self, - one for GDB-4.17. 1/ RTEMS patch -------------- This patch adds 2 libraries : - a simplified SUN RPC library - the Remote Debugger library The configuration command is the following : ../rtems4/configure --target=i386-rtemself --enable-rtemsbsp=pc386 --enable-rdbg The SUN RPC library is built only if networking is set. The RDBG library is built if networking and enable-rdbg are set. The function used to initialize the debugger is : rtems_rdbg_initialize (); A special function has been created to force a task to be in a "debug" state : enterRdbg(). The use of this function is not mandatory. 2/ GDB-4.17 patch ----------------- This patch create a new RTEMS target for GDB-4.17. The configuration command is the following : ./configure --enable-shared --target=i386RTEMS To connect to a target, use : target rtems [your_site_address] Then, attach the target using : attach 1 And... Debug ;) You can obtain the original GDB-4.17 on ftp://ftp.debian.org/debian/dists/stable/main/source/devel/gdb_4.17.orig.tar.gz This has been tested from a Debian 2.0.1 linux host. --- c/src/librdbg/src/ptrace.c | 335 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 c/src/librdbg/src/ptrace.c (limited to 'c/src/librdbg/src/ptrace.c') diff --git a/c/src/librdbg/src/ptrace.c b/c/src/librdbg/src/ptrace.c new file mode 100644 index 0000000000..158bd57cbb --- /dev/null +++ b/c/src/librdbg/src/ptrace.c @@ -0,0 +1,335 @@ +/* + ************************************************************************** + * + * Component = + * + * Synopsis = rkdb/rkdb.c + * + ************************************************************************** + */ + +#include +#include +#include +#include +#include + +extern rtems_id serializeSemId; +extern rtems_id wakeupEventSemId; +extern rtems_id eventTaskId; +extern Exception_context *FirstCtx; +extern Exception_context *LastCtx; +extern CPU_Exception_frame SavedContext; +extern unsigned int NbExceptCtx; +extern unsigned int NbSerializedCtx; + + + +/* -------------------------------------------------------------------- + return a pointeur to the Tread Control structure of the specified + 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) { + + 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 ( 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]); + } + + return 0; + +} + + +/* -------------------------------------------------------------------- + Memory read + -------------------------------------------------------------------- */ + +int +safeMemRead(void *src, void *dest, int nbBytes){ + + /* + * safe because if it generates an exception, + * it must return normally + * TBD + */ + + memcpy(dest, src, nbBytes); + return 0; +} + +/* -------------------------------------------------------------------- + Memory write + -------------------------------------------------------------------- */ +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; +} + +/* -------------------------------------------------------------------- + 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) { + + case RPT_SINGLESTEP:{ + Exception_context *ctx; + + if (CannotRestart == 1){ + setErrno(EIO); + return -1; + } + + 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_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(); + 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 (CannotRestart == 1){ + setErrno (EIO); + return -1; + } + + ctx = GetExceptCtx (currentTargetThread); + + if ( + ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG && + ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT && + ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG + ) { + CannotRestart = 1; + setErrno (EIO); + return -1; + } + + assert (data == 0); + assert (ExitForSingleStep == 0); + + rtems_semaphore_release( serializeSemId ); + + 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 ((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; +} -- cgit v1.2.3