diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-03 01:22:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-03 01:22:27 +0000 |
commit | f9bbe9da79dbc8557c74efeb158b431cd67ace52 (patch) | |
tree | 3220d014a35f9d88a48668a1468524e988daebff /arch/i386/kernel/ptrace.c | |
parent | 3d697109c1ff85ef563aec3d5e113ef225ed2792 (diff) |
Upgrade to 2.1.73.
Diffstat (limited to 'arch/i386/kernel/ptrace.c')
-rw-r--r-- | arch/i386/kernel/ptrace.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 246a6c29b..e08d75100 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -16,6 +16,7 @@ #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/system.h> +#include <asm/processor.h> /* * does not yet catch signals sent when the child dies. @@ -561,6 +562,102 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) goto out; } + case PTRACE_GETREGS: { /* Get all gp regs from the child. */ + if (!access_ok(VERIFY_WRITE, (unsigned *)data, + 17*sizeof(long))) + { + ret = -EIO; + goto out; + } + for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) + { + __put_user(getreg(child, i),(unsigned long *) data); + data += sizeof(long); + } + ret = 0; + goto out; + }; + + case PTRACE_SETREGS: { /* Set all gp regs in the child. */ + unsigned long tmp; + if (!access_ok(VERIFY_READ, (unsigned *)data, + 17*sizeof(long))) + { + ret = -EIO; + goto out; + } + for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) + { + __get_user(tmp, (unsigned long *) data); + putreg(child, i, tmp); + data += sizeof(long); + } + ret = 0; + goto out; + }; + + case PTRACE_GETFPREGS: { /* Get the child FPU state. */ + if (!access_ok(VERIFY_WRITE, (unsigned *)data, + sizeof(struct user_i387_struct))) + { + ret = -EIO; + goto out; + } + ret = 0; + if ( !child->used_math ) { + /* Simulate an empty FPU. */ + child->tss.i387.hard.cwd = 0xffff037f; + child->tss.i387.hard.swd = 0xffff0000; + child->tss.i387.hard.twd = 0xffffffff; + } +#ifdef CONFIG_MATH_EMULATION + if ( hard_math ) { +#endif + if (last_task_used_math == child) { + clts(); + __asm__("fnsave %0; fwait":"=m" (child->tss.i387.hard)); + last_task_used_math = NULL; + stts(); + } + __copy_to_user((void *)data, &child->tss.i387.hard, + sizeof(struct user_i387_struct)); +#ifdef CONFIG_MATH_EMULATION + } else { + save_i387_soft(&child->tss.i387.soft, + (struct _fpstate *)data); + } +#endif + goto out; + }; + + case PTRACE_SETFPREGS: { /* Set the child FPU state. */ + if (!access_ok(VERIFY_READ, (unsigned *)data, + sizeof(struct user_i387_struct))) + { + ret = -EIO; + goto out; + } + child->used_math = 1; +#ifdef CONFIG_MATH_EMULATION + if ( hard_math ) { +#endif + if (last_task_used_math == child) { + /* Discard the state of the FPU */ + last_task_used_math = NULL; + } + __copy_from_user(&child->tss.i387.hard, (void *)data, + sizeof(struct user_i387_struct)); + child->flags &= ~PF_USEDFPU; +#ifdef CONFIG_MATH_EMULATION + } else { + restore_i387_soft(&child->tss.i387.soft, + (struct _fpstate *)data); + } +#endif + ret = 0; + goto out; + }; + default: ret = -EIO; goto out; |