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.
This commit is contained in:
Дмитрий Левин 2017-12-24 15:07:10 +00:00
parent 660f100099
commit 1f0803c366
2 changed files with 27 additions and 17 deletions

View File

@ -1,5 +1,6 @@
#if defined LINUX_MIPSO32 #if defined LINUX_MIPSO32
/* For an O32 strace, decode the o32 syscalls. */ /* For an O32 strace, decode the o32 syscalls. */
# define SYS_syscall_subcall 4000
[4000] = { MA, 0, SEN(syscall), "syscall" }, /* start of Linux o32 */ [4000] = { MA, 0, SEN(syscall), "syscall" }, /* start of Linux o32 */
[4001] = { 1, TP|SE, SEN(exit), "exit" }, [4001] = { 1, TP|SE, SEN(exit), "exit" },
[4002] = { 0, TP, SEN(fork), "fork" }, [4002] = { 0, TP, SEN(fork), "fork" },

View File

@ -350,7 +350,7 @@ decode_socket_subcall(struct tcb *tcp)
tcp->u_arg[i] = (sizeof(uint32_t) == current_wordsize) tcp->u_arg[i] = (sizeof(uint32_t) == current_wordsize)
? ((uint32_t *) (void *) buf)[i] : buf[i]; ? ((uint32_t *) (void *) buf)[i] : buf[i];
} }
#endif #endif /* SYS_socket_subcall */
#ifdef SYS_ipc_subcall #ifdef SYS_ipc_subcall
static void static void
@ -390,11 +390,11 @@ decode_ipc_subcall(struct tcb *tcp)
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
tcp->u_arg[i] = tcp->u_arg[i + 1]; tcp->u_arg[i] = tcp->u_arg[i + 1];
} }
#endif #endif /* SYS_ipc_subcall */
#ifdef LINUX_MIPSO32 #ifdef SYS_syscall_subcall
static void static void
decode_mips_subcall(struct tcb *tcp) decode_syscall_subcall(struct tcb *tcp)
{ {
if (!scno_is_valid(tcp->u_arg[0])) if (!scno_is_valid(tcp->u_arg[0]))
return; return;
@ -403,6 +403,7 @@ decode_mips_subcall(struct tcb *tcp)
tcp->s_ent = &sysent[tcp->scno]; tcp->s_ent = &sysent[tcp->scno];
memmove(&tcp->u_arg[0], &tcp->u_arg[1], memmove(&tcp->u_arg[0], &tcp->u_arg[1],
sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0])); sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0]));
# ifdef LINUX_MIPSO32
/* /*
* Fetching the last arg of 7-arg syscalls (fadvise64_64 * Fetching the last arg of 7-arg syscalls (fadvise64_64
* and sync_file_range) requires additional code, * 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)
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 static void
dumpio(struct tcb *tcp) dumpio(struct tcb *tcp)
@ -628,23 +630,30 @@ syscall_entering_decode(struct tcb *tcp)
return res; return res;
} }
#ifdef LINUX_MIPSO32 #if defined SYS_ipc_subcall \
if (SEN_syscall == tcp->s_ent->sen) || defined SYS_socket_subcall \
decode_mips_subcall(tcp); || defined SYS_syscall_subcall
#endif for (;;) {
#if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall)
switch (tcp->s_ent->sen) { switch (tcp->s_ent->sen) {
# ifdef SYS_socket_subcall
case SEN_socketcall:
decode_socket_subcall(tcp);
break;
# endif
# ifdef SYS_ipc_subcall # ifdef SYS_ipc_subcall
case SEN_ipc: case SEN_ipc:
decode_ipc_subcall(tcp); decode_ipc_subcall(tcp);
break; break;
# endif # 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 #endif