summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2013-07-04 09:54:19 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2013-07-04 09:54:19 +0200
commit8b7aa2b35d40836d376990f0e5eaf473b70bc26d (patch)
tree3295c9438a3d57dc5815877f52794d45f0f23be1 /syscall.c
parent6162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1 (diff)
downloadstrace-8b7aa2b35d40836d376990f0e5eaf473b70bc26d.tar.gz
strace-8b7aa2b35d40836d376990f0e5eaf473b70bc26d.tar.bz2
strace-8b7aa2b35d40836d376990f0e5eaf473b70bc26d.tar.xz
ARM: add STRACE_KNOWS_ONLY_EABI define which can be used to omit OABI support
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/syscall.c b/syscall.c
index 1ccee6e..af9c2a0 100644
--- a/syscall.c
+++ b/syscall.c
@@ -1339,6 +1339,7 @@ get_scno(struct tcb *tcp)
break;
case sizeof(arm_regs):
/* We are in 32-bit mode */
+ /* Note: we don't support OABI, unlike 32-bit ARM build */
scno = arm_regs.ARM_r7;
update_personality(tcp, 0);
break;
@@ -1352,30 +1353,34 @@ get_scno(struct tcb *tcp)
}
/* Note: we support only 32-bit CPUs, not 26-bit */
- if (arm_regs.ARM_cpsr & 0x20) {
+# ifndef STRACE_KNOWS_ONLY_EABI
+# warning STRACE_KNOWS_ONLY_EABI not set, will PTRACE_PEEKTEXT on every syscall (slower tracing)
+ 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)
+ goto scno_in_r7;
+ /* ARM mode */
+ /* Check EABI/OABI by examining SVC insn's low 24 bits */
+ 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) {
+ /* No, it's OABI */
+ if ((scno & 0x0ff00000) != 0x0f900000) {
+ fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n",
+ tcp->pid, scno);
return -1;
-
- /* EABI syscall convention? */
- if (scno == 0xef000000) {
- scno = arm_regs.ARM_r7; /* yes */
- } else {
- if ((scno & 0x0ff00000) != 0x0f900000) {
- fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n",
- tcp->pid, scno);
- return -1;
- }
- /* Fixup the syscall number */
- scno &= 0x000fffff;
}
+ /* Fixup the syscall number */
+ scno &= 0x000fffff;
+ } else {
+ scno_in_r7:
+ scno = arm_regs.ARM_r7;
}
-
+# else
+ scno = arm_regs.ARM_r7;
+# endif
scno = shuffle_scno(scno);
#elif defined(M68K)
if (upeek(tcp->pid, 4*PT_ORIG_D0, &scno) < 0)