1 /*
2 * Copyright (c) 2003 Russell King <rmk@arm.linux.org.uk>
3 * Copyright (c) 2011-2013 Denys Vlasenko <vda.linux@googlemail.com>
4 * Copyright (c) 2011-2015 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2015-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: LGPL-2.1-or-later
9 */
10
11 /* Return codes: 1 - ok, 0 - ignore, other - error. */
12 static int
13 arch_get_scno(struct tcb *tcp)
14 {
15 kernel_ulong_t scno = 0;
16
17 /* Note: we support only 32-bit CPUs, not 26-bit */
18
19 #if !defined(__ARM_EABI__) || ENABLE_ARM_OABI
20 if (arm_regs.ARM_cpsr & 0x20) {
21 /* Thumb mode */
22 goto scno_in_r7;
23 }
24 /* ARM mode */
25 /* Check EABI/OABI by examining SVC insn's low 24 bits */
26 errno = 0;
27 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
28 if (errno)
29 return -1;
30 /* EABI syscall convention? */
31 if (scno != 0xef000000) {
32 /* No, it's OABI */
33 if ((scno & 0x0ff00000) != 0x0f900000) {
34 error_msg("pid %d unknown syscall trap 0x%08lx",
35 tcp->pid, scno);
36 return -1;
37 }
38 /* Fixup the syscall number */
39 scno &= 0x000fffff;
40 } else {
41 scno_in_r7:
42 scno = arm_regs.ARM_r7;
43 }
44 #else /* __ARM_EABI__ || !ENABLE_ARM_OABI */
45
46 scno = arm_regs.ARM_r7;
47
48 #endif
49
50 /*
51 * Do some sanity checks to figure out
52 * whether it's really a syscall entry.
53 */
54 if (arm_regs.ARM_ip && !scno_in_range(scno)) {
55 debug_msg("pid %d stray syscall exit: ARM_ip = %ld, scno = %ld",
56 tcp->pid, arm_regs.ARM_ip, scno);
57 return 0;
58 }
59
60 tcp->scno = scno;
61 return 1;
62 }