From 1f0803c3661c319c82193194b78ff918739e682f Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 24 Dec 2017 15:07:10 +0000 Subject: [PATCH] syscall: rework subcall decoding on mips o32 Move syscall subcall handling to the same switch statement that handles ipc and socket subcalls. * linux/mips/syscallent-o32.h [LINUX_MIPSO32] (SYS_syscall_subcall): Define. * syscall.c (decode_mips_subcall): Rename to decode_syscall_subcall, conditionalize on SYS_syscall_subcall instead of LINUX_MIPSO32. (syscall_entering_decode) [LINUX_MIPSO32]: Remove. (syscall_entering_decode) [SYS_syscall_subcall]: Handle SEN_syscall using decode_syscall_subcall. --- linux/mips/syscallent-o32.h | 1 + syscall.c | 43 ++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/linux/mips/syscallent-o32.h b/linux/mips/syscallent-o32.h index 5ac79b5f..8e1d9c76 100644 --- a/linux/mips/syscallent-o32.h +++ b/linux/mips/syscallent-o32.h @@ -1,5 +1,6 @@ #if defined LINUX_MIPSO32 /* For an O32 strace, decode the o32 syscalls. */ +# define SYS_syscall_subcall 4000 [4000] = { MA, 0, SEN(syscall), "syscall" }, /* start of Linux o32 */ [4001] = { 1, TP|SE, SEN(exit), "exit" }, [4002] = { 0, TP, SEN(fork), "fork" }, diff --git a/syscall.c b/syscall.c index 420f5be9..7f914661 100644 --- a/syscall.c +++ b/syscall.c @@ -350,7 +350,7 @@ decode_socket_subcall(struct tcb *tcp) tcp->u_arg[i] = (sizeof(uint32_t) == current_wordsize) ? ((uint32_t *) (void *) buf)[i] : buf[i]; } -#endif +#endif /* SYS_socket_subcall */ #ifdef SYS_ipc_subcall static void @@ -390,11 +390,11 @@ decode_ipc_subcall(struct tcb *tcp) for (i = 0; i < n; i++) tcp->u_arg[i] = tcp->u_arg[i + 1]; } -#endif +#endif /* SYS_ipc_subcall */ -#ifdef LINUX_MIPSO32 +#ifdef SYS_syscall_subcall static void -decode_mips_subcall(struct tcb *tcp) +decode_syscall_subcall(struct tcb *tcp) { if (!scno_is_valid(tcp->u_arg[0])) return; @@ -403,6 +403,7 @@ decode_mips_subcall(struct tcb *tcp) tcp->s_ent = &sysent[tcp->scno]; memmove(&tcp->u_arg[0], &tcp->u_arg[1], sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0])); +# ifdef LINUX_MIPSO32 /* * Fetching the last arg of 7-arg syscalls (fadvise64_64 * and sync_file_range) requires additional code, @@ -415,8 +416,9 @@ decode_mips_subcall(struct tcb *tcp) &tcp->u_arg[MAX_ARGS - 1]) < 0) tcp->u_arg[MAX_ARGS - 1] = 0; } +# endif /* LINUX_MIPSO32 */ } -#endif /* LINUX_MIPSO32 */ +#endif /* SYS_syscall_subcall */ static void dumpio(struct tcb *tcp) @@ -628,23 +630,30 @@ syscall_entering_decode(struct tcb *tcp) return res; } -#ifdef LINUX_MIPSO32 - if (SEN_syscall == tcp->s_ent->sen) - decode_mips_subcall(tcp); -#endif - -#if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall) - switch (tcp->s_ent->sen) { -# ifdef SYS_socket_subcall - case SEN_socketcall: - decode_socket_subcall(tcp); - break; -# endif +#if defined SYS_ipc_subcall \ + || defined SYS_socket_subcall \ + || defined SYS_syscall_subcall + for (;;) { + switch (tcp->s_ent->sen) { # ifdef SYS_ipc_subcall case SEN_ipc: decode_ipc_subcall(tcp); break; # endif +# ifdef SYS_socket_subcall + case SEN_socketcall: + decode_socket_subcall(tcp); + break; +# endif +# ifdef SYS_syscall_subcall + case SEN_syscall: + decode_syscall_subcall(tcp); + if (tcp->s_ent->sen != SEN_syscall) + continue; + break; +# endif + } + break; } #endif