|
@@ -167,6 +167,9 @@ long arch_ptrace(struct task_struct *child, long request,
|
|
|
if ((addr & (sizeof(unsigned long)-1)) ||
|
|
if ((addr & (sizeof(unsigned long)-1)) ||
|
|
|
addr >= sizeof(struct pt_regs))
|
|
addr >= sizeof(struct pt_regs))
|
|
|
break;
|
|
break;
|
|
|
|
|
+ if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
|
|
|
|
|
+ data |= 3; /* ensure userspace privilege */
|
|
|
|
|
+ }
|
|
|
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
|
|
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
|
|
|
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
|
|
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
|
|
|
(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
|
|
(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
|
|
@@ -228,16 +231,18 @@ long arch_ptrace(struct task_struct *child, long request,
|
|
|
|
|
|
|
|
static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
|
|
static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
|
|
|
{
|
|
{
|
|
|
- if (offset < 0)
|
|
|
|
|
- return sizeof(struct pt_regs);
|
|
|
|
|
- else if (offset <= 32*4) /* gr[0..31] */
|
|
|
|
|
- return offset * 2 + 4;
|
|
|
|
|
- else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
|
|
|
|
|
- return offset + 32*4;
|
|
|
|
|
- else if (offset < sizeof(struct pt_regs)/2 + 32*4)
|
|
|
|
|
- return offset * 2 + 4 - 32*8;
|
|
|
|
|
|
|
+ compat_ulong_t pos;
|
|
|
|
|
+
|
|
|
|
|
+ if (offset < 32*4) /* gr[0..31] */
|
|
|
|
|
+ pos = offset * 2 + 4;
|
|
|
|
|
+ else if (offset < 32*4+32*8) /* fr[0] ... fr[31] */
|
|
|
|
|
+ pos = (offset - 32*4) + PT_FR0;
|
|
|
|
|
+ else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
|
|
|
|
|
+ pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
|
|
|
else
|
|
else
|
|
|
- return sizeof(struct pt_regs);
|
|
|
|
|
|
|
+ pos = sizeof(struct pt_regs);
|
|
|
|
|
+
|
|
|
|
|
+ return pos;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|
@@ -281,9 +286,12 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|
|
addr = translate_usr_offset(addr);
|
|
addr = translate_usr_offset(addr);
|
|
|
if (addr >= sizeof(struct pt_regs))
|
|
if (addr >= sizeof(struct pt_regs))
|
|
|
break;
|
|
break;
|
|
|
|
|
+ if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
|
|
|
|
|
+ data |= 3; /* ensure userspace privilege */
|
|
|
|
|
+ }
|
|
|
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
|
|
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
|
|
|
/* Special case, fp regs are 64 bits anyway */
|
|
/* Special case, fp regs are 64 bits anyway */
|
|
|
- *(__u64 *) ((char *) task_regs(child) + addr) = data;
|
|
|
|
|
|
|
+ *(__u32 *) ((char *) task_regs(child) + addr) = data;
|
|
|
ret = 0;
|
|
ret = 0;
|
|
|
}
|
|
}
|
|
|
else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
|
|
else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
|