{ uoff(regs), "offsetof(struct user, regs)" },
{ uoff(fpu), "offsetof(struct user, fpu)" },
#endif
+#ifdef ARM
+ { uoff(regs.ARM_r0), "r0" },
+ { uoff(regs.ARM_r1), "r1" },
+ { uoff(regs.ARM_r2), "r2" },
+ { uoff(regs.ARM_r3), "r3" },
+ { uoff(regs.ARM_r4), "r4" },
+ { uoff(regs.ARM_r5), "r5" },
+ { uoff(regs.ARM_r6), "r6" },
+ { uoff(regs.ARM_r7), "r7" },
+ { uoff(regs.ARM_r8), "r8" },
+ { uoff(regs.ARM_r9), "r9" },
+ { uoff(regs.ARM_r10), "r10" },
+ { uoff(regs.ARM_fp), "fp" },
+ { uoff(regs.ARM_ip), "ip" },
+ { uoff(regs.ARM_sp), "sp" },
+ { uoff(regs.ARM_lr), "lr" },
+ { uoff(regs.ARM_pc), "pc" },
+ { uoff(regs.ARM_cpsr), "cpsr" },
+#endif
#if !defined(S390) && !defined(S390X) && !defined(MIPS)
{ uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
sys_sigreturn(tcp)
struct tcb *tcp;
{
-#if defined(S390) || defined(S390X)
- long usp;
- struct sigcontext_struct sc;
-
- if (entering(tcp)) {
- tcp->u_arg[0] = 0;
- if (upeek(tcp->pid,PT_GPR15,&usp)<0)
- return 0;
- if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
- return 0;
- tcp->u_arg[0] = 1;
- memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
- } else {
- tcp->u_rval = tcp->u_error = 0;
- if (tcp->u_arg[0] == 0)
- return 0;
- tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
- return RVAL_NONE | RVAL_STR;
- }
- return 0;
+#ifdef ARM
+ struct pt_regs regs;
+ struct sigcontext_struct sc;
+
+ if (entering(tcp)) {
+ tcp->u_arg[0] = 0;
+
+ if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
+ return 0;
+
+ if (umove(tcp, regs.ARM_sp, &sc) < 0)
+ return 0;
+
+ tcp->u_arg[0] = 1;
+ tcp->u_arg[1] = sc.oldmask;
+ } else {
+ sigset_t sigm;
+ long_to_sigset(tcp->u_arg[1], &sigm);
+ tcp->u_rval = tcp->u_error = 0;
+ if (tcp->u_arg[0] == 0)
+ return 0;
+ tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
+ return RVAL_NONE | RVAL_STR;
+ }
+ return 0;
+#elif defined(S390) || defined(S390X)
+ long usp;
+ struct sigcontext_struct sc;
+
+ if (entering(tcp)) {
+ tcp->u_arg[0] = 0;
+ if (upeek(tcp->pid,PT_GPR15,&usp)<0)
+ return 0;
+ if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
+ return 0;
+ tcp->u_arg[0] = 1;
+ memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
+ } else {
+ tcp->u_rval = tcp->u_error = 0;
+ if (tcp->u_arg[0] == 0)
+ return 0;
+ tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
+ return RVAL_NONE | RVAL_STR;
+ }
+ return 0;
#else
#ifdef I386
long esp;
return 0;
#else /* !IA64 */
#ifdef POWERPC
- long esp;
- struct sigcontext_struct sc;
-
- if (entering(tcp)) {
- tcp->u_arg[0] = 0;
- if (upeek(tcp->pid, sizeof(unsigned long)*PT_R1, &esp) < 0)
- return 0;
- if (umove(tcp, esp, &sc) < 0)
- return 0;
- tcp->u_arg[0] = 1;
- tcp->u_arg[1] = sc.oldmask;
- }
- else {
- sigset_t sigm;
- long_to_sigset(tcp->u_arg[1], &sigm);
- tcp->u_rval = tcp->u_error = 0;
- if (tcp->u_arg[0] == 0)
- return 0;
- tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
- return RVAL_NONE | RVAL_STR;
- }
- return 0;
+ long esp;
+ struct sigcontext_struct sc;
+
+ if (entering(tcp)) {
+ tcp->u_arg[0] = 0;
+ if (upeek(tcp->pid, sizeof(unsigned long)*PT_R1, &esp) < 0)
+ return 0;
+ if (umove(tcp, esp, &sc) < 0)
+ return 0;
+ tcp->u_arg[0] = 1;
+ tcp->u_arg[1] = sc.oldmask;
+ }
+ else {
+ sigset_t sigm;
+ long_to_sigset(tcp->u_arg[1], &sigm);
+ tcp->u_rval = tcp->u_error = 0;
+ if (tcp->u_arg[0] == 0)
+ return 0;
+ tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
+ return RVAL_NONE | RVAL_STR;
+ }
+ return 0;
#else /* !POWERPC */
#ifdef M68K
long usp;
struct sigcontext sc;
if (entering(tcp)) {
- tcp->u_arg[0] = 0;
- if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
+ tcp->u_arg[0] = 0;
+ if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
return 0;
- if (umove(tcp, usp, &sc) < 0)
+ if (umove(tcp, usp, &sc) < 0)
return 0;
- tcp->u_arg[0] = 1;
- tcp->u_arg[1] = sc.sc_mask;
+ tcp->u_arg[0] = 1;
+ tcp->u_arg[1] = sc.sc_mask;
}
else {
- sigset_t sigm;
- long_to_sigset(tcp->u_arg[1], &sigm);
- tcp->u_rval = tcp->u_error = 0;
- if (tcp->u_arg[0] == 0)
+ sigset_t sigm;
+ long_to_sigset(tcp->u_arg[1], &sigm);
+ tcp->u_rval = tcp->u_error = 0;
+ if (tcp->u_arg[0] == 0)
return 0;
- tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
- return RVAL_NONE | RVAL_STR;
+ tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
+ return RVAL_NONE | RVAL_STR;
}
return 0;
#else /* !M68K */
struct sigcontext_struct sc;
if (entering(tcp)) {
- tcp->u_arg[0] = 0;
- if (upeek(tcp->pid, REG_FP, &fp) < 0)
+ tcp->u_arg[0] = 0;
+ if (upeek(tcp->pid, REG_FP, &fp) < 0)
return 0;
- if (umove(tcp, fp, &sc) < 0)
+ if (umove(tcp, fp, &sc) < 0)
return 0;
- tcp->u_arg[0] = 1;
- tcp->u_arg[1] = sc.sc_mask;
+ tcp->u_arg[0] = 1;
+ tcp->u_arg[1] = sc.sc_mask;
}
else {
- sigset_t sigm;
- long_to_sigset(tcp->u_arg[1], &sigm);
- tcp->u_rval = tcp->u_error = 0;
- if (tcp->u_arg[0] == 0)
+ sigset_t sigm;
+ long_to_sigset(tcp->u_arg[1], &sigm);
+ tcp->u_rval = tcp->u_error = 0;
+ if (tcp->u_arg[0] == 0)
return 0;
- tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
- return RVAL_NONE | RVAL_STR;
+ tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
+ return RVAL_NONE | RVAL_STR;
}
return 0;
#else
m_siginfo_t si;
if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
- perror("sigreturn: PTRACE_GETREGS ");
- return 0;
+ perror("sigreturn: PTRACE_GETREGS ");
+ return 0;
}
if(entering(tcp)) {
tcp->u_arg[0] = 0;
#elif defined (M68K)
static int d0;
#elif defined (ARM)
- static int r0;
+ static struct pt_regs regs;
#elif defined (ALPHA)
static long r0;
static long a3;
#elif defined(SH)
static long r0;
#elif defined(SHMEDIA)
- static long r9;
+ static long r9;
#elif defined(X86_64)
static long rax;
#endif
return -1;
}
#elif defined (ARM)
- {
- long pc;
- upeek(pid, 4*15, &pc);
- umoven(tcp, pc-4, 4, (char *)&scno);
- scno &= 0x000fffff;
+ /*
+ * Read complete register set in one go.
+ */
+ if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s) == -1)
+ return -1;
+
+ /*
+ * We only need to grab the syscall number on syscall entry.
+ */
+ if (regs.ARM_ip == 0) {
+ /*
+ * Note: we only deal with only 32-bit CPUs here.
+ */
+ if (regs.ARM_cpsr & 0x20) {
+ /*
+ * Get the Thumb-mode system call number
+ */
+ scno = regs.ARM_r7;
+ } else {
+ /*
+ * Get the ARM-mode system call number
+ */
+ errno = 0;
+ scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
+ if (errno)
+ return -1;
+
+ if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+
+ if ((scno & 0x0ff00000) != 0x0f900000) {
+ fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
+ scno);
+ return -1;
+ }
+
+ /*
+ * Fixup the syscall number
+ */
+ scno &= 0x000fffff;
+ }
+
+ if (tcp->flags & TCB_INSYSCALL) {
+ fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
+ tcp->flags &= ~TCB_INSYSCALL;
+ }
+ } else {
+ if (!(tcp->flags & TCB_INSYSCALL)) {
+ fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
+ tcp->flags |= TCB_INSYSCALL;
+ }
}
#elif defined (M68K)
if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
return 0;
}
#elif defined (ARM)
- if (upeek(pid, 4*0, (long *)&r0) < 0)
- return -1;
- if ( 0 && r0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
- if (debug)
- fprintf(stderr, "stray syscall exit: d0 = %ld\n", r0);
- return 0;
- }
+ /*
+ * Nothing required
+ */
#elif defined (HPPA)
if (upeek(pid, PT_GR28, &r28) < 0)
return -1;
}
#else /* !M68K */
#ifdef ARM
- if (r0 && (unsigned) -r0 < nerrnos) {
+ if (regs.ARM_r0 && (unsigned) -regs.ARM_r0 < nerrnos) {
tcp->u_rval = -1;
- u_error = -r0;
+ u_error = -regs.ARM_r0;
}
else {
- tcp->u_rval = r0;
+ tcp->u_rval = regs.ARM_r0;
u_error = 0;
}
#else /* !ARM */
return -1;
}
}
+#elif defined(ARM)
+ {
+ int i;
+
+ if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+ tcp->u_nargs = sysent[tcp->scno].nargs;
+ else
+ tcp->u_nargs = MAX_ARGS;
+ for (i = 0; i < tcp->u_nargs; i++)
+ tcp->u_arg[i] = regs.uregs[i];
+ }
#elif defined(SH)
{
int i;