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
/* 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" },

View File

@ -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