Various amd64 syscall improvements (Tom Hughes)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3425 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/amd64-linux/syscalls.c b/coregrind/amd64-linux/syscalls.c
index 6874670..35197b3 100644
--- a/coregrind/amd64-linux/syscalls.c
+++ b/coregrind/amd64-linux/syscalls.c
@@ -539,30 +539,37 @@
PRE(sys_setsockopt, 0)
{
- /* int setsockopt(int s, int level, int optname,
- const void *optval, int optlen); */
+ PRINT("sys_setsockopt ( %d, %d, %d, %p, %d ",ARG1,ARG2,ARG3,ARG4,ARG5);
+ PRE_REG_READ5(int, "setsockopt",
+ int, s, int, level, int, optname,
+ const void *, optval, int, optlen);
VG_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
}
PRE(sys_connect, MayBlock)
{
- /* int connect(int sockfd,
- struct sockaddr *serv_addr, int addrlen ); */
+ PRINT("sys_connect ( %d, %p, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "connect",
+ int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
VG_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
}
PRE(sys_sendto, MayBlock)
{
- /* int sendto(int s, const void *msg, int len,
- unsigned int flags,
- const struct sockaddr *to, int tolen); */
+ PRINT("sys_sendto ( %d, %s, %d, %u, %p, %d )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+ PRE_REG_READ6(int, "sendto",
+ int, s, const void *, msg, int, len,
+ unsigned int, flags,
+ const struct sockaddr *, to, int, tolen);
VG_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
}
PRE(sys_recvfrom, MayBlock)
{
- /* int recvfrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, int *fromlen); */
+ PRINT("sys_recvfrom ( %d, %p, %d, %u, %p, %p )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+ PRE_REG_READ6(int, "recvfrom",
+ int, s, void *, buf, int, len, unsigned int, flags,
+ struct sockaddr *, from, int *, fromlen);
VG_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
}
POST(sys_recvfrom)
@@ -572,13 +579,16 @@
PRE(sys_sendmsg, MayBlock)
{
- /* int sendmsg(int s, const struct msghdr *msg, int flags); */
+ PRINT("sys_sendmsg ( %d, %p, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "sendmsg",
+ int, s, const struct msghdr *, msg, int, flags);
VG_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
}
PRE(sys_recvmsg, MayBlock)
{
- /* int recvmsg(int s, struct msghdr *msg, int flags); */
+ PRINT("sys_recvmsg ( %d, %p, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "recvmsg", int, s, struct msghdr *, msg, int, flags);
VG_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
}
POST(sys_recvmsg)
@@ -588,11 +598,15 @@
PRE(sys_shutdown, MayBlock)
{
- /* int shutdown(int s, int how); */
+ PRINT("sys_shutdown ( %d, %d )",ARG1,ARG2);
+ PRE_REG_READ2(int, "shutdown", int, s, int, how);
}
PRE(sys_getsockname, MayBlock)
{
+ PRINT("sys_getsockname ( %d, %p, %p )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "getsockname",
+ int, s, struct sockaddr *, name, int *, namelen);
VG_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
}
POST(sys_getsockname)
@@ -602,6 +616,9 @@
PRE(sys_getpeername, MayBlock)
{
+ PRINT("sys_getpeername ( %d, %p, %p )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "getpeername",
+ int, s, struct sockaddr *, name, int *, namelen);
VG_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
}
POST(sys_getpeername)
@@ -609,6 +626,171 @@
VG_(generic_POST_sys_getpeername)(tid, RES,ARG1,ARG2,ARG3);
}
+PRE(sys_socketpair, MayBlock)
+{
+ PRINT("sys_socketpair ( %d, %d, %d, %p )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "socketpair",
+ int, d, int, type, int, protocol, int [2], sv);
+ VG_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
+}
+POST(sys_socketpair)
+{
+ VG_(generic_POST_sys_socketpair)(tid, RES,ARG1,ARG2,ARG3,ARG4);
+}
+
+PRE(sys_semget, 0)
+{
+ PRINT("sys_semget ( %d, %d, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "semget", key_t, key, int, nsems, int, semflg);
+}
+
+PRE(sys_semop, MayBlock)
+{
+ PRINT("sys_semop ( %d, %p, %u )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "semop",
+ int, semid, struct sembuf *, sops, unsigned, nsoops);
+ VG_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
+}
+
+PRE(sys_semtimedop, MayBlock)
+{
+ PRINT("sys_semtimedop ( %d, %p, %u, %p )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "semtimedop",
+ int, semid, struct sembuf *, sops, unsigned, nsoops,
+ struct timespec *, timeout);
+ VG_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
+}
+
+PRE(sys_semctl, 0)
+{
+ switch (ARG3 & ~VKI_IPC_64) {
+ case VKI_IPC_INFO:
+ case VKI_SEM_INFO:
+ PRINT("sys_semctl ( %d, %d, %d, %p )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "semctl",
+ int, semid, int, semnum, int, cmd, struct seminfo *, arg);
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SEM_STAT:
+ case VKI_IPC_SET:
+ PRINT("sys_semctl ( %d, %d, %d, %p )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "semctl",
+ int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
+ break;
+ case VKI_GETALL:
+ case VKI_SETALL:
+ PRINT("sys_semctl ( %d, %d, %d, %p )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "semctl",
+ int, semid, int, semnum, int, cmd, unsigned short *, arg);
+ break;
+ default:
+ PRINT("sys_semctl ( %d, %d, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "semctl",
+ int, semid, int, semnum, int, cmd);
+ break;
+ }
+ VG_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
+}
+
+POST(sys_semctl)
+{
+ VG_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
+}
+
+PRE(sys_msgget, 0)
+{
+ PRINT("sys_msgget ( %d, %d )",ARG1,ARG2);
+ PRE_REG_READ2(int, "msgget", key_t, key, int, msgflg);
+}
+
+PRE(sys_msgsnd, 0)
+{
+ PRINT("sys_msgsnd ( %d, %p, %d, %d )",ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "msgsnd",
+ int, msqid, struct msgbuf *, msgp, size_t, msgsz, int, msgflg);
+ VG_(generic_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
+ /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ tst->sys_flags |= MayBlock;
+ */
+}
+
+PRE(sys_msgrcv, 0)
+{
+ PRINT("sys_msgrcv ( %d, %p, %d, %d, %d )",ARG1,ARG2,ARG3,ARG4,ARG5);
+ PRE_REG_READ5(ssize_t, "msgrcv",
+ int, msqid, struct msgbuf *, msgp, size_t, msgsz,
+ long, msgytp, int, msgflg);
+ VG_(generic_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
+ /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ tst->sys_flags |= MayBlock;
+ */
+}
+
+POST(sys_msgrcv)
+{
+ VG_(generic_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
+}
+
+PRE(sys_msgctl, 0)
+{
+ PRINT("sys_msgctl ( %d, %d, %p )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "msgctl",
+ int, msqid, int, cmd, struct msqid_ds *, buf);
+ VG_(generic_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
+}
+
+POST(sys_msgctl)
+{
+ VG_(generic_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
+}
+
+PRE(sys_shmget, 0)
+{
+ PRINT("sys_shmget ( %d, %d, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "shmget", key_t, key, size_t, size, int, shmflg);
+}
+
+PRE(wrap_sys_shmat, 0)
+{
+ PRINT("wrap_sys_shmat ( %d, %p, %d )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(void *, "shmat",
+ int, shmid, const void *, shmaddr, int, shmflg);
+ ARG2 = VG_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
+ if (ARG2 == 0)
+ SET_RESULT( -VKI_EINVAL );
+}
+
+POST(wrap_sys_shmat)
+{
+ VG_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
+}
+
+PRE(sys_shmdt, 0)
+{
+ PRINT("sys_shmdt ( %p )",ARG1);
+ PRE_REG_READ1(int, "shmdt", const void *, shmaddr);
+ if (!VG_(generic_PRE_sys_shmdt)(tid, ARG1))
+ SET_RESULT( -VKI_EINVAL );
+}
+
+POST(sys_shmdt)
+{
+ VG_(generic_POST_sys_shmdt)(tid, RES,ARG1);
+}
+
+PRE(sys_shmctl, 0)
+{
+ PRINT("sys_shmctl ( %d, %d, %p )",ARG1,ARG2,ARG3);
+ PRE_REG_READ3(int, "shmctl",
+ int, shmid, int, cmd, struct shmid_ds *, buf);
+ VG_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
+}
+
+POST(sys_shmctl)
+{
+ VG_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
+}
+
#undef PRE
#undef POST
@@ -664,12 +846,12 @@
// (__NR_msync, sys_msync), // 26
// (__NR_mincore, sys_mincore), // 27
GENX_(__NR_madvise, sys_madvise), // 28
- // (__NR_shmget, sys_shmget), // 29
+ PLAX_(__NR_shmget, sys_shmget), // 29
- // (__NR_shmat, wrap_sys_shmat), // 30
- // (__NR_shmctl, sys_shmctl), // 31
- // (__NR_dup, sys_dup), // 32
- // (__NR_dup2, sys_dup2), // 33
+ PLAXY(__NR_shmat, wrap_sys_shmat), // 30
+ PLAXY(__NR_shmctl, sys_shmctl), // 31
+ GENXY(__NR_dup, sys_dup), // 32
+ GENXY(__NR_dup2, sys_dup2), // 33
// (__NR_pause, sys_pause), // 34
// (__NR_nanosleep, sys_nanosleep), // 35
@@ -693,36 +875,36 @@
// (__NR_listen, sys_listen), // 50
PLAXY(__NR_getsockname, sys_getsockname), // 51
PLAXY(__NR_getpeername, sys_getpeername), // 52
- // (__NR_socketpair, sys_socketpair), // 53
+ PLAXY(__NR_socketpair, sys_socketpair), // 53
PLAX_(__NR_setsockopt, sys_setsockopt), // 54
// (__NR_getsockopt, sys_getsockopt), // 55
// (__NR_clone, stub_clone), // 56
// (__NR_fork, stub_fork), // 57
// (__NR_vfork, stub_vfork), // 58
- // (__NR_execve, stub_execve), // 59
+ GENX_(__NR_execve, sys_execve), // 59
GENX_(__NR_exit, sys_exit), // 60
- // (__NR_wait4, sys_wait4), // 61
+ GENXY(__NR_wait4, sys_wait4), // 61
GENXY(__NR_kill, sys_kill), // 62
GENXY(__NR_uname, sys_newuname), // 63
- // (__NR_semget, sys_semget), // 64
+ PLAX_(__NR_semget, sys_semget), // 64
- // (__NR_semop, sys_semop), // 65
- // (__NR_semctl, sys_semctl), // 66
- // (__NR_shmdt, sys_shmdt), // 67
- // (__NR_msgget, sys_msgget), // 68
- // (__NR_msgsnd, sys_msgsnd), // 69
+ PLAX_(__NR_semop, sys_semop), // 65
+ PLAXY(__NR_semctl, sys_semctl), // 66
+ PLAXY(__NR_shmdt, sys_shmdt), // 67
+ PLAX_(__NR_msgget, sys_msgget), // 68
+ PLAX_(__NR_msgsnd, sys_msgsnd), // 69
- // (__NR_msgrcv, sys_msgrcv), // 70
- // (__NR_msgctl, sys_msgctl), // 71
+ PLAXY(__NR_msgrcv, sys_msgrcv), // 70
+ PLAXY(__NR_msgctl, sys_msgctl), // 71
GENXY(__NR_fcntl, sys_fcntl), // 72
// (__NR_flock, sys_flock), // 73
// (__NR_fsync, sys_fsync), // 74
// (__NR_fdatasync, sys_fdatasync), // 75
// (__NR_truncate, sys_truncate), // 76
- // (__NR_ftruncate, sys_ftruncate), // 77
+ GENX_(__NR_ftruncate, sys_ftruncate), // 77
GENXY(__NR_getdents, sys_getdents), // 78
GENXY(__NR_getcwd, sys_getcwd), // 79
@@ -750,7 +932,7 @@
GENXY(__NR_getrusage, sys_getrusage), // 98
// (__NR_sysinfo, sys_sysinfo), // 99
- // (__NR_times, sys_times), // 100
+ GENXY(__NR_times, sys_times), // 100
// (__NR_ptrace, sys_ptrace), // 101
GENX_(__NR_getuid, sys_getuid), // 102
// (__NR_syslog, sys_syslog), // 103
@@ -822,7 +1004,7 @@
PLAX_(__NR_arch_prctl, sys_arch_prctl), // 158
// (__NR_adjtimex, sys_adjtimex), // 159
- // (__NR_setrlimit, sys_setrlimit), // 160
+ GENX_(__NR_setrlimit, sys_setrlimit), // 160
// (__NR_chroot, sys_chroot), // 161
// (__NR_sync, sys_sync), // 162
// (__NR_acct, sys_acct), // 163
@@ -894,7 +1076,7 @@
GENX_(__NR_set_tid_address, sys_set_tid_address),// 218
// (__NR_restart_syscall, sys_restart_syscall),// 219
- // (__NR_semtimedop, sys_semtimedop), // 220
+ PLAX_(__NR_semtimedop, sys_semtimedop), // 220
// (__NR_fadvise64, sys_fadvise64), // 221
// (__NR_timer_create, sys_timer_create), // 222
// (__NR_timer_settime, sys_timer_settime), // 223
@@ -919,13 +1101,13 @@
// (__NR_set_mempolicy, sys_set_mempolicy), // 238
// (__NR_get_mempolicy, sys_get_mempolicy), // 239
- // (__NR_mq_open, sys_mq_open), // 240
- // (__NR_mq_unlink, sys_mq_unlink), // 241
- // (__NR_mq_timedsend, sys_mq_timedsend), // 242
- // (__NR_mq_timedreceive, sys_mq_timedreceive),// 243
+ GENXY(__NR_mq_open, sys_mq_open), // 240
+ GENX_(__NR_mq_unlink, sys_mq_unlink), // 241
+ GENX_(__NR_mq_timedsend, sys_mq_timedsend), // 242
+ GENX_(__NR_mq_timedreceive, sys_mq_timedreceive),// 243
- // (__NR_mq_notify, sys_mq_notify), // 244
- // (__NR_mq_getsetattr, sys_mq_getsetattr), // 245
+ GENX_(__NR_mq_notify, sys_mq_notify), // 244
+ GENXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 245
// (__NR_kexec_load, sys_ni_syscall), // 246
// (__NR_waitid, sys_waitid), // 247
};
diff --git a/coregrind/core.h b/coregrind/core.h
index fc4cec2..25be871 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -1543,6 +1543,22 @@
extern void VG_(generic_PRE_sys_recvmsg) ( TId, UW, UW );
extern void VG_(generic_POST_sys_recvmsg) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_semop) ( TId, UW, UW, UW );
+extern void VG_(generic_PRE_sys_semtimedop) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_semctl) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_semctl) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgsnd) ( TId, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgrcv) ( TId, UW, UW, UW, UW, UW );
+extern void VG_(generic_POST_sys_msgrcv) ( TId, UW, UW, UW, UW, UW, UW );
+extern void VG_(generic_PRE_sys_msgctl) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_msgctl) ( TId, UW, UW, UW, UW );
+extern UWord VG_(generic_PRE_sys_shmat) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_shmat) ( TId, UW, UW, UW, UW );
+extern Bool VG_(generic_PRE_sys_shmdt) ( TId, UW );
+extern void VG_(generic_POST_sys_shmdt) ( TId, UW, UW );
+extern void VG_(generic_PRE_sys_shmctl) ( TId, UW, UW, UW );
+extern void VG_(generic_POST_sys_shmctl) ( TId, UW, UW, UW, UW );
+
#undef TID
#undef UW
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 2066701..14e4c97 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -1317,6 +1317,373 @@
/* ---------------------------------------------------------------------
+ Deal with a bunch of IPC related syscalls
+ ------------------------------------------------------------------ */
+
+/* ------ */
+
+void
+VG_(generic_PRE_sys_semop) ( ThreadId tid,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
+ PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
+}
+
+/* ------ */
+
+void
+VG_(generic_PRE_sys_semtimedop) ( ThreadId tid,
+ UWord arg0, UWord arg1,
+ UWord arg2, UWord arg3 )
+{
+ /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
+ struct timespec *timeout); */
+ PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
+ if (arg3 != 0)
+ PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
+}
+
+/* ------ */
+
+static
+UInt get_sem_count( Int semid )
+{
+ struct vki_semid_ds buf;
+ union vki_semun arg;
+ long res;
+
+ arg.buf = &buf;
+
+#ifdef __NR_semctl
+ res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
+#else
+ res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
+ VKI_IPC_STAT, (UWord)&arg);
+#endif
+ if ( VG_(is_kerror)(res) )
+ return 0;
+
+ return buf.sem_nsems;
+}
+
+void
+VG_(generic_PRE_sys_semctl) ( ThreadId tid,
+ UWord arg0, UWord arg1,
+ UWord arg2, UWord arg3 )
+{
+ /* int semctl(int semid, int semnum, int cmd, ...); */
+ union vki_semun arg = *(union vki_semun *)&arg3;
+ UInt nsems;
+ switch (arg2 /* cmd */) {
+ case VKI_IPC_INFO:
+ case VKI_SEM_INFO:
+ case VKI_IPC_INFO|VKI_IPC_64:
+ case VKI_SEM_INFO|VKI_IPC_64:
+ PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
+ (Addr)arg.buf, sizeof(struct vki_seminfo) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SEM_STAT:
+ PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
+ (Addr)arg.buf, sizeof(struct vki_semid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_SEM_STAT|VKI_IPC_64:
+ PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
+ (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
+ break;
+ case VKI_IPC_SET:
+ PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
+ (Addr)arg.buf, sizeof(struct vki_semid_ds) );
+ break;
+ case VKI_IPC_SET|VKI_IPC_64:
+ PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
+ (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
+ break;
+ case VKI_GETALL:
+ case VKI_GETALL|VKI_IPC_64:
+ nsems = get_sem_count( arg0 );
+ PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
+ (Addr)arg.array, sizeof(unsigned short) * nsems );
+ break;
+ case VKI_SETALL:
+ case VKI_SETALL|VKI_IPC_64:
+ nsems = get_sem_count( arg0 );
+ PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
+ (Addr)arg.array, sizeof(unsigned short) * nsems );
+ break;
+ }
+}
+
+void
+VG_(generic_POST_sys_semctl) ( ThreadId tid,
+ UWord res,
+ UWord arg0, UWord arg1,
+ UWord arg2, UWord arg3 )
+{
+ union vki_semun arg = *(union vki_semun *)&arg3;
+ UInt nsems;
+ switch (arg2 /* cmd */) {
+ case VKI_IPC_INFO:
+ case VKI_SEM_INFO:
+ case VKI_IPC_INFO|VKI_IPC_64:
+ case VKI_SEM_INFO|VKI_IPC_64:
+ POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SEM_STAT:
+ POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_SEM_STAT|VKI_IPC_64:
+ POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
+ break;
+ case VKI_GETALL:
+ case VKI_GETALL|VKI_IPC_64:
+ nsems = get_sem_count( arg0 );
+ POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
+ break;
+ }
+}
+
+/* ------ */
+
+void
+VG_(generic_PRE_sys_msgsnd) ( ThreadId tid,
+ UWord arg0, UWord arg1,
+ UWord arg2, UWord arg3 )
+{
+ /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
+ struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
+ PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
+ PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
+}
+
+/* ------ */
+
+void
+VG_(generic_PRE_sys_msgrcv) ( ThreadId tid,
+ UWord arg0, UWord arg1, UWord arg2,
+ UWord arg3, UWord arg4 )
+{
+ /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
+ long msgtyp, int msgflg); */
+ struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
+ PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
+ PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
+}
+
+void
+VG_(generic_POST_sys_msgrcv) ( ThreadId tid,
+ UWord res,
+ UWord arg0, UWord arg1, UWord arg2,
+ UWord arg3, UWord arg4 )
+{
+ struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
+ POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
+ POST_MEM_WRITE( (Addr)&msgp->mtext, res );
+}
+
+/* ------ */
+
+void
+VG_(generic_PRE_sys_msgctl) ( ThreadId tid,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
+ switch (arg1 /* cmd */) {
+ case VKI_IPC_INFO:
+ case VKI_MSG_INFO:
+ case VKI_IPC_INFO|VKI_IPC_64:
+ case VKI_MSG_INFO|VKI_IPC_64:
+ PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
+ arg2, sizeof(struct vki_msginfo) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_MSG_STAT:
+ PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
+ arg2, sizeof(struct vki_msqid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_MSG_STAT|VKI_IPC_64:
+ PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
+ arg2, sizeof(struct vki_msqid64_ds) );
+ break;
+ case VKI_IPC_SET:
+ PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
+ arg2, sizeof(struct vki_msqid_ds) );
+ break;
+ case VKI_IPC_SET|VKI_IPC_64:
+ PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
+ arg2, sizeof(struct vki_msqid64_ds) );
+ break;
+ }
+}
+
+void
+VG_(generic_POST_sys_msgctl) ( ThreadId tid,
+ UWord res,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ switch (arg1 /* cmd */) {
+ case VKI_IPC_INFO:
+ case VKI_MSG_INFO:
+ case VKI_IPC_INFO|VKI_IPC_64:
+ case VKI_MSG_INFO|VKI_IPC_64:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_MSG_STAT:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_MSG_STAT|VKI_IPC_64:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
+ break;
+ }
+}
+
+/* ------ */
+
+static
+UInt get_shm_size ( Int shmid )
+{
+#ifdef __NR_shmctl
+ struct vki_shmid64_ds buf;
+ long __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
+#else
+ struct vki_shmid_ds buf;
+ long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
+ VKI_IPC_STAT, 0, (UWord)&buf);
+#endif
+ if ( VG_(is_kerror) ( __res ) )
+ return 0;
+
+ return buf.shm_segsz;
+}
+
+UWord
+VG_(generic_PRE_sys_shmat) ( ThreadId tid,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
+ UInt segmentSize = get_shm_size ( arg0 );
+ if (arg1 == 0)
+ arg1 = VG_(find_map_space)(0, segmentSize, True);
+ else if (!VG_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
+ arg1 = 0;
+ return arg1;
+}
+
+void
+VG_(generic_POST_sys_shmat) ( ThreadId tid,
+ UWord res,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ UInt segmentSize = get_shm_size ( arg0 );
+ if ( segmentSize > 0 ) {
+ UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
+ /* we don't distinguish whether it's read-only or
+ * read-write -- it doesn't matter really. */
+ VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
+
+ if (!(arg2 & 010000)) /* = SHM_RDONLY */
+ prot &= ~VKI_PROT_WRITE;
+ VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
+ }
+}
+
+/* ------ */
+
+Bool
+VG_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
+{
+ /* int shmdt(const void *shmaddr); */
+ return VG_(valid_client_addr)(arg0, 1, tid, "shmdt");
+}
+
+void
+VG_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
+{
+ Segment *s = VG_(find_segment)(arg0);
+
+ if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, 1)) {
+ VG_TRACK( die_mem_munmap, s->addr, s->len );
+ VG_(unmap_range)(s->addr, s->len);
+ }
+}
+/* ------ */
+
+void
+VG_(generic_PRE_sys_shmctl) ( ThreadId tid,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
+ switch (arg1 /* cmd */) {
+ case VKI_IPC_INFO:
+ PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
+ arg2, sizeof(struct vki_shminfo) );
+ break;
+ case VKI_IPC_INFO|VKI_IPC_64:
+ PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
+ arg2, sizeof(struct vki_shminfo64) );
+ break;
+ case VKI_SHM_INFO:
+ case VKI_SHM_INFO|VKI_IPC_64:
+ PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
+ arg2, sizeof(struct vki_shm_info) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SHM_STAT:
+ PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
+ arg2, sizeof(struct vki_shmid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_SHM_STAT|VKI_IPC_64:
+ PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
+ arg2, sizeof(struct vki_shmid64_ds) );
+ break;
+ case VKI_IPC_SET:
+ PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
+ arg2, sizeof(struct vki_shmid_ds) );
+ break;
+ case VKI_IPC_SET|VKI_IPC_64:
+ PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
+ arg2, sizeof(struct vki_shmid64_ds) );
+ break;
+ }
+}
+
+void
+VG_(generic_POST_sys_shmctl) ( ThreadId tid,
+ UWord res,
+ UWord arg0, UWord arg1, UWord arg2 )
+{
+ switch (arg1 /* cmd */) {
+ case VKI_IPC_INFO:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
+ break;
+ case VKI_IPC_INFO|VKI_IPC_64:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
+ break;
+ case VKI_SHM_INFO:
+ case VKI_SHM_INFO|VKI_IPC_64:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SHM_STAT:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
+ break;
+ case VKI_IPC_STAT|VKI_IPC_64:
+ case VKI_SHM_STAT|VKI_IPC_64:
+ POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
+ break;
+ }
+}
+
+
+/* ---------------------------------------------------------------------
The Main Entertainment ... syscall wrappers
------------------------------------------------------------------ */
diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c
index a7120d5..1fe922d 100644
--- a/coregrind/x86-linux/syscalls.c
+++ b/coregrind/x86-linux/syscalls.c
@@ -726,35 +726,6 @@
}
}
-static
-UInt get_shm_size ( Int shmid )
-{
- struct vki_shmid_ds buf;
- long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
- VKI_IPC_STAT, 0, (UWord)&buf);
- if ( VG_(is_kerror) ( __res ) )
- return 0;
-
- return buf.shm_segsz;
-}
-
-static
-UInt get_sem_count( Int semid )
-{
- struct vki_semid_ds buf;
- union vki_semun arg;
- long res;
-
- arg.buf = &buf;
-
- res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
- VKI_IPC_STAT, (UWord)&arg);
- if ( VG_(is_kerror)(res) )
- return 0;
-
- return buf.sem_nsems;
-}
-
// XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
{
@@ -774,146 +745,40 @@
switch (ARG1 /* call */) {
case VKI_SEMOP:
- PRE_MEM_READ( "semop(sops)", ARG5, ARG3 * sizeof(struct vki_sembuf) );
+ VG_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
/* tst->sys_flags |= MayBlock; */
break;
case VKI_SEMGET:
break;
case VKI_SEMCTL:
{
- union vki_semun *arg = (union vki_semun *)ARG5;
- switch (ARG4 /* cmd */) {
- case VKI_IPC_INFO:
- case VKI_SEM_INFO:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
- PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
- sizeof(struct vki_seminfo) );
- break;
- }
- case VKI_IPC_STAT:
- case VKI_SEM_STAT:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
- PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
- sizeof(struct vki_semid_ds) );
- break;
- }
- case VKI_IPC_SET:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
- PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
- sizeof(struct vki_semid_ds) );
- break;
- }
- case VKI_GETALL:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
- UInt nsems = get_sem_count( ARG2 );
- PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
- sizeof(short) * nsems );
- break;
- }
- case VKI_SETALL:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
- UInt nsems = get_sem_count( ARG2 );
- PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
- sizeof(short) * nsems );
- break;
- }
- case VKI_SETVAL:
- {
- PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
- (Addr)&arg->val, sizeof(arg->val) );
- break;
- }
- case VKI_IPC_INFO|VKI_IPC_64:
- case VKI_SEM_INFO|VKI_IPC_64:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
- PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
- sizeof(struct vki_seminfo) );
- break;
- }
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_SEM_STAT|VKI_IPC_64:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
- PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
- sizeof(struct vki_semid64_ds) );
- break;
- }
- case VKI_IPC_SET|VKI_IPC_64:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
- PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
- sizeof(struct vki_semid64_ds) );
- break;
- }
- case VKI_GETALL|VKI_IPC_64:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
- UInt nsems = get_sem_count( ARG2 );
- PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
- sizeof(short) * nsems );
- break;
- }
- case VKI_SETALL|VKI_IPC_64:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
- UInt nsems = get_sem_count( ARG2 );
- PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
- sizeof(short) * nsems );
- break;
- }
- case VKI_SETVAL|VKI_IPC_64:
- {
- PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
- (Addr)&arg->val, sizeof(arg->val) );
- break;
- }
- default:
- break;
- }
+ UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
+ VG_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
break;
}
case VKI_SEMTIMEDOP:
- PRE_MEM_READ( "semtimedop(sops)", ARG5,
- ARG3 * sizeof(struct vki_sembuf) );
- if (ARG6 != 0)
- PRE_MEM_READ( "semtimedop(timeout)", ARG6,
- sizeof(struct vki_timespec) );
+ VG_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
/* tst->sys_flags |= MayBlock; */
break;
case VKI_MSGSND:
- {
- struct vki_msgbuf *msgp = (struct vki_msgbuf *)ARG5;
- Int msgsz = ARG3;
-
- PRE_MEM_READ( "msgsnd(msgp->mtype)",
- (Addr)&msgp->mtype, sizeof(msgp->mtype) );
- PRE_MEM_READ( "msgsnd(msgp->mtext)",
- (Addr)msgp->mtext, msgsz );
-
+ VG_(generic_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
/* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
tst->sys_flags |= MayBlock;
*/
break;
- }
case VKI_MSGRCV:
{
- struct vki_msgbuf *msgp;
- Int msgsz = ARG3;
+ Addr msgp;
+ Word msgtyp;
- msgp = (struct vki_msgbuf *)deref_Addr( tid,
- (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
- "msgrcv(msgp)" );
+ msgp = deref_Addr( tid,
+ (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
+ "msgrcv(msgp)" );
+ msgtyp = deref_Addr( tid,
+ (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
+ "msgrcv(msgp)" );
- PRE_MEM_WRITE( "msgrcv(msgp->mtype)",
- (Addr)&msgp->mtype, sizeof(msgp->mtype) );
- PRE_MEM_WRITE( "msgrcv(msgp->mtext)",
- (Addr)msgp->mtext, msgsz );
+ VG_(generic_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
/* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
tst->sys_flags |= MayBlock;
@@ -923,102 +788,23 @@
case VKI_MSGGET:
break;
case VKI_MSGCTL:
- {
- switch (ARG3 /* cmd */) {
- case VKI_IPC_INFO:
- case VKI_MSG_INFO:
- PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", ARG5,
- sizeof(struct vki_msginfo) );
- break;
- case VKI_IPC_STAT:
- case VKI_MSG_STAT:
- PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", ARG5,
- sizeof(struct vki_msqid_ds) );
- break;
- case VKI_IPC_SET:
- PRE_MEM_READ( "msgctl(IPC_SET, buf)", ARG5,
- sizeof(struct vki_msqid_ds) );
- break;
- case VKI_IPC_INFO|VKI_IPC_64:
- case VKI_MSG_INFO|VKI_IPC_64:
- PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", ARG5,
- sizeof(struct vki_msginfo) );
- break;
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_MSG_STAT|VKI_IPC_64:
- PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", ARG5,
- sizeof(struct vki_msqid64_ds) );
- break;
- case VKI_IPC_SET|VKI_IPC_64:
- PRE_MEM_READ( "msgctl(IPC_SET, buf)", ARG5,
- sizeof(struct vki_msqid64_ds) );
- break;
- default:
- break;
- }
+ VG_(generic_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
break;
- }
case VKI_SHMAT:
- {
- UInt shmid = ARG2;
- UInt segmentSize = get_shm_size ( shmid );
-
- /* If they didn't ask for a particular address, then place it
- like an mmap. */
+ PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
+ ARG5 = VG_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
if (ARG5 == 0)
- ARG5 = VG_(find_map_space)(0, segmentSize, True);
- else if (!VG_(valid_client_addr)(ARG5, segmentSize, tid, "shmat"))
- SET_RESULT( -VKI_EINVAL );
+ SET_RESULT( -VKI_EINVAL );
break;
- }
case VKI_SHMDT:
- if (!VG_(valid_client_addr)(ARG5, 1, tid, "shmdt"))
+ if (!VG_(generic_PRE_sys_shmdt)(tid, ARG5))
SET_RESULT( -VKI_EINVAL );
break;
case VKI_SHMGET:
break;
case VKI_SHMCTL: /* IPCOP_shmctl */
- {
- switch (ARG3 /* cmd */) {
- case VKI_IPC_INFO:
- PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", ARG5,
- sizeof(struct vki_shminfo) );
- break;
- case VKI_SHM_INFO:
- PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", ARG5,
- sizeof(struct vki_shm_info) );
- break;
- case VKI_IPC_STAT:
- case VKI_SHM_STAT:
- PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", ARG5,
- sizeof(struct vki_shmid_ds) );
- break;
- case VKI_IPC_SET:
- PRE_MEM_READ( "shmctl(IPC_SET, buf)", ARG5,
- sizeof(struct vki_shmid_ds) );
- break;
- case VKI_IPC_INFO|VKI_IPC_64:
- PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", ARG5,
- sizeof(struct vki_shminfo64) );
- break;
- case VKI_SHM_INFO|VKI_IPC_64:
- PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", ARG5,
- sizeof(struct vki_shm_info) );
- break;
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_SHM_STAT|VKI_IPC_64:
- PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", ARG5,
- sizeof(struct vki_shmid64_ds) );
- break;
- case VKI_IPC_SET|VKI_IPC_64:
- PRE_MEM_READ( "shmctl(IPC_SET, buf)", ARG5,
- sizeof(struct vki_shmid_ds) );
- break;
- default:
- break;
- }
+ VG_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
break;
- }
default:
VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
VG_(core_panic)("... bye!\n");
@@ -1034,53 +820,8 @@
break;
case VKI_SEMCTL:
{
- union vki_semun *arg = (union vki_semun *)ARG5;
- switch (ARG4 /* cmd */) {
- case VKI_IPC_INFO:
- case VKI_SEM_INFO:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
- POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
- break;
- }
- case VKI_IPC_STAT:
- case VKI_SEM_STAT:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
- POST_MEM_WRITE( buf, sizeof(struct vki_semid_ds) );
- break;
- }
- case VKI_GETALL:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
- UInt nsems = get_sem_count( ARG2 );
- POST_MEM_WRITE( array, sizeof(short) * nsems );
- break;
- }
- case VKI_IPC_INFO|VKI_IPC_64:
- case VKI_SEM_INFO|VKI_IPC_64:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
- POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
- break;
- }
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_SEM_STAT|VKI_IPC_64:
- {
- Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
- POST_MEM_WRITE( buf, sizeof(struct vki_semid64_ds) );
- break;
- }
- case VKI_GETALL|VKI_IPC_64:
- {
- Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
- UInt nsems = get_sem_count( ARG2 );
- POST_MEM_WRITE( array, sizeof(short) * nsems );
- break;
- }
- default:
- break;
- }
+ UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
+ VG_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
break;
}
case VKI_SEMTIMEDOP:
@@ -1088,114 +829,47 @@
break;
case VKI_MSGRCV:
{
- struct vki_msgbuf *msgp;
-
- msgp = (struct vki_msgbuf *)deref_Addr( tid,
- (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
- "msgrcv(msgp)" );
- if ( RES > 0 ) {
- POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
- POST_MEM_WRITE( (Addr)msgp->mtext, RES );
- }
+ Addr msgp;
+ Word msgtyp;
+
+ msgp = deref_Addr( tid,
+ (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
+ "msgrcv(msgp)" );
+ msgtyp = deref_Addr( tid,
+ (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
+ "msgrcv(msgp)" );
+
+ VG_(generic_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
break;
}
case VKI_MSGGET:
break;
case VKI_MSGCTL:
- {
- switch (ARG3 /* cmd */) {
- case VKI_IPC_INFO:
- case VKI_MSG_INFO:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_msginfo) );
- break;
- case VKI_IPC_STAT:
- case VKI_MSG_STAT:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_msqid_ds) );
- break;
- case VKI_IPC_SET:
- break;
- case VKI_IPC_INFO|VKI_IPC_64:
- case VKI_MSG_INFO|VKI_IPC_64:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_msginfo) );
- break;
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_MSG_STAT|VKI_IPC_64:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_msqid64_ds) );
- break;
- case VKI_IPC_SET|VKI_IPC_64:
- break;
- default:
- break;
- }
+ VG_(generic_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
break;
- }
case VKI_SHMAT:
{
- Int shmid = ARG2;
- Int shmflag = ARG3;
Addr addr;
/* force readability. before the syscall it is
* indeed uninitialized, as can be seen in
* glibc/sysdeps/unix/sysv/linux/shmat.c */
- POST_MEM_WRITE( ARG4, sizeof( ULong ) );
+ POST_MEM_WRITE( ARG4, sizeof( Addr ) );
addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
if ( addr > 0 ) {
- UInt segmentSize = get_shm_size ( shmid );
- if ( segmentSize > 0 ) {
- UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
- /* we don't distinguish whether it's read-only or
- * read-write -- it doesn't matter really. */
- VG_TRACK( new_mem_mmap, addr, segmentSize, True, True, False );
-
- if (!(shmflag & 010000)) /* = SHM_RDONLY */
- prot &= ~VKI_PROT_WRITE;
- VG_(map_segment)(addr, segmentSize, prot, SF_SHARED|SF_SHM);
- }
+ VG_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
}
break;
}
case VKI_SHMDT:
- {
- Segment *s = VG_(find_segment)(ARG5);
-
- if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, ARG5, 1)) {
- VG_TRACK( die_mem_munmap, s->addr, s->len );
- VG_(unmap_range)(s->addr, s->len);
- }
+ VG_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
break;
- }
case VKI_SHMGET:
break;
case VKI_SHMCTL:
- {
- switch (ARG3 /* cmd */) {
- case VKI_IPC_INFO:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shminfo) );
- break;
- case VKI_SHM_INFO:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shm_info) );
- break;
- case VKI_IPC_STAT:
- case VKI_SHM_STAT:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shmid_ds) );
- break;
- case VKI_IPC_INFO|VKI_IPC_64:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shminfo64) );
- break;
- case VKI_SHM_INFO|VKI_IPC_64:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shm_info) );
- break;
- case VKI_IPC_STAT|VKI_IPC_64:
- case VKI_SHM_STAT|VKI_IPC_64:
- POST_MEM_WRITE( ARG5, sizeof(struct vki_shmid64_ds) );
- break;
- default:
- break;
- }
+ VG_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
break;
- }
default:
VG_(message)(Vg_DebugMsg,
"FATAL: unhandled syscall(ipc) %d",
diff --git a/include/amd64-linux/vki_arch.h b/include/amd64-linux/vki_arch.h
index 2cda2f6..018df7e 100644
--- a/include/amd64-linux/vki_arch.h
+++ b/include/amd64-linux/vki_arch.h
@@ -520,6 +520,87 @@
typedef void vki_modify_ldt_t;
//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/ipcbuf.h
+//----------------------------------------------------------------------
+
+struct vki_ipc64_perm
+{
+ __vki_kernel_key_t key;
+ __vki_kernel_uid32_t uid;
+ __vki_kernel_gid32_t gid;
+ __vki_kernel_uid32_t cuid;
+ __vki_kernel_gid32_t cgid;
+ __vki_kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/sembuf.h
+//----------------------------------------------------------------------
+
+struct vki_semid64_ds {
+ struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __vki_kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __vki_kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/msgbuf.h
+//----------------------------------------------------------------------
+
+struct vki_msqid64_ds {
+ struct vki_ipc64_perm msg_perm;
+ __vki_kernel_time_t msg_stime; /* last msgsnd time */
+ __vki_kernel_time_t msg_rtime; /* last msgrcv time */
+ __vki_kernel_time_t msg_ctime; /* last change time */
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __vki_kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.11.2/include/asm-x86_64/shmbuf.h
+//----------------------------------------------------------------------
+
+struct vki_shmid64_ds {
+ struct vki_ipc64_perm shm_perm; /* operation perms */
+ vki_size_t shm_segsz; /* size of segment (bytes) */
+ __vki_kernel_time_t shm_atime; /* last attach time */
+ __vki_kernel_time_t shm_dtime; /* last detach time */
+ __vki_kernel_time_t shm_ctime; /* last change time */
+ __vki_kernel_pid_t shm_cpid; /* pid of creator */
+ __vki_kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct vki_shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+//----------------------------------------------------------------------
// And that's it!
//----------------------------------------------------------------------