summaryrefslogtreecommitdiff
path: root/ipc_msg.c
diff options
context:
space:
mode:
authorElvira Khabirova <lineprinter0@gmail.com>2015-08-19 06:06:29 +0300
committerElvira Khabirova <lineprinter0@gmail.com>2015-08-20 22:21:04 +0300
commitd079fb19f239be3dfb7c7062ce7cae6e908a4f92 (patch)
tree4441054e9e31a5344e89e5d8f88a71223bb255e5 /ipc_msg.c
parentc01ad06002f6c15fd0c8807e38e452bb240a1f92 (diff)
downloadstrace-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.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/ipc_msg.c b/ipc_msg.c
index fb126f538..5052eacea 100644
--- a/ipc_msg.c
+++ b/ipc_msg.c
@@ -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],