patch-2.4.21 linux-2.4.21/arch/x86_64/kernel/ptrace.c
Next file: linux-2.4.21/arch/x86_64/kernel/setup.c
Previous file: linux-2.4.21/arch/x86_64/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 112
- Date:
2003-06-13 07:51:32.000000000 -0700
- Orig file:
linux-2.4.20/arch/x86_64/kernel/ptrace.c
- Orig date:
2002-11-28 15:53:12.000000000 -0800
diff -urN linux-2.4.20/arch/x86_64/kernel/ptrace.c linux-2.4.21/arch/x86_64/kernel/ptrace.c
@@ -90,6 +90,8 @@
unsigned long regno, unsigned long value)
{
unsigned long tmp;
+ if (child->thread.flags & THREAD_IA32)
+ value &= 0xffffffff;
switch (regno) {
case offsetof(struct user_regs_struct,fs):
if (value && (value & 3) != 3)
@@ -144,6 +146,7 @@
static unsigned long getreg(struct task_struct *child, unsigned long regno)
{
+ unsigned long val;
switch (regno) {
case offsetof(struct user_regs_struct, fs):
return child->thread.fsindex;
@@ -159,7 +162,10 @@
return child->thread.gs;
default:
regno = regno - sizeof(struct pt_regs);
- return get_stack_long(child, regno);
+ val = get_stack_long(child, regno);
+ if (child->thread.flags & THREAD_IA32)
+ val &= 0xffffffff;
+ return val;
}
}
@@ -199,15 +205,10 @@
ret = ptrace_attach(child);
goto out_tsk;
}
- ret = -ESRCH;
- if (!(child->ptrace & PT_PTRACED))
- goto out_tsk;
- if (child->state != TASK_STOPPED) {
- if (request != PTRACE_KILL)
- goto out_tsk;
- }
- if (child->p_pptr != current)
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
goto out_tsk;
+
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -228,8 +229,8 @@
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 7) || addr < 0 ||
+ addr > sizeof(struct user) - 7)
break;
tmp = 0; /* Default return condition */
@@ -238,7 +239,7 @@
if(addr >= (long) &dummy->u_debugreg[0] &&
addr <= (long) &dummy->u_debugreg[7]){
addr -= (long) &dummy->u_debugreg[0];
- addr = addr >> 2;
+ addr = addr >> 3;
tmp = child->thread.debugreg[addr];
}
ret = put_user(tmp,(unsigned long *) data);
@@ -256,8 +257,8 @@
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 7) || addr < 0 ||
+ addr > sizeof(struct user) - 7)
break;
if (addr < sizeof(struct user_regs_struct)) {
@@ -278,6 +279,11 @@
if(addr < (long) &dummy->u_debugreg[4] &&
((unsigned long) data) >= TASK_SIZE-3) break;
+ if (addr == (long) &dummy->u_debugreg[6]) {
+ if (data >> 32)
+ goto out_tsk;
+ }
+
if(addr == (long) &dummy->u_debugreg[7]) {
data &= ~DR_CONTROL_RESERVED;
for(i=0; i<4; i++)
@@ -286,7 +292,7 @@
}
addr -= (long) &dummy->u_debugreg;
- addr = addr >> 2;
+ addr = addr >> 3;
child->thread.debugreg[addr] = data;
ret = 0;
}
@@ -401,8 +407,10 @@
ret = -EIO;
break;
}
- child->used_math = 1;
+ unlazy_fpu(child);
ret = set_fpregs(child, (struct user_i387_struct *)data);
+ if (!ret)
+ child->used_math = 1;
break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)