diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-08-02 15:00:07 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-08-02 15:00:07 +0000 |
commit | 261f99bdac9a995f8b2740b7ae52c8ad81001132 (patch) | |
tree | 2a5006b2c876e801a11527f6b20f47c312370b2f /c/src/librdbg/src/servtgt.c | |
parent | 2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com> (diff) | |
download | rtems-261f99bdac9a995f8b2740b7ae52c8ad81001132.tar.bz2 |
2007-08-02 Joel Sherrill <joel.sherrill@OARcorp.com>
* configure.ac, wrapup/Makefile.am: Remove RDBG.
* aclocal/check-rdbg.m4, aclocal/enable-rdbg.m4, librdbg/.cvsignore,
librdbg/Makefile.am, librdbg/preinstall.am,
librdbg/include/rdbg/rdbg.h, librdbg/include/rdbg/servrpc.h,
librdbg/include/rdbg/i386/rdbg_f.h, librdbg/include/rdbg/i386/reg.h,
librdbg/include/rdbg/m68k/rdbg_f.h, librdbg/include/rdbg/m68k/reg.h,
librdbg/include/rdbg/powerpc/rdbg_f.h,
librdbg/include/rdbg/powerpc/reg.h, librdbg/src/_servtgt.c,
librdbg/src/awk.svc, librdbg/src/excep.c, librdbg/src/ptrace.c,
librdbg/src/rdbg.c, librdbg/src/remdeb.x, librdbg/src/servbkpt.c,
librdbg/src/servcon.c, librdbg/src/servrpc.c, librdbg/src/servtgt.c,
librdbg/src/servtsp.c, librdbg/src/servutil.c,
librdbg/src/i386/excep_f.c, librdbg/src/i386/rdbg_cpu_asm.S,
librdbg/src/i386/rdbg_f.c, librdbg/src/i386/any/remdeb.h,
librdbg/src/i386/any/remdeb_f.x, librdbg/src/i386/any/remdeb_svc.c,
librdbg/src/i386/any/remdeb_xdr.c, librdbg/src/m68k/excep_f.c,
librdbg/src/m68k/rdbg_cpu_asm.S, librdbg/src/m68k/rdbg_f.c,
librdbg/src/m68k/any/remdeb.h, librdbg/src/m68k/any/remdeb_f.x,
librdbg/src/m68k/any/remdeb_svc.c, librdbg/src/m68k/any/remdeb_xdr.c,
librdbg/src/powerpc/excep_f.c, librdbg/src/powerpc/rdbg_cpu_asm.S,
librdbg/src/powerpc/rdbg_f.c,
librdbg/src/powerpc/new_exception_processing/remdeb.h,
librdbg/src/powerpc/new_exception_processing/remdeb_f.x,
librdbg/src/powerpc/new_exception_processing/remdeb_svc.c,
librdbg/src/powerpc/new_exception_processing/remdeb_xdr.c: Removed.
Diffstat (limited to 'c/src/librdbg/src/servtgt.c')
-rw-r--r-- | c/src/librdbg/src/servtgt.c | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/c/src/librdbg/src/servtgt.c b/c/src/librdbg/src/servtgt.c deleted file mode 100644 index 8635ad87c9..0000000000 --- a/c/src/librdbg/src/servtgt.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - ************************************************************************** - * - * Component: RDB servers - * Module: servtgt.c - * - * $Id$ - * - ************************************************************************** - */ - -#include <string.h> -#include <errno.h> -#include <rdbg/rdbg.h> -#include <rdbg/servrpc.h> -#include <sys/socket.h> -#include <assert.h> - -#ifdef DDEBUG -#define Ptrace TgtDbgPtrace -#else -#define Ptrace TgtRealPtrace -#endif - -/* - * 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 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 */ - return ret; -} - -/* - * - * 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) -{ - assert (plst->break_list); - assert (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)); - Ptrace (RPT_POKETEXT, plst->pid, - (char *) plst->break_list[idx].ee_loc, - (int) SET_BREAK (data), NULL); - } -} - -/* - * TgtCreateNew - add a new process into the process management lists. - */ - - void -TgtCreateNew (PID pid, int conn, INT32 child, char *name, Boolean spawn) -{ - int idx; - - for (idx = 0; idx < pid_list_cnt; idx++) - if (!pid_list[idx].pid) - break; /* find empty */ - - 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_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 - */ - } - return; /* failed */ - } - /* - * 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)); - - /* - * 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].owners = 1; - 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].name = name ? (char *) StrDup (name) : (char *) NULL; - -} - -/* - * TgtNotifyWaitChange - send event to clients indicating child changed state. - */ - - void -TgtNotifyWaitChange (PID pid, int status, Boolean exclude) -{ - 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 */ - } - 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 */ - } - } -} - -/* - * 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) -{ - int conn; - - 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 != exclude) - TspSendWaitChange (conn, msg, spec, pid_list[pid_idx].pid, context, - force); - } -} - -/* - * 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. - */ - - void -TgtDelete (PID_LIST * plst, int conn_idx, BACK_MSG notify) -{ - int idx = plst - pid_list, cnt, conn; - - /* - * found - */ - cnt = pid_list[idx].owners; - 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 (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); - } - pid_list[idx].pid = 0; /* gone */ -} - -/* - * TgtKillAndDelete - kill or detach process and remove entry. - */ - - int -TgtKillAndDelete (PID_LIST * plst, struct svc_req *rqstp, Boolean term) -{ - ptrace_in pin; /* used for ptrace call */ - ptrace_out *pout; - - /* - * Remove breakpoints - */ - if (plst->break_alloc > 0) { - pin.pid = plst->pid; - pin.addr.req = RPT_CLRBREAK; - pin.data = 0; /* clear all */ - pin.flags = PTRFLG_NON_OWNER; - pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp); - if (pout->result < 0) { - DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n", getErrno ())); - return -1; - } - } - - if (term) { /* kill */ - pin.addr.ptrace_addr_data_in_u.address = 0; - pin.data = -1; /* Don't want notification from slave */ - pin.addr.req = RPT_KILL; - } else { /* detach */ - pin.addr.ptrace_addr_data_in_u.address = 1; - pin.data = 0; - pin.addr.req = RPT_DETACH; - } - pin.pid = plst->pid; - 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)); - - pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp); /* start it */ - if (pout->errNo == ESRCH && plst->pid) - TgtDelete (plst, -1, BMSG_KILLED); /* only entry remains */ - return 0; -} - -/* - * TgtDetachCon - detach a connection's ownership of a process. - */ - - 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 */ - PIDMAP_CLEAR (conn_idx, pid_idx); - - if (pid_list[pid_idx].owners) - pid_list[pid_idx].owners--; - 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 */ - } -} - -/* ----------------------------------------------------------------------- - TgtHandleChildChange - decide what action to take after wait() returns. - Used in the master only. - ----------------------------------------------------------------------- */ - -#ifdef DDEBUG -static char *LastStartNames[] = { - "NONE", "STEP", "CONT", "RANGE", - "STEPOFF", "KILLED", "DETACHED" -}; - - char * -GetLastStartName (int last_start) -{ - static char buf[32]; - - 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; - - DPRINTF (("TgtHandleChildChange: pid %d status %x cap\n", - (int) pid, *status)); - if (unexp) - *unexp = 0; /* initialize to ok */ - - /* - * first, find pid in question - */ - idx = FindPidEntry (pid); - if (idx < 0) { /* cannot locate this process */ - DPRINTF (("TgtHandleChildChange: unknown process (%s pid)\n", - FindPidEntry (pid) >= 0 ? "stale" : "unknown")); - if (unexp) - *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 - */ - - /* - * copy ctxt - */ - CtxToRegs (ctx, &(plst->regs)); - - stopWanted = plst->stop_wanted; - plst->stop_wanted = 0; /* For the next time */ - - hadStepEmul = BreakClear (plst, -1, -1) > 0; - origHadStepEmul = hadStepEmul; /* hadStepEmul is cleared if real bkpt met */ - - 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)); - } - - /* - * Get current thread - */ - plst->thread = TgtPtrace (RPT_GETTARGETTHREAD, pid, NULL, 0, NULL); - - 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; - } - 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))); - - 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); - } - - 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 - */ - - 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->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 */ - 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); - } - - 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 (True); /* stop and notify */ -} - -#ifdef DDEBUG - -/* - * TgtDbgPtrace - debug version of ptrace. - */ - - int -TgtDbgPtrace (int request, PID pid, char *addr, int data, void *addr2) -{ - int diag; - - DPRINTF (("TgtDbgPtrace: entered (%s (%d), %d, %x, %d, %x)\n", - PtraceName (request), request, pid, (int) addr, data, - (int) addr2)); - - if (request == RPT_WRITETEXT || request == RPT_WRITEDATA) { - int i; - - DPRINTF (("TgtDbgPtrace:")); - if (rdb_debug) { - for (i = 0; i < data && i < 16; ++i) { - printf (" %02x", ((char *) addr2)[i] & 0xFF); - } - printf ("\n"); - } - } - - diag = TgtRealPtrace (request, pid, addr, data, addr2); - - DPRINTF (("TgtDbgPtrace: returned %d (%x) errno %d\n", - 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 - */ - 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)); - } - - return (diag); -} -#endif /* DDEBUG */ |