+ /*
+ * 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;
+ }