patch-1.3.22 linux/arch/alpha/kernel/signal.c
Next file: linux/arch/alpha/kernel/traps.c
Previous file: linux/arch/alpha/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 90
- Date:
Tue Aug 29 10:15:48 1995
- Orig file:
v1.3.21/linux/arch/alpha/kernel/signal.c
- Orig date:
Tue Jul 25 18:21:20 1995
diff -u --recursive --new-file v1.3.21/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
@@ -25,6 +25,9 @@
unsigned long, unsigned long);
asmlinkage void imb(void);
+extern int ptrace_set_bpt (struct task_struct *child);
+extern int ptrace_cancel_bpt (struct task_struct *child);
+
/*
* The OSF/1 sigprocmask calling sequence is different from the
* C sigprocmask() sequence..
@@ -119,13 +122,19 @@
regs->gp = get_fs_quad(sc->sc_regs+29);
for (i = 0; i < 31; i++)
sw->fp[i] = get_fs_quad(sc->sc_fpregs+i);
+
+ /* send SIGTRAP if we're single-stepping: */
+ if (ptrace_cancel_bpt (current))
+ send_sig(SIGTRAP, current, 1);
}
/*
* Set up a signal frame...
*/
-static void setup_frame(struct sigaction * sa, struct sigcontext_struct ** fp, unsigned long pc,
- struct pt_regs * regs, struct switch_stack * sw, int signr, unsigned long oldmask)
+static void setup_frame(struct sigaction * sa, struct sigcontext_struct ** fp,
+ unsigned long pc, struct pt_regs * regs,
+ struct switch_stack * sw, int signr,
+ unsigned long oldmask)
{
int i;
struct sigcontext_struct * sc;
@@ -212,11 +221,10 @@
unsigned long handler_signal = 0;
struct sigcontext_struct *frame = NULL;
unsigned long pc = 0;
- unsigned long signr;
+ unsigned long signr, single_stepping;
struct sigaction * sa;
- extern ptrace_cancel_bpt (struct task_struct *child);
- ptrace_cancel_bpt(current); /* make sure single-step bpt is gone */
+ single_stepping = ptrace_cancel_bpt(current);
while ((signr = current->signal & mask) != 0) {
signr = ffz(~signr);
@@ -228,6 +236,7 @@
current->state = TASK_STOPPED;
notify_parent(current);
schedule();
+ single_stepping |= ptrace_cancel_bpt(current);
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
@@ -263,6 +272,7 @@
SA_NOCLDSTOP))
notify_parent(current);
schedule();
+ single_stepping |= ptrace_cancel_bpt(current);
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
@@ -292,12 +302,16 @@
(regs->r0 == ERESTARTNOHAND ||
regs->r0 == ERESTARTSYS ||
regs->r0 == ERESTARTNOINTR)) {
- regs->r0 = r0;
+ regs->r0 = r0; /* reset v0 and a3 and replay syscall */
regs->r19 = r19;
regs->pc -= 4;
}
- if (!handler_signal) /* no handler will be called - return 0 */
+ if (!handler_signal) { /* no handler will be called - return 0 */
+ if (single_stepping) {
+ ptrace_set_bpt(current); /* re-set breakpoint */
+ }
return 0;
+ }
pc = regs->pc;
frame = (struct sigcontext_struct *) rdusp();
signr = 1;
@@ -318,5 +332,8 @@
imb();
wrusp((unsigned long) frame);
regs->pc = pc; /* "return" to the first handler */
+ if (single_stepping) {
+ ptrace_set_bpt(current); /* re-set breakpoint */
+ }
return 1;
}
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]
with Sam's (original) version of this