📄 servbkpt.c
字号:
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;}/*----- Hiding of breakpoints -----*/ /* * PatchBreak - patch original data from break into data buffer. * * Notes: * - this routine patches the original data under a break into the data * buffer from a ptrace read/peek. */ static voidPatchBreak (char *buff, UINT32 bstart, int bsize, UINT32 dstart, char *dvalue){ 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 */ } 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);} voidBreakHide (const PID_LIST * plst, void *addr, int data, void *addr2){ int idx; if (!plst->break_list) /* no breaks exist, so skip this */ return; /* * if breakpoints, replace */ 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); } }}/*----- Checking of breakpoint overwrites -----*/ /* * BreakOverwrite - check if memory write does not involve addresses * having software breakpoints. */ intBreakOverwrite (const PID_LIST * plst, const char *addr, unsigned int size){ 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 */ } } return 0;}/*----- Execution support -----*/ /* * BreakStepRange - Start stepping in a range. * * Range is saved in breakpoint 0. */ intBreakStepRange (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 */ } } BKPT0 (plst)->range_start = (UINT32) addr; BKPT0 (plst)->range_end = (UINT32) addr + (len - 1); return 0;} /* * If the Program Counter is changed, consider that the * current breakpoint has not been reached yet. */ voidBreakPcChanged (PID_LIST * plst){ if (plst->break_list) { /* * clear break stuff */ BKPT0 (plst)->clr_step = False; }} /* * BreakStepOff - prepare stepping off a breakpoint. */ intBreakStepOff (const PID_LIST * plst, void **paddr2){ if (plst->break_list && BKPT0 (plst)->clr_step) { /* * need clear then step off break */ int last = BKPT0 (plst)->last_break; /* * clear break, step, then do exec */ *paddr2 = (void *) plst->break_list[last].ee_type; /* * Need to clr_step after TgtPtrace() when wait() returns */ return 1; } return 0;} /* * BreakSteppedOff - check if just stepped off a breakpoint * and re-insert it into the code. */ voidBreakSteppedOff (PID_LIST * plst){ if (plst->break_list && BKPT0 (plst)->clr_step) { int idx = BKPT0 (plst)->last_break; int data; 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); }} /* * Returns whether a thread matches a breakpoint. */ static intBreakThreadMatch (xdr_break * xb, int thread){ int slot; if (thread < 0) return 1; /* Break existence check only */ 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 */} intBreakAdjustPC (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. */#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);#else (void) plst;#endif return 0;}/* * Identify the current breakpoint. The process just stopped. */ intBreakIdentify (PID_LIST * plst, int adjust, int thread){ int foreignBkpt = 0; int bidx; 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 (foreignBkpt) { if (adjust) { BreakAdjustPC (plst); } return -foreignBkpt; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -