patch-2.4.3 linux/arch/sparc64/kernel/ptrace.c
Next file: linux/arch/sparc64/kernel/rtrap.S
Previous file: linux/arch/sparc64/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 439
- Date:
Sun Mar 25 18:14:21 2001
- Orig file:
v2.4.2/linux/arch/sparc64/kernel/ptrace.c
- Orig date:
Wed Feb 21 18:20:15 2001
diff -u --recursive --new-file v2.4.2/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
@@ -53,10 +53,10 @@
pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
{
if (current->thread.flags & SPARC_FLAG_32BIT) {
- if(put_user(value, (unsigned int *)addr))
+ if (put_user(value, (unsigned int *)addr))
return pt_error_return(regs, EFAULT);
} else {
- if(put_user(value, addr))
+ if (put_user(value, addr))
return pt_error_return(regs, EFAULT);
}
regs->u_regs[UREG_I0] = 0;
@@ -137,7 +137,7 @@
s, request, pid, addr, data, addr2);
}
#endif
- if(request == PTRACE_TRACEME) {
+ if (request == PTRACE_TRACEME) {
/* are we already being traced? */
if (current->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
@@ -149,7 +149,7 @@
goto out;
}
#ifndef ALLOW_INIT_TRACING
- if(pid == 1) {
+ if (pid == 1) {
/* Can't dork with init. */
pt_error_return(regs, EPERM);
goto out;
@@ -157,9 +157,11 @@
#endif
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
read_unlock(&tasklist_lock);
- if(!child) {
+ if (!child) {
pt_error_return(regs, ESRCH);
goto out;
}
@@ -168,32 +170,32 @@
|| (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags;
- if(child == current) {
+ if (child == current) {
/* Try this under SunOS/Solaris, bwa haha
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
- if((!child->dumpable ||
- (current->uid != child->euid) ||
- (current->uid != child->uid) ||
- (current->uid != child->suid) ||
- (current->gid != child->egid) ||
- (current->gid != child->sgid) ||
- (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
- (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
+ if ((!child->dumpable ||
+ (current->uid != child->euid) ||
+ (current->uid != child->uid) ||
+ (current->uid != child->suid) ||
+ (current->gid != child->egid) ||
+ (current->gid != child->sgid) ||
+ (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
- if(child->p_pptr != current) {
+ if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
@@ -201,32 +203,32 @@
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
- if(child->state != TASK_STOPPED) {
- if(request != PTRACE_KILL) {
+ if (child->state != TASK_STOPPED) {
+ if (request != PTRACE_KILL) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
}
- if(child->p_pptr != current) {
+ if (child->p_pptr != current) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
- if(!(child->thread.flags & SPARC_FLAG_32BIT) &&
- ((request == PTRACE_READDATA64) ||
- (request == PTRACE_WRITEDATA64) ||
- (request == PTRACE_READTEXT64) ||
- (request == PTRACE_WRITETEXT64) ||
- (request == PTRACE_PEEKTEXT64) ||
- (request == PTRACE_POKETEXT64) ||
- (request == PTRACE_PEEKDATA64) ||
- (request == PTRACE_POKEDATA64))) {
+ if (!(child->thread.flags & SPARC_FLAG_32BIT) &&
+ ((request == PTRACE_READDATA64) ||
+ (request == PTRACE_WRITEDATA64) ||
+ (request == PTRACE_READTEXT64) ||
+ (request == PTRACE_WRITETEXT64) ||
+ (request == PTRACE_PEEKTEXT64) ||
+ (request == PTRACE_POKETEXT64) ||
+ (request == PTRACE_PEEKDATA64) ||
+ (request == PTRACE_POKEDATA64))) {
addr = regs->u_regs[UREG_G2];
addr2 = regs->u_regs[UREG_G3];
request -= 30; /* wheee... */
@@ -278,7 +280,7 @@
if (copied == sizeof(tmp64))
res = 0;
}
- if(res < 0)
+ if (res < 0)
pt_error_return(regs, -res);
else
pt_succ_return(regs, res);
@@ -295,42 +297,45 @@
__put_user(cregs->tnpc, (&pregs->npc)) ||
__put_user(cregs->y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
- for(rval = 1; rval < 16; rval++)
+ for (rval = 1; rval < 16; rval++)
if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_GETREGS64: {
struct pt_regs *pregs = (struct pt_regs *) addr;
struct pt_regs *cregs = child->thread.kregs;
+ unsigned long tpc = cregs->tpc;
int rval;
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+ tpc &= 0xffffffff;
if (__put_user(cregs->tstate, (&pregs->tstate)) ||
- __put_user(cregs->tpc, (&pregs->tpc)) ||
+ __put_user(tpc, (&pregs->tpc)) ||
__put_user(cregs->tnpc, (&pregs->tnpc)) ||
__put_user(cregs->y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
- for(rval = 1; rval < 16; rval++)
+ for (rval = 1; rval < 16; rval++)
if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS: {
@@ -347,23 +352,23 @@
__get_user(npc, (&pregs->npc)) ||
__get_user(y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
cregs->tstate &= ~(TSTATE_ICC);
cregs->tstate |= psr_to_tstate_icc(psr);
- if(!((pc | npc) & 3)) {
+ if (!((pc | npc) & 3)) {
cregs->tpc = pc;
cregs->tnpc = npc;
}
cregs->y = y;
- for(i = 1; i < 16; i++) {
+ for (i = 1; i < 16; i++) {
if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS64: {
@@ -380,24 +385,28 @@
__get_user(tnpc, (&pregs->tnpc)) ||
__get_user(y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
+ }
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ tpc &= 0xffffffff;
+ tnpc &= 0xffffffff;
}
tstate &= (TSTATE_ICC | TSTATE_XCC);
cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
cregs->tstate |= tstate;
- if(!((tpc | tnpc) & 3)) {
+ if (!((tpc | tnpc) & 3)) {
cregs->tpc = tpc;
cregs->tnpc = tnpc;
}
cregs->y = y;
- for(i = 1; i < 16; i++) {
+ for (i = 1; i < 16; i++) {
if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS: {
@@ -422,10 +431,10 @@
__put_user(0, (&fps->extra)) ||
clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS64: {
@@ -439,10 +448,10 @@
(64 * sizeof(unsigned int))) ||
__put_user(child->thread.xfsr[0], (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS: {
@@ -464,7 +473,7 @@
(32 * sizeof(unsigned int))) ||
__get_user(fsr, (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
child->thread.xfsr[0] &= 0xffffffff00000000UL;
child->thread.xfsr[0] |= fsr;
@@ -472,7 +481,7 @@
child->thread.gsr[0] = 0;
child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS64: {
@@ -486,13 +495,13 @@
(64 * sizeof(unsigned int))) ||
__get_user(child->thread.xfsr[0], (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
if (!(child->thread.fpsaved[0] & FPRS_FEF))
child->thread.gsr[0] = 0;
child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_READTEXT:
@@ -528,19 +537,24 @@
case PTRACE_CONT: { /* restart after signal. */
if (data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
if (addr != 1) {
+ unsigned long pc_mask = ~0UL;
+
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+ pc_mask = 0xffffffff;
+
if (addr & 3) {
pt_error_return(regs, EINVAL);
- goto out;
+ goto out_tsk;
}
#ifdef DEBUG_PTRACE
printk ("Original: %016lx %016lx\n", child->thread.kregs->tpc, child->thread.kregs->tnpc);
printk ("Continuing with %016lx %016lx\n", addr, addr+4);
#endif
- child->thread.kregs->tpc = addr;
- child->thread.kregs->tnpc = addr + 4;
+ child->thread.kregs->tpc = (addr & pc_mask);
+ child->thread.kregs->tnpc = ((addr + 4) & pc_mask);
}
if (request == PTRACE_SYSCALL)
@@ -558,7 +572,7 @@
#endif
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/*
@@ -569,12 +583,12 @@
case PTRACE_KILL: {
if (child->state == TASK_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
child->exit_code = SIGKILL;
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
@@ -582,7 +596,7 @@
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
@@ -595,29 +609,39 @@
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* PTRACE_DUMPCORE unsupported... */
default:
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
flush_and_out:
{
unsigned long va;
- for(va = 0; va < (PAGE_SIZE << 1); va += 32)
- spitfire_put_dcache_tag(va, 0x0);
- if (request == PTRACE_PEEKTEXT ||
- request == PTRACE_POKETEXT ||
- request == PTRACE_READTEXT ||
- request == PTRACE_WRITETEXT) {
- for(va = 0; va < (PAGE_SIZE << 1); va += 32)
- spitfire_put_icache_tag(va, 0x0);
- __asm__ __volatile__("flush %g6");
+
+ if (tlb_type == cheetah) {
+ for (va = 0; va < (1 << 16); va += (1 << 5))
+ spitfire_put_dcache_tag(va, 0x0);
+ /* No need to mess with I-cache on Cheetah. */
+ } else {
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_dcache_tag(va, 0x0);
+ if (request == PTRACE_PEEKTEXT ||
+ request == PTRACE_POKETEXT ||
+ request == PTRACE_READTEXT ||
+ request == PTRACE_WRITETEXT) {
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_icache_tag(va, 0x0);
+ __asm__ __volatile__("flush %g6");
+ }
}
}
+out_tsk:
+ if (child)
+ free_task_struct(child);
out:
unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)