diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-20 18:08:25 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-20 18:08:25 +0100 |
commit | e7030e5a7ef541f0ffda46a2850ef720245f01a5 (patch) | |
tree | 2e4f1e4c896a8c59db70ec44bfc5f6ff110072e0 /syscall.c | |
parent | 4bfb198db17d9a6b83f104d4f1e184664db78391 (diff) | |
download | strace-e7030e5a7ef541f0ffda46a2850ef720245f01a5.tar.gz strace-e7030e5a7ef541f0ffda46a2850ef720245f01a5.tar.bz2 strace-e7030e5a7ef541f0ffda46a2850ef720245f01a5.tar.xz |
arm: shorten syscall table for EABI - no point in storing NULL entries
Also, reformatted ARM code in get_scno(), mostly improved comments,
without code changes.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'syscall.c')
-rw-r--r-- | syscall.c | 80 |
1 files changed, 32 insertions, 48 deletions
@@ -1215,59 +1215,43 @@ get_scno(struct tcb *tcp) break; } #elif defined(ARM) - /* - * We only need to grab the syscall number on syscall entry. - */ - if (arm_regs.ARM_ip == 0) { - /* - * Note: we only deal with 32-bit CPUs here - */ - if (arm_regs.ARM_cpsr & 0x20) { - /* - * Get the Thumb-mode system call number - */ - scno = arm_regs.ARM_r7; + if (arm_regs.ARM_ip != 0) { + /* It is not a syscall entry */ + fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid); + tcp->flags |= TCB_INSYSCALL; + return 0; + } + /* Note: we support only 32-bit CPUs, not 26-bit */ + + if (arm_regs.ARM_cpsr & 0x20) { + /* Thumb mode */ + scno = arm_regs.ARM_r7; + } else { + /* ARM mode */ + errno = 0; + scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL); + if (errno) + return -1; + + /* EABI syscall convention? */ + if (scno == 0xef000000) { + scno = arm_regs.ARM_r7; /* yes */ } else { - /* - * Get the ARM-mode system call number - */ - errno = 0; - scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL); - if (errno) + if ((scno & 0x0ff00000) != 0x0f900000) { + fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n", + tcp->pid, scno); return -1; - - /* Handle the EABI syscall convention. We do not - bother converting structures between the two - ABIs, but basic functionality should work even - if strace and the traced program have different - ABIs. */ - if (scno == 0xef000000) { - scno = arm_regs.ARM_r7; - } else { - if ((scno & 0x0ff00000) != 0x0f900000) { - fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n", - scno); - return -1; - } - - /* - * Fixup the syscall number - */ - scno &= 0x000fffff; } + /* Fixup the syscall number */ + scno &= 0x000fffff; } - if (scno & 0x0f0000) { - /* - * Handle ARM specific syscall - */ - update_personality(tcp, 1); - scno &= 0x0000ffff; - } else - update_personality(tcp, 0); - + } + if (scno & 0x000f0000) { + /* ARM specific syscall. We handle it as a separate "personality" */ + update_personality(tcp, 1); + scno &= 0x0000ffff; } else { - fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid); - tcp->flags |= TCB_INSYSCALL; + update_personality(tcp, 0); } #elif defined(M68K) if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0) |