diff options
author | TAKADA Yoshihito <takada@mbf.nifty.com> | 2008-06-30 18:22:07 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-02 20:46:16 -0700 |
commit | 66f100382995e2510e5bbae37ec4dbc4f73e4638 (patch) | |
tree | af8583f68d1e9047cb47bab56d9446acda210026 | |
parent | 0758c2f30b75419fbe5e0ec6dfc892bbc0687f57 (diff) |
ptrace GET/SET FPXREGS broken
Commit 11dbc963a8f6128595d0f6ecf138dc369e144997 upstream
ptrace GET/SET FPXREGS broken
When I update kernel 2.6.25 from 2.6.24, gdb does not work.
On 2.6.25, ptrace(PTRACE_GETFPXREGS, ...) returns ENODEV.
But 2.6.24 kernel's ptrace() returns EIO.
It is issue of compatibility.
I attached test program as pt.c and patch for fix it.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/types.h>
struct user_fxsr_struct {
unsigned short cwd;
unsigned short swd;
unsigned short twd;
unsigned short fop;
long fip;
long fcs;
long foo;
long fos;
long mxcsr;
long reserved;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
};
int main(void)
{
pid_t pid;
pid = fork();
switch(pid){
case -1:/* error */
break;
case 0:/* child */
child();
break;
default:
parent(pid);
break;
}
return 0;
}
int child(void)
{
ptrace(PTRACE_TRACEME);
kill(getpid(), SIGSTOP);
sleep(10);
return 0;
}
int parent(pid_t pid)
{
int ret;
struct user_fxsr_struct fpxregs;
ret = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpxregs);
if(ret < 0){
printf("%d: %s.\n", errno, strerror(errno));
}
kill(pid, SIGCONT);
wait(pid);
return 0;
}
/* in the kerel, at kernel/i387.c get_fpxregs() */
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | arch/x86/kernel/i387.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index d2e39e69aaf..5f04579b5ca 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -130,7 +130,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, void *kbuf, void __user *ubuf) { if (!cpu_has_fxsr) - return -ENODEV; + return -EIO; init_fpu(target); @@ -145,7 +145,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, int ret; if (!cpu_has_fxsr) - return -ENODEV; + return -EIO; init_fpu(target); set_stopped_child_used_math(target); |