diff options
author | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2005-03-24 17:52:02 +0000 |
---|---|---|
committer | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2005-03-24 17:52:02 +0000 |
commit | b369c5e35c69997f9bc5798f476108da59876cfc (patch) | |
tree | 4d3f365d43eff20be1744a5d0d951464070e9905 | |
parent | 674915a01b1a49fbb2399b6751d047d8e9466326 (diff) |
Various amd64 syscall improvements (Tom Hughes)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3425 a5019735-40e9-0310-863c-91ae7b9d1cf9
-rw-r--r-- | coregrind/amd64-linux/syscalls.c | 258 | ||||
-rw-r--r-- | coregrind/core.h | 16 | ||||
-rw-r--r-- | coregrind/vg_syscalls.c | 367 | ||||
-rw-r--r-- | coregrind/x86-linux/syscalls.c | 402 | ||||
-rw-r--r-- | include/amd64-linux/vki_arch.h | 81 |
5 files changed, 722 insertions, 402 deletions
diff --git a/coregrind/amd64-linux/syscalls.c b/coregrind/amd64-linux/syscalls.c index 6874670b..35197b33 100644 --- a/coregrind/amd64-linux/syscalls.c +++ b/coregrind/amd64-linux/syscalls.c @@ -539,30 +539,37 @@ POST(sys_socketcall) 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 @@ POST(sys_recvfrom) 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 @@ POST(sys_recvmsg) 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 @@ POST(sys_getsockname) 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 @@ POST(sys_getpeername) 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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { // (__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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { // (__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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { 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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { 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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { 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 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { // (__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 fc4cec29..25be8710 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -1543,6 +1543,22 @@ extern void VG_(generic_PRE_sys_sendmsg) ( TId, UW, UW ); 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 20667013..14e4c970 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -1317,6 +1317,373 @@ VG_(generic_POST_sys_recvmsg) ( ThreadId tid, /* --------------------------------------------------------------------- + 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 a7120d5b..1fe922d3 100644 --- a/coregrind/x86-linux/syscalls.c +++ b/coregrind/x86-linux/syscalls.c @@ -726,35 +726,6 @@ POST(sys_ptrace) } } -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 @@ PRE(sys_ipc, 0) 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 @@ PRE(sys_ipc, 0) 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 @@ POST(sys_ipc) 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 @@ POST(sys_ipc) 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 2cda2f69..018df7e9 100644 --- a/include/amd64-linux/vki_arch.h +++ b/include/amd64-linux/vki_arch.h @@ -520,6 +520,87 @@ typedef struct vki_user_desc vki_modify_ldt_t; 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! //---------------------------------------------------------------------- |