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>
diff --git a/ipc.c b/ipc.c
index 4387772..a94f572 100644
--- a/ipc.c
+++ b/ipc.c
@@ -281,7 +281,16 @@
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 @@
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 @@
*/
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: