Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 85948
b: refs/heads/master
c: 42086ce
h: refs/heads/master
v: v3
  • Loading branch information
Chris Zankel committed Feb 14, 2008
1 parent 989dd7e commit 9ada011
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bdd362ff4ff8dc0c697ce87dbb337f3b7341fc46
refs/heads/master: 42086cec3263b8c015ca3faa01e8190f0e3ff445
66 changes: 35 additions & 31 deletions trunk/arch/xtensa/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,61 +43,65 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs)
{
struct pt_regs *regs = task_pt_regs(child);
xtensa_gregset_t __user *gregset = uregs;
unsigned long wb = regs->windowbase;
unsigned long ws = regs->windowstart;
unsigned long wm = regs->wmask;
int ret = 0;
int live, last;
unsigned long wb = regs->windowbase;
int live, i;

if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
return -EIO;

/* Norm windowstart to a windowbase of 0. */

ws = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1);

ret |= __put_user(regs->pc, &gregset->pc);
ret |= __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
ret |= __put_user(regs->lbeg, &gregset->lbeg);
ret |= __put_user(regs->lend, &gregset->lend);
ret |= __put_user(regs->lcount, &gregset->lcount);
ret |= __put_user(ws, &gregset->windowstart);
__put_user(regs->pc, &gregset->pc);
__put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
__put_user(regs->lbeg, &gregset->lbeg);
__put_user(regs->lend, &gregset->lend);
__put_user(regs->lcount, &gregset->lcount);
__put_user(regs->windowstart, &gregset->windowstart);
__put_user(regs->windowbase, &gregset->windowbase);

live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
ret |= __copy_to_user(gregset->a, regs->areg, live * 4);
ret |= __copy_to_user(gregset->a + last, regs->areg + last, (wm>>4)*16);

return ret ? -EFAULT : 0;
for (i = 0; i < live; i++)
__put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++)
__put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));

return 0;
}

int ptrace_setregs(struct task_struct *child, void __user *uregs)
{
struct pt_regs *regs = task_pt_regs(child);
xtensa_gregset_t *gregset = uregs;
const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
unsigned long wm = regs->wmask;
unsigned long ps;
int ret = 0;
int live, last;
unsigned long wb;

if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
return -EIO;

ret |= __get_user(regs->pc, &gregset->pc);
ret |= __get_user(ps, &gregset->ps);
ret |= __get_user(regs->lbeg, &gregset->lbeg);
ret |= __get_user(regs->lend, &gregset->lend);
ret |= __get_user(regs->lcount, &gregset->lcount);
__get_user(regs->pc, &gregset->pc);
__get_user(ps, &gregset->ps);
__get_user(regs->lbeg, &gregset->lbeg);
__get_user(regs->lend, &gregset->lend);
__get_user(regs->lcount, &gregset->lcount);
__get_user(regs->windowstart, &gregset->windowstart);
__get_user(wb, &gregset->windowbase);

regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);

live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
ret |= __copy_from_user(regs->areg, gregset->a, live * 4);
ret |= __copy_from_user(regs->areg+last, gregset->a+last, (wm>>4)*16);
if (wb >= XCHAL_NUM_AREGS / 4)
return -EFAULT;

return ret ? -EFAULT : 0;
regs->windowbase = wb;

if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
gregset->a, wb * 16))
return -EFAULT;

if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16))
return -EFAULT;

return 0;
}


Expand Down
3 changes: 2 additions & 1 deletion trunk/include/asm-xtensa/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ typedef struct {
elf_greg_t lcount;
elf_greg_t sar;
elf_greg_t windowstart;
elf_greg_t reserved[9+48];
elf_greg_t windowbase;
elf_greg_t reserved[8+48];
elf_greg_t a[64];
} xtensa_gregset_t;

Expand Down

0 comments on commit 9ada011

Please sign in to comment.