File 0010-semctl-fix-indirect-syscall-decoding.patch of Package strace.2926

From 499c5aad0c2a4204ce28bd7761cabe9ceba57bec Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 11 Mar 2015 14:57:57 +0000
Subject: [PATCH 10/15] semctl: fix indirect syscall decoding

On architectures where the semctl call is implemented by the ipc syscall
the 4th argument is passed by reference.

* ipc.c (sys_semctl): Handle the indirect ipc subcall case.
* tests/ipc_sem.c (main): Optionally match indirection
in the 4th argument of semctl calls.

Reported-by: Andreas Schwab <schwab@suse.de>
---
 ipc.c           | 11 ++++++++++-
 tests/ipc_sem.c | 14 +++++++++-----
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/ipc.c b/ipc.c
index 4387772..a94f572 100644
--- a/ipc.c
+++ b/ipc.c
@@ -281,7 +281,16 @@ int sys_semctl(struct tcb *tcp)
 	if (entering(tcp)) {
 		tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
 		PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???");
-		tprintf(", %#lx", tcp->u_arg[3]);
+		tprints(", ");
+		if (indirect_ipccall(tcp)) {
+			if (current_wordsize == sizeof(int)) {
+				printnum_int(tcp, tcp->u_arg[3], "%#x");
+			} else {
+				printnum_long(tcp, tcp->u_arg[3], "%#lx");
+			}
+		} else {
+			tprintf("%#lx", tcp->u_arg[3]);
+		}
 	}
 	return 0;
 }
diff --git a/tests/ipc_sem.c b/tests/ipc_sem.c
index d92ec60..64450b8 100644
--- a/tests/ipc_sem.c
+++ b/tests/ipc_sem.c
@@ -26,13 +26,15 @@ main(void)
 	un.buf = &ds;
 	if (semctl(id, 0, IPC_STAT, un))
 		goto fail;
-	printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_STAT, %p\\) += 0\n", id, &ds);
+	printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_STAT, \\[?%p\\]?\\) += 0\n",
+	       id, &ds);
 
 	un.__buf = &info;
 	int max = semctl(0, 0, SEM_INFO, un);
 	if (max < 0)
 		goto fail;
-	printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, %p\\) += %d\n", &info, max);
+	printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, \\[?%p\\]?\\) += %d\n",
+	       &info, max);
 
 	un.buf = &ds;
 	rc = semctl(id, 0, SEM_STAT, un);
@@ -43,16 +45,18 @@ main(void)
 		 */
 		if (-1 != rc || EINVAL != errno)
 			goto fail;
-		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, %p\\) += -1 EINVAL \\(Invalid argument\\)\n", id, &ds);
+		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\)"
+		       " += -1 EINVAL \\(Invalid argument\\)\n", id, &ds);
 	} else {
-		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, %p\\) += %d\n", id, &ds, id);
+		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\)"
+		       " += %d\n", id, &ds, id);
 	}
 
 	rc = 0;
 done:
 	if (semctl(id, 0, IPC_RMID, 0) < 0)
 		return 1;
-	printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_RMID, 0\\) += 0\n", id);
+	printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_RMID, \\[?0\\]?\\) += 0\n", id);
 	return rc;
 
 fail:
-- 
2.3.3

openSUSE Build Service is sponsored by