diff options
author | Elvira Khabirova <lineprinter0@gmail.com> | 2015-08-19 06:06:29 +0300 |
---|---|---|
committer | Elvira Khabirova <lineprinter0@gmail.com> | 2015-08-20 22:21:04 +0300 |
commit | d079fb19f239be3dfb7c7062ce7cae6e908a4f92 (patch) | |
tree | 4441054e9e31a5344e89e5d8f88a71223bb255e5 /ipc_msg.c | |
parent | c01ad06002f6c15fd0c8807e38e452bb240a1f92 (diff) | |
download | strace-d079fb19f239be3dfb7c7062ce7cae6e908a4f92.tar.gz |
ipc_msg.c: fix multiple personalities support in msgrcv ipc subcall
When msgrcv syscall is an ipc subcall, msgp (pointer to struct msgbuf)
and msgtyp (message type) syscall arguments are passed via proxy
structure which definition significantly depends on tracee's
wordsize.
* ipc_msg.c (fetch_msgrcv_args): New function.
(sys_msgrcv): Use it.
Diffstat (limited to 'ipc_msg.c')
-rw-r--r-- | ipc_msg.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -81,22 +81,35 @@ tprint_msgrcv(struct tcb *tcp, const long addr, const unsigned long count, tprintf("%ld, ", msgtyp); } +static int +fetch_msgrcv_args(struct tcb *tcp, const long addr, long *pair) +{ + if (current_wordsize == sizeof(long)) { + if (umoven_or_printaddr(tcp, addr, 2 * sizeof(long), pair)) + return -1; + } else { + unsigned int tmp[2]; + + if (umove_or_printaddr(tcp, addr, &tmp)) + return -1; + pair[0] = tmp[0]; + pair[1] = tmp[1]; + } + return 0; +} + SYS_FUNC(msgrcv) { if (entering(tcp)) { tprintf("%d, ", (int) tcp->u_arg[0]); } else { if (indirect_ipccall(tcp)) { - struct ipc_wrapper { - struct msgbuf *msgp; - long msgtyp; - } tmp; + long pair[2]; - if (umove_or_printaddr(tcp, tcp->u_arg[3], &tmp)) + if (fetch_msgrcv_args(tcp, tcp->u_arg[3], pair)) tprintf(", %lu, ", tcp->u_arg[1]); else - tprint_msgrcv(tcp, (long) tmp.msgp, - tcp->u_arg[1], tmp.msgtyp); + 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], |