patch-2.1.44 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: 437
- Date:
Mon Jul 7 08:18:54 1997
- Orig file:
v2.1.43/linux/arch/sparc64/kernel/ptrace.c
- Orig date:
Thu May 29 21:53:04 1997
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
@@ -100,7 +100,16 @@
/* this is a hack for non-kernel-mapped video buffers and similar */
flush_cache_page(vma, addr);
if (MAP_NR(page) < max_mapnr) {
- *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
+ unsigned long pgaddr;
+
+ pgaddr = page + (addr & ~PAGE_MASK);
+ *(unsigned long *) (pgaddr) = data;
+
+ __asm__ __volatile__("
+ membar #StoreStore
+ flush %0
+" : : "r" (pgaddr & ~7) : "memory");
+
flush_page_to_ram(page);
}
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
@@ -138,7 +147,16 @@
/* this is a hack for non-kernel-mapped video buffers and similar */
flush_cache_page(vma, addr);
if (MAP_NR(page) < max_mapnr) {
- *(unsigned int *) (page + (addr & ~PAGE_MASK)) = data;
+ unsigned long pgaddr;
+
+ pgaddr = page + (addr & ~PAGE_MASK);
+ *(unsigned int *) (pgaddr) = data;
+
+ __asm__ __volatile__("
+ membar #StoreStore
+ flush %0
+" : : "r" (pgaddr & ~7) : "memory");
+
flush_page_to_ram(page);
}
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
@@ -570,6 +588,21 @@
pt_error_return(regs, ESRCH);
goto out;
}
+
+ if(!(child->tss.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... */
+ }
+
switch(request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -641,195 +674,207 @@
goto out;
}
- case PTRACE_GETREGS:
- if (current->tss.flags & SPARC_FLAG_32BIT) {
- struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
- struct pt_regs *cregs = child->tss.kregs;
- int rval;
-
- if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
- __put_user(cregs->tpc, (&pregs->pc)) ||
- __put_user(cregs->tnpc, (&pregs->npc)) ||
- __put_user(cregs->y, (&pregs->y))) {
+ case PTRACE_GETREGS: {
+ struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
+ struct pt_regs *cregs = child->tss.kregs;
+ int rval;
+
+ if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
+ __put_user(cregs->tpc, (&pregs->pc)) ||
+ __put_user(cregs->tnpc, (&pregs->npc)) ||
+ __put_user(cregs->y, (&pregs->y))) {
+ pt_error_return(regs, EFAULT);
+ goto out;
+ }
+ 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;
}
- 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;
- }
- pt_succ_return(regs, 0);
+ pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
- printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
+ printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
+ goto out;
+ }
+
+ case PTRACE_GETREGS64: {
+ struct pt_regs *pregs = (struct pt_regs *) addr;
+ struct pt_regs *cregs = child->tss.kregs;
+ int rval;
+
+ if (__put_user(cregs->tstate, (&pregs->tstate)) ||
+ __put_user(cregs->tpc, (&pregs->tpc)) ||
+ __put_user(cregs->tnpc, (&pregs->tnpc)) ||
+ __put_user(cregs->y, (&pregs->y))) {
+ pt_error_return(regs, EFAULT);
goto out;
- } else {
- struct pt_regs *pregs = (struct pt_regs *) addr;
- struct pt_regs *cregs = child->tss.kregs;
- int rval;
-
- if (__put_user(cregs->tstate, (&pregs->tstate)) ||
- __put_user(cregs->tpc, (&pregs->tpc)) ||
- __put_user(cregs->tnpc, (&pregs->tnpc)) ||
- __put_user(cregs->y, (&pregs->y))) {
+ }
+ 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;
}
- 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;
- }
- pt_succ_return(regs, 0);
+ pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
- printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
+ printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
- goto out;
- }
+ goto out;
+ }
- case PTRACE_SETREGS:
- if (current->tss.flags & SPARC_FLAG_32BIT) {
- struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
- struct pt_regs *cregs = child->tss.kregs;
- unsigned int psr, pc, npc, y;
- int i;
+ case PTRACE_SETREGS: {
+ struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
+ struct pt_regs *cregs = child->tss.kregs;
+ unsigned int psr, pc, npc, y;
+ int i;
- /* Must be careful, tracing process can only set certain
- * bits in the psr.
- */
- if (__get_user(psr, (&pregs->psr)) ||
- __get_user(pc, (&pregs->pc)) ||
- __get_user(npc, (&pregs->npc)) ||
- __get_user(y, (&pregs->y))) {
- pt_error_return(regs, EFAULT);
- goto out;
- }
- cregs->tstate &= ~(TSTATE_ICC);
- cregs->tstate |= psr_to_tstate_icc(psr);
- if(!((pc | npc) & 3)) {
- cregs->tpc = pc;
- cregs->tpc = npc;
- }
- cregs->y = y;
- 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;
- }
- pt_succ_return(regs, 0);
- goto out;
- } else {
- struct pt_regs *pregs = (struct pt_regs *) addr;
- struct pt_regs *cregs = child->tss.kregs;
- unsigned long tstate, tpc, tnpc, y;
- int i;
-
- /* Must be careful, tracing process can only set certain
- * bits in the psr.
- */
- if (__get_user(tstate, (&pregs->tstate)) ||
- __get_user(tpc, (&pregs->tpc)) ||
- __get_user(tnpc, (&pregs->tnpc)) ||
- __get_user(y, (&pregs->y))) {
- pt_error_return(regs, EFAULT);
- goto out;
- }
- tstate &= (TSTATE_ICC | TSTATE_XCC);
- cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
- cregs->tstate |= tstate;
- if(!((tpc | tnpc) & 3)) {
- cregs->tpc = tpc;
- cregs->tnpc = tnpc;
- }
- cregs->y = y;
- 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;
- }
- pt_succ_return(regs, 0);
+ /* Must be careful, tracing process can only set certain
+ * bits in the psr.
+ */
+ if (__get_user(psr, (&pregs->psr)) ||
+ __get_user(pc, (&pregs->pc)) ||
+ __get_user(npc, (&pregs->npc)) ||
+ __get_user(y, (&pregs->y))) {
+ pt_error_return(regs, EFAULT);
goto out;
}
-
- case PTRACE_GETFPREGS:
- if (current->tss.flags & SPARC_FLAG_32BIT) {
- struct fps {
- unsigned int regs[32];
- unsigned int fsr;
- unsigned int flags;
- unsigned int extra;
- unsigned int fpqd;
- struct fq {
- unsigned int insnaddr;
- unsigned int insn;
- } fpq[16];
- } *fps = (struct fps *) addr;
-
- if (copy_to_user(&fps->regs[0], &child->tss.float_regs[0], (32 * sizeof(unsigned int))) ||
- __put_user(child->tss.fsr, (&fps->fsr)) ||
- __put_user(0, (&fps->fpqd)) ||
- __put_user(0, (&fps->flags)) ||
- __put_user(0, (&fps->extra)) ||
- clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
+ cregs->tstate &= ~(TSTATE_ICC);
+ cregs->tstate |= psr_to_tstate_icc(psr);
+ if(!((pc | npc) & 3)) {
+ cregs->tpc = pc;
+ cregs->tpc = npc;
+ }
+ cregs->y = y;
+ 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;
}
- pt_succ_return(regs, 0);
- goto out;
- } else {
- struct fps {
- unsigned int regs[64];
- unsigned long fsr;
- } *fps = (struct fps *) addr;
+ pt_succ_return(regs, 0);
+ goto out;
+ }
- if (copy_to_user(&fps->regs[0], &child->tss.float_regs[0], (64 * sizeof(unsigned int))) ||
- __put_user(child->tss.fsr, (&fps->fsr))) {
+ case PTRACE_SETREGS64: {
+ struct pt_regs *pregs = (struct pt_regs *) addr;
+ struct pt_regs *cregs = child->tss.kregs;
+ unsigned long tstate, tpc, tnpc, y;
+ int i;
+
+ /* Must be careful, tracing process can only set certain
+ * bits in the psr.
+ */
+ if (__get_user(tstate, (&pregs->tstate)) ||
+ __get_user(tpc, (&pregs->tpc)) ||
+ __get_user(tnpc, (&pregs->tnpc)) ||
+ __get_user(y, (&pregs->y))) {
+ pt_error_return(regs, EFAULT);
+ goto out;
+ }
+ tstate &= (TSTATE_ICC | TSTATE_XCC);
+ cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+ cregs->tstate |= tstate;
+ if(!((tpc | tnpc) & 3)) {
+ cregs->tpc = tpc;
+ cregs->tnpc = tnpc;
+ }
+ cregs->y = y;
+ 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;
}
- pt_succ_return(regs, 0);
+ pt_succ_return(regs, 0);
+ goto out;
+ }
+
+ case PTRACE_GETFPREGS: {
+ struct fps {
+ unsigned int regs[32];
+ unsigned int fsr;
+ unsigned int flags;
+ unsigned int extra;
+ unsigned int fpqd;
+ struct fq {
+ unsigned int insnaddr;
+ unsigned int insn;
+ } fpq[16];
+ } *fps = (struct fps *) addr;
+ unsigned long *fpregs = (unsigned long *)(child->tss.kregs+1);
+
+ if (copy_to_user(&fps->regs[0], fpregs,
+ (32 * sizeof(unsigned int))) ||
+ __put_user(((unsigned int)fpregs[32]), (&fps->fsr)) ||
+ __put_user(0, (&fps->fpqd)) ||
+ __put_user(0, (&fps->flags)) ||
+ __put_user(0, (&fps->extra)) ||
+ clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
+ pt_error_return(regs, EFAULT);
goto out;
}
+ pt_succ_return(regs, 0);
+ goto out;
+ }
- case PTRACE_SETFPREGS:
- if (current->tss.flags & SPARC_FLAG_32BIT) {
- struct fps {
- unsigned int regs[32];
- unsigned int fsr;
- unsigned int flags;
- unsigned int extra;
- unsigned int fpqd;
- struct fq {
- unsigned int insnaddr;
- unsigned int insn;
- } fpq[16];
- } *fps = (struct fps *) addr;
- unsigned fsr;
+ case PTRACE_GETFPREGS64: {
+ struct fps {
+ unsigned int regs[64];
+ unsigned long fsr;
+ } *fps = (struct fps *) addr;
+ unsigned long *fpregs = (unsigned long *)(child->tss.kregs+1);
+
+ if (copy_to_user(&fps->regs[0], fpregs,
+ (64 * sizeof(unsigned int))) ||
+ __put_user(fpregs[32], (&fps->fsr))) {
+ pt_error_return(regs, EFAULT);
+ goto out;
+ }
+ pt_succ_return(regs, 0);
+ goto out;
+ }
- if (copy_from_user(&child->tss.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned int))) ||
- __get_user(fsr, (&fps->fsr))) {
- pt_error_return(regs, EFAULT);
- goto out;
- }
- child->tss.fsr &= 0xffffffff00000000UL;
- child->tss.fsr |= fsr;
- pt_succ_return(regs, 0);
+ case PTRACE_SETFPREGS: {
+ struct fps {
+ unsigned int regs[32];
+ unsigned int fsr;
+ unsigned int flags;
+ unsigned int extra;
+ unsigned int fpqd;
+ struct fq {
+ unsigned int insnaddr;
+ unsigned int insn;
+ } fpq[16];
+ } *fps = (struct fps *) addr;
+ unsigned long *fpregs = (unsigned long *)(child->tss.kregs+1);
+ unsigned fsr;
+
+ if (copy_from_user(fpregs, &fps->regs[0],
+ (32 * sizeof(unsigned int))) ||
+ __get_user(fsr, (&fps->fsr))) {
+ pt_error_return(regs, EFAULT);
goto out;
- } else {
- struct fps {
- unsigned int regs[64];
- unsigned long fsr;
- } *fps = (struct fps *) addr;
+ }
+ fpregs[32] &= 0xffffffff00000000UL;
+ fpregs[32] |= fsr;
+ pt_succ_return(regs, 0);
+ goto out;
+ }
- if (copy_from_user(&child->tss.float_regs[0], &fps->regs[0], (64 * sizeof(unsigned int))) ||
- __get_user(child->tss.fsr, (&fps->fsr))) {
- pt_error_return(regs, EFAULT);
- goto out;
- }
- pt_succ_return(regs, 0);
+ case PTRACE_SETFPREGS64: {
+ struct fps {
+ unsigned int regs[64];
+ unsigned long fsr;
+ } *fps = (struct fps *) addr;
+ unsigned long *fpregs = (unsigned long *)(child->tss.kregs+1);
+
+ if (copy_from_user(fpregs, &fps->regs[0],
+ (64 * sizeof(unsigned int))) ||
+ __get_user(fpregs[32], (&fps->fsr))) {
+ pt_error_return(regs, EFAULT);
goto out;
}
+ pt_succ_return(regs, 0);
+ goto out;
+ }
case PTRACE_READTEXT:
case PTRACE_READDATA: {
@@ -1022,7 +1067,10 @@
current->pid, current->exit_code);
#endif
if (current->exit_code) {
- set_bit(current->exit_code + 31, ¤t->signal);
+ /* spin_lock_irq(¤t->sigmask_lock); */
+ current->signal |= (1 << (current->exit_code - 1));
+ /* spin_unlock_irq(¤t->sigmask_lock); */
}
+
current->exit_code = 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov