summaryrefslogtreecommitdiff
path: root/ipc_msg.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2016-07-22 01:17:25 +0000
committerDmitry V. Levin <ldv@altlinux.org>2016-07-22 19:28:06 +0000
commitb412d75f747b3cd25300b76d536365b00096bd5e (patch)
treeff53f35f79c928c032abc7169b5738c696fbdceb /ipc_msg.c
parent9c652ccf908b246b016f8ae7904d80fbe83be542 (diff)
downloadstrace-b412d75f747b3cd25300b76d536365b00096bd5e.tar.gz
Fix corner cases of ipc syscall decoding
* xlat/ipccalls.in: New file. * ipc.c: New file. * Makefile.am (libstrace_a_SOURCES): Add it. * linux/dummy.h (sys_ipc): Remove stub alias. * syscall.c (decode_ipc_subcall): Treat 1st argument of ipc syscall as "unsigned int". [S390 || S390X]: Skip ipc cubcalls that have non-zero version. [SPARC64]: Likewise, for the native personality. Save ipc cubcall version for later use by specific ipc parsers. * ipc_msg.c (SYS_FUNC(msgrcv)): Handle non-zero ipc subcall version. [SPARC64]: Handle non-ipc_kludge case for the native personality. * linux/subcall.h (msgrcv): Change nargs from 4 to 5. * linux/s390/syscallent.h (ipc): Change nargs from 6 to 5. * linux/s390x/syscallent.h (ipc): Likewise.
Diffstat (limited to 'ipc_msg.c')
-rw-r--r--ipc_msg.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/ipc_msg.c b/ipc_msg.c
index 965e2e493..daa003652 100644
--- a/ipc_msg.c
+++ b/ipc_msg.c
@@ -84,10 +84,10 @@ tprint_msgrcv(struct tcb *tcp, const long addr, const unsigned long count,
}
static int
-fetch_msgrcv_args(struct tcb *tcp, const long addr, long *pair)
+fetch_msgrcv_args(struct tcb *tcp, const long addr, unsigned long *pair)
{
- if (current_wordsize == sizeof(long)) {
- if (umoven_or_printaddr(tcp, addr, 2 * sizeof(long), pair))
+ if (current_wordsize == sizeof(*pair)) {
+ if (umoven_or_printaddr(tcp, addr, 2 * sizeof(*pair), pair))
return -1;
} else {
unsigned int tmp[2];
@@ -106,12 +106,23 @@ SYS_FUNC(msgrcv)
tprintf("%d, ", (int) tcp->u_arg[0]);
} else {
if (indirect_ipccall(tcp)) {
- long pair[2];
+ const bool direct =
+#ifdef SPARC64
+ current_wordsize == 8 ||
+#endif
+ get_tcb_priv_ulong(tcp) != 0;
+ if (direct) {
+ tprint_msgrcv(tcp, tcp->u_arg[3],
+ tcp->u_arg[1], tcp->u_arg[4]);
+ } else {
+ unsigned long pair[2];
- if (fetch_msgrcv_args(tcp, tcp->u_arg[3], pair))
- tprintf(", %lu, ", tcp->u_arg[1]);
- else
- tprint_msgrcv(tcp, pair[0], tcp->u_arg[1], pair[1]);
+ if (fetch_msgrcv_args(tcp, tcp->u_arg[3], pair))
+ tprintf(", %lu, ", tcp->u_arg[1]);
+ else
+ tprint_msgrcv(tcp, pair[0],
+ tcp->u_arg[1], pair[1]);
+ }
printflags(ipc_msg_flags, tcp->u_arg[2], "MSG_???");
} else {
tprint_msgrcv(tcp, tcp->u_arg[1],