diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2016-07-22 01:17:25 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2016-07-22 19:28:06 +0000 |
commit | b412d75f747b3cd25300b76d536365b00096bd5e (patch) | |
tree | ff53f35f79c928c032abc7169b5738c696fbdceb /ipc_msg.c | |
parent | 9c652ccf908b246b016f8ae7904d80fbe83be542 (diff) | |
download | strace-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.c | 27 |
1 files changed, 19 insertions, 8 deletions
@@ -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], |