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 | |
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>
-rw-r--r-- | linux/arm/signalent1.h | 2 | ||||
-rw-r--r-- | linux/arm/syscallent.h | 4 | ||||
-rw-r--r-- | syscall.c | 80 |
3 files changed, 35 insertions, 51 deletions
diff --git a/linux/arm/signalent1.h b/linux/arm/signalent1.h index c927d72..130972b 100644 --- a/linux/arm/signalent1.h +++ b/linux/arm/signalent1.h @@ -1,2 +1,2 @@ -/* i386 personality */ +/* "ARM specific syscall" personality */ #include "../signalent.h" diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h index e3de1f5..53c01a8 100644 --- a/linux/arm/syscallent.h +++ b/linux/arm/syscallent.h @@ -406,6 +406,8 @@ { 2, TD, sys_setns, "setns" }, /* 375 */ { 6, 0, sys_process_vm_readv, "process_vm_readv" }, /* 376 */ { 6, 0, sys_process_vm_writev, "process_vm_writev" }, /* 377 */ + +#ifndef __ARM_EABI__ { 5, 0, NULL, NULL }, /* 378 */ { 5, 0, NULL, NULL }, /* 379 */ { 5, 0, NULL, NULL }, /* 380 */ @@ -428,8 +430,6 @@ { 5, 0, NULL, NULL }, /* 397 */ { 5, 0, NULL, NULL }, /* 398 */ { 5, 0, NULL, NULL }, /* 399 */ - -#ifndef __ARM_EABI__ #if SYS_socket_subcall != 400 #error fix me #endif @@ -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) |