if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(®s, 1);
+
+ if (test_thread_flag(TIF_SINGLESTEP)) {
+ force_sig(SIGTRAP, current); /* XXX */
+ tracehook_report_syscall_step(®s);
+ }
}
return do_regset_call(do_gpregs_set, target, regset, pos, count, kbuf, ubuf);
}
+static void do_gpregs_writeback(struct unw_frame_info *info, void *arg)
+{
+ struct pt_regs *pt;
+ utrace_getset_t *dst = arg;
+ unsigned long urbs_end;
+
+ if (unw_unwind_to_user(info) < 0)
+ return;
+ pt = task_pt_regs(dst->target);
+ urbs_end = ia64_get_user_rbs_end(dst->target, pt, NULL);
+ dst->ret = ia64_sync_user_rbs(dst->target, info->sw, pt->ar_bspstore, urbs_end);
+}
/*
* This is called to write back the register backing store.
* ptrace does this before it stops, so that a tracer reading the user
const struct utrace_regset *regset,
int now)
{
- unsigned long urbs_end, cfm;
- struct pt_regs *pt = task_pt_regs(target);
- struct switch_stack *sw = (void *) (target->thread.ksp + 16);
- urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
- return ia64_sync_user_rbs(target, sw, pt->ar_bspstore, urbs_end);
+ return do_regset_call(do_gpregs_writeback, target, regset, 0, 0, NULL, NULL);
}
static int
const struct utrace_regset_view utrace_ia64_native = {
.name = "ia64",
.e_machine = EM_IA_64,
- .regsets = native_regsets,
- .n = sizeof native_regsets / sizeof native_regsets[0],
+ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
};
EXPORT_SYMBOL_GPL(utrace_ia64_native);
offsetof(struct pt_all_user_regs, member), \
offsetof(struct pt_all_user_regs, member) + num * sizeof(long)
static const struct ptrace_layout_segment pt_all_user_regs_layout[] = {
- {WORD(nat, 1), 0, ELF_NAT_OFFSET},
- {WORD(cr_iip, 1), 0, ELF_CR_IIP_OFFSET},
- {WORD(cfm, 1), 0, ELF_CFM_OFFSET},
- {WORD(cr_ipsr, 1), 0, ELF_CR_IPSR_OFFSET},
- {WORD(pr, 1), 0, ELF_PR_OFFSET},
- {WORD(gr[0], 32), 0, ELF_GR_OFFSET(0)},
- {WORD(br[0], 8), 0, ELF_BR_OFFSET(0)},
- {WORD(ar[PT_AUR_RSC], 4), 0, ELF_AR_RSC_OFFSET},
- {WORD(ar[PT_AUR_CCV], 1), 0, ELF_AR_CCV_OFFSET},
- {WORD(ar[PT_AUR_UNAT], 1), 0, ELF_AR_UNAT_OFFSET},
- {WORD(ar[PT_AUR_FPSR], 1), 0, ELF_AR_FPSR_OFFSET},
- {WORD(ar[PT_AUR_PFS], 3), 0, ELF_AR_PFS_OFFSET},
+ {WORD(nat, 1), 0, ELF_NAT_OFFSET},
+ {WORD(cr_iip, 1), 0, ELF_CR_IIP_OFFSET},
+ {WORD(cfm, 1), 0, ELF_CFM_OFFSET},
+ {WORD(cr_ipsr, 1), 0, ELF_CR_IPSR_OFFSET},
+ {WORD(pr, 1), 0, ELF_PR_OFFSET},
+ {WORD(gr[0], 1), -1, -1},
+ {WORD(gr[1], 31), 0, ELF_GR_OFFSET(1)},
+ {WORD(br[0], 8), 0, ELF_BR_OFFSET(0)},
+ {WORD(ar[0], 16), -1, -1},
+ {WORD(ar[PT_AUR_RSC], 4), 0, ELF_AR_RSC_OFFSET},
+ {WORD(ar[PT_AUR_RNAT+1], 12), -1, -1},
+ {WORD(ar[PT_AUR_CCV], 1), 0, ELF_AR_CCV_OFFSET},
+ {WORD(ar[PT_AUR_CCV+1], 3), -1, -1},
+ {WORD(ar[PT_AUR_UNAT], 1), 0, ELF_AR_UNAT_OFFSET},
+ {WORD(ar[PT_AUR_UNAT+1], 3), -1, -1},
+ {WORD(ar[PT_AUR_FPSR], 1), 0, ELF_AR_FPSR_OFFSET},
+ {WORD(ar[PT_AUR_FPSR+1], 23), -1, -1},
+ {WORD(ar[PT_AUR_PFS], 3), 0, ELF_AR_PFS_OFFSET},
+ {WORD(ar[PT_AUR_EC+1], 62), -1, -1},
{offsetof(struct pt_all_user_regs, fr[0]),
+ offsetof(struct pt_all_user_regs, fr[2]),
+ -1, -1},
+ {offsetof(struct pt_all_user_regs, fr[2]),
offsetof(struct pt_all_user_regs, fr[128]),
- 1, 0},
+ 1, 2 * sizeof(elf_fpreg_t)},
{0, 0, -1, 0}
};
#undef WORD
};
#undef NEXT
-fastcall int arch_ptrace(long *request, struct task_struct *child,
- struct utrace_attached_engine *engine,
- unsigned long addr, unsigned long data, long *val)
+int arch_ptrace(long *request, struct task_struct *child,
+ struct utrace_attached_engine *engine,
+ unsigned long addr, unsigned long data, long *val)
{
int ret = -ENOSYS;
switch (*request) {