blob: d9b6ffc51a3e39dcadedafca17da73bebb4df94f [file] [log] [blame]
Dmitry V. Levin16510512015-11-30 01:46:52 +00001/* Return codes: 1 - ok, 0 - ignore, other - error. */
2static int
3arch_get_scno(struct tcb *tcp)
4{
5 long scno = 0;
6
7 /* Note: we support only 32-bit CPUs, not 26-bit */
Dmitry V. Levind70d1c42015-03-22 22:13:55 +00008
9#if !defined(__ARM_EABI__) || ENABLE_ARM_OABI
Dmitry V. Levin16510512015-11-30 01:46:52 +000010 if (arm_regs.ARM_cpsr & 0x20) {
11 /* Thumb mode */
12 goto scno_in_r7;
Dmitry V. Levind70d1c42015-03-22 22:13:55 +000013 }
Dmitry V. Levin16510512015-11-30 01:46:52 +000014 /* ARM mode */
15 /* Check EABI/OABI by examining SVC insn's low 24 bits */
16 errno = 0;
17 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
18 if (errno)
19 return -1;
20 /* EABI syscall convention? */
21 if ((unsigned long) scno != 0xef000000) {
22 /* No, it's OABI */
23 if ((scno & 0x0ff00000) != 0x0f900000) {
24 error_msg("pid %d unknown syscall trap 0x%08lx",
25 tcp->pid, scno);
26 return -1;
27 }
28 /* Fixup the syscall number */
29 scno &= 0x000fffff;
30 } else {
31 scno_in_r7:
32 scno = arm_regs.ARM_r7;
33 }
Dmitry V. Levind70d1c42015-03-22 22:13:55 +000034#else /* __ARM_EABI__ || !ENABLE_ARM_OABI */
35
Dmitry V. Levin16510512015-11-30 01:46:52 +000036 scno = arm_regs.ARM_r7;
Dmitry V. Levind70d1c42015-03-22 22:13:55 +000037
38#endif
39
Dmitry V. Levin16510512015-11-30 01:46:52 +000040 scno = shuffle_scno(scno);
Dmitry V. Levin9945ec92015-03-23 23:00:37 +000041
Dmitry V. Levin16510512015-11-30 01:46:52 +000042 /*
43 * Do some sanity checks to figure out
44 * whether it's really a syscall entry.
45 */
46 if (arm_regs.ARM_ip && !SCNO_IN_RANGE(scno)) {
47 if (debug_flag)
48 error_msg("pid %d stray syscall exit:"
49 " ARM_ip = %ld, scno = %ld",
50 tcp->pid, arm_regs.ARM_ip,
51 shuffle_scno(scno));
52 return 0;
53 }
54
55 tcp->scno = scno;
56 return 1;
Dmitry V. Levin9945ec92015-03-23 23:00:37 +000057}