/* ************************************************************************** * * Component = * * Synopsis = rkdb/rkdb.c * * $Id$ * ************************************************************************** */ #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(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 (CannotRestart == 1){ setErrno (EIO); return -1; } ctx = GetExceptCtx (currentTargetThread); if (!isRdbgException(ctx)) { 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; }