--- zzzz-none-000/linux-2.4.17/arch/mips/kernel/ptrace.c 2001-09-18 23:56:19.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/arch/mips/kernel/ptrace.c 2004-11-24 13:22:35.000000000 +0000 @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -42,7 +41,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; - int res; + int ret; extern void save_fp(struct task_struct *); lock_kernel(); @@ -54,15 +53,15 @@ if (request == PTRACE_TRACEME) { /* are we already being traced? */ if (current->ptrace & PT_PTRACED) { - res = -EPERM; + ret = -EPERM; goto out; } /* set the ptrace bit in the process flags. */ current->ptrace |= PT_PTRACED; - res = 0; + ret = 0; goto out; } - res = -ESRCH; + ret = -ESRCH; read_lock(&tasklist_lock); child = find_task_by_pid(pid); if (child) @@ -71,23 +70,19 @@ if (!child) goto out; - res = -EPERM; + ret = -EPERM; if (pid == 1) /* you may not mess with init */ goto out; if (request == PTRACE_ATTACH) { - res = ptrace_attach(child); + ret = ptrace_attach(child); goto out_tsk; } - res = -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) { case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { @@ -95,10 +90,10 @@ int copied; copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - res = -EIO; + ret = -EIO; if (copied != sizeof(tmp)) break; - res = put_user(tmp,(unsigned long *) data); + ret = put_user(tmp,(unsigned long *) data); goto out; } @@ -126,9 +121,9 @@ child->thread.fpu.soft.regs; } else if (last_task_used_math == child) { - enable_cp1(); + __enable_fpu(); save_fp(child); - disable_cp1(); + __disable_fpu(); last_task_used_math = NULL; regs->cp0_status &= ~ST0_CU1; } @@ -137,7 +132,7 @@ * order bits of the values stored in the even * registers - unless we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_LX45XXX) if (mips_cpu.options & MIPS_CPU_FPU) tmp = *(unsigned long *)(fregs + addr); else @@ -174,33 +169,37 @@ case FPC_EIR: { /* implementation / version register */ unsigned int flags; + if (!(mips_cpu.options & MIPS_CPU_FPU)) { + break; + } + __save_flags(flags); - enable_cp1(); + __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); __restore_flags(flags); break; } default: tmp = 0; - res = -EIO; + ret = -EIO; goto out; } - res = put_user(tmp, (unsigned long *) data); + ret = put_user(tmp, (unsigned long *) data); goto out; } case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: - res = 0; + ret = 0; if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) break; - res = -EIO; + ret = -EIO; goto out; case PTRACE_POKEUSR: { struct pt_regs *regs; - res = 0; + ret = 0; regs = (struct pt_regs *) ((unsigned long) child + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); @@ -217,9 +216,9 @@ fregs = (unsigned long long *) child->thread.fpu.soft.regs; } else { - enable_cp1(); + __enable_fpu(); save_fp(child); - disable_cp1(); + __disable_fpu(); last_task_used_math = NULL; regs->cp0_status &= ~ST0_CU1; } @@ -235,7 +234,7 @@ * of the values stored in the even registers - unless * we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_LX45XXX) if (mips_cpu.options & MIPS_CPU_FPU) *(unsigned long *)(fregs + addr) = data; else @@ -266,7 +265,7 @@ break; default: /* The rest are not allowed. */ - res = -EIO; + ret = -EIO; break; } break; @@ -274,7 +273,7 @@ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ - res = -EIO; + ret = -EIO; if ((unsigned long) data > _NSIG) break; if (request == PTRACE_SYSCALL) @@ -283,7 +282,7 @@ child->ptrace &= ~PT_TRACESYS; child->exit_code = data; wake_up_process(child); - res = 0; + ret = 0; break; } @@ -293,7 +292,7 @@ * exit. */ case PTRACE_KILL: - res = 0; + ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; child->exit_code = SIGKILL; @@ -301,7 +300,7 @@ break; case PTRACE_DETACH: /* detach a process that was attached. */ - res = ptrace_detach(child, data); + ret = ptrace_detach(child, data); break; case PTRACE_SETOPTIONS: @@ -309,18 +308,27 @@ child->ptrace |= PT_TRACESYSGOOD; else child->ptrace &= ~PT_TRACESYSGOOD; - res = 0; + ret = 0; break; default: - res = -EIO; + ret = -EIO; goto out; } out_tsk: free_task_struct(child); out: unlock_kernel(); - return res; + return ret; +} + +struct pt_regs *get_task_registers(struct task_struct* task) +{ + struct pt_regs *regs; + + regs = (struct pt_regs *) ((unsigned long) task + + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); + return regs; } asmlinkage void syscall_trace(void)