in kernel/ptrace.c [72:130]
static int genregs_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
int ret;
unsigned long bucket;
struct pt_regs *regs = task_pt_regs(target);
if (!regs)
return -EIO;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
®s->r00, 0, 32*sizeof(unsigned long));
#define INEXT(KPT_REG, USR_REG) \
if (!ret) \
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, \
KPT_REG, offsetof(struct user_regs_struct, USR_REG), \
offsetof(struct user_regs_struct, USR_REG) + \
sizeof(unsigned long));
/* Must be exactly same sequence as struct user_regs_struct */
INEXT(®s->sa0, sa0);
INEXT(®s->lc0, lc0);
INEXT(®s->sa1, sa1);
INEXT(®s->lc1, lc1);
INEXT(®s->m0, m0);
INEXT(®s->m1, m1);
INEXT(®s->usr, usr);
INEXT(®s->preds, p3_0);
INEXT(®s->gp, gp);
INEXT(®s->ugp, ugp);
INEXT(&pt_elr(regs), pc);
/* CAUSE and BADVA aren't writeable. */
INEXT(&bucket, cause);
INEXT(&bucket, badva);
#if CONFIG_HEXAGON_ARCH_VERSION >=4
INEXT(®s->cs0, cs0);
INEXT(®s->cs1, cs1);
#endif
/* Ignore the rest, if needed */
if (!ret)
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
offsetof(struct user_regs_struct, pad1), -1);
if (ret)
return ret;
/*
* This is special; SP is actually restored by the VM via the
* special event record which is set by the special trap.
*/
regs->hvmer.vmpsp = regs->r29;
return 0;
}