patch-2.4.10 linux/arch/mips64/kernel/ptrace.c
Next file: linux/arch/mips64/kernel/r4k_cache.S
Previous file: linux/arch/mips64/kernel/proc.c
Back to the patch index
Back to the overall index
- Lines: 181
- Date:
Tue Sep 18 16:56:19 2001
- Orig file:
v2.4.9/linux/arch/mips64/kernel/ptrace.c
- Orig date:
Wed Jul 25 17:10:18 2001
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/ptrace.c linux/arch/mips64/kernel/ptrace.c
@@ -29,6 +29,16 @@
#include <asm/uaccess.h>
/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ /* Nothing to do.. */
+}
+
+/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
*/
@@ -104,6 +114,9 @@
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
+ unsigned long *fregs =
+ (void *) child->thread.fpu.hard.fp_regs;
+
#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
@@ -112,7 +125,15 @@
last_task_used_math = NULL;
}
#endif
- tmp = child->thread.fpu.hard.fp_regs[addr - 32];
+ /*
+ * The odd registers are actually the high
+ * order bits of the values stored in the even
+ * registers.
+ */
+ if (addr & 1)
+ tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+ else
+ tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
} else {
tmp = -EIO;
}
@@ -171,7 +192,8 @@
regs->regs[addr] = data;
break;
case FPR_BASE ... FPR_BASE + 31: {
- unsigned long *fregs;
+ unsigned long *fregs =
+ (void *) child->thread.fpu.hard.fp_regs;
if (child->used_math) {
#ifndef CONFIG_SMP
if (last_task_used_math == child) {
@@ -188,8 +210,18 @@
sizeof(child->thread.fpu.hard));
child->thread.fpu.hard.control = 0;
}
- fregs = child->thread.fpu.hard.fp_regs;
- fregs[addr - FPR_BASE] = data;
+ /*
+ * The odd registers are actually the high order bits
+ * of the values stored in the even registers - unless
+ * we're using r2k_switch.S.
+ */
+ if (addr & 1) {
+ fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+ fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
+ } else {
+ fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+ fregs[addr - FPR_BASE] |= data;
+ }
break;
}
case PC:
@@ -239,21 +271,9 @@
break;
}
- case PTRACE_DETACH: { /* detach a process that was attached. */
- ret = -EIO;
- if ((unsigned long) data > _NSIG)
- break;
- child->ptrace = 0;
- child->exit_code = data;
- write_lock_irq(&tasklist_lock);
- REMOVE_LINKS(child);
- child->p_pptr = child->p_opptr;
- SET_LINKS(child);
- write_unlock_irq(&tasklist_lock);
- wake_up_process(child);
- ret = 0;
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
break;
- }
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
@@ -354,6 +374,9 @@
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
+ unsigned long long *fregs
+ = (unsigned long long *)
+ &child->thread.fpu.hard.fp_regs[0];
#ifndef CONFIG_SMP
if (last_task_used_math == child) {
set_cp0_status(ST0_CU1, ST0_CU1);
@@ -362,7 +385,15 @@
last_task_used_math = NULL;
}
#endif
- tmp = child->thread.fpu.hard.fp_regs[addr - 32];
+ /*
+ * The odd registers are actually the high
+ * order bits of the values stored in the even
+ * registers.
+ */
+ if (addr & 1)
+ tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+ else
+ tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
} else {
tmp = -EIO;
}
@@ -421,7 +452,8 @@
regs->regs[addr] = data;
break;
case FPR_BASE ... FPR_BASE + 31: {
- unsigned long *fregs;
+ unsigned long *fregs =
+ (void *) child->thread.fpu.hard.fp_regs;
if (child->used_math) {
#ifndef CONFIG_SMP
if (last_task_used_math == child) {
@@ -438,8 +470,18 @@
sizeof(child->thread.fpu.hard));
child->thread.fpu.hard.control = 0;
}
- fregs = child->thread.fpu.hard.fp_regs;
- fregs[addr - FPR_BASE] = data;
+ /*
+ * The odd registers are actually the high order bits
+ * of the values stored in the even registers - unless
+ * we're using r2k_switch.S.
+ */
+ if (addr & 1) {
+ fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+ fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
+ } else {
+ fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+ fregs[addr - FPR_BASE] |= data;
+ }
break;
}
case PC:
@@ -489,21 +531,9 @@
break;
}
- case PTRACE_DETACH: { /* detach a process that was attached. */
- ret = -EIO;
- if ((unsigned long) data > _NSIG)
- break;
- child->ptrace = 0;
- child->exit_code = data;
- write_lock_irq(&tasklist_lock);
- REMOVE_LINKS(child);
- child->p_pptr = child->p_opptr;
- SET_LINKS(child);
- write_unlock_irq(&tasklist_lock);
- wake_up_process(child);
- ret = 0;
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
break;
- }
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)