fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ia64 / kernel / ptrace.c
index 1a25131..370b51b 100644 (file)
@@ -763,6 +763,11 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
 
        if (test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall(&regs, 1);
+
+       if (test_thread_flag(TIF_SINGLESTEP)) {
+               force_sig(SIGTRAP, current); /* XXX */
+               tracehook_report_syscall_step(&regs);
+       }
 }
 
 
@@ -1389,6 +1394,18 @@ static int gpregs_set(struct task_struct *target,
        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
@@ -1399,11 +1416,7 @@ gpregs_writeback(struct task_struct *target,
                 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
@@ -1535,8 +1548,7 @@ static const struct utrace_regset native_regsets[] = {
 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);
 
@@ -1549,21 +1561,31 @@ 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
@@ -1604,9 +1626,9 @@ static const struct ptrace_layout_segment pt_uarea_layout[] = {
 };
 #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) {