in kernel/ptrace.c [1530:1571]
static void do_gpregs_set(struct unw_frame_info *info, void *arg)
{
struct regset_getset *dst = arg;
if (unw_unwind_to_user(info) < 0)
return;
if (!dst->count)
return;
/* Skip r0 */
if (dst->pos < ELF_GR_OFFSET(1)) {
dst->ret = user_regset_copyin_ignore(&dst->pos, &dst->count,
&dst->u.set.kbuf,
&dst->u.set.ubuf,
0, ELF_GR_OFFSET(1));
if (dst->ret)
return;
}
while (dst->count && dst->pos < ELF_AR_END_OFFSET) {
unsigned int n, from, to;
elf_greg_t tmp[16];
from = dst->pos;
to = from + sizeof(tmp);
if (to > ELF_AR_END_OFFSET)
to = ELF_AR_END_OFFSET;
/* get up to 16 values */
dst->ret = user_regset_copyin(&dst->pos, &dst->count,
&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
from, to);
if (dst->ret)
return;
/* now copy them into registers */
for (n = 0; from < dst->pos; from += sizeof(elf_greg_t), n++)
if (access_elf_reg(dst->target, info, from,
&tmp[n], 1) < 0) {
dst->ret = -EIO;
return;
}
}
}