X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=ipc.c;h=dd5358e930e95f581e37847d2753650713478ffb;hb=090bd651d3b8ae02241006bb3f725600d61e480f;hp=baec4240de97c63525455cd26ae162d22a0dbe34;hpb=a81bf4c79f9f2706cd1bea0082fb8d63f08e8a5b;p=strace diff --git a/ipc.c b/ipc.c index baec4240..dd5358e9 100644 --- a/ipc.c +++ b/ipc.c @@ -1,8 +1,6 @@ /* - * Copyright (c) 1993 Ulrich Pegelow - * Copyright (c) 1993 Branko Lankester - * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey - * Copyright (c) 1996-1999 Wichert Akkerman + * Copyright (c) 2016 Dmitry V. Levin + * Copyright (c) 1999-2018 The strace developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,483 +24,25 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id$ */ #include "defs.h" +#include "xlat/ipccalls.h" -#if defined(LINUX) || defined(SUNOS4) || defined(FREEBSD) - -# ifdef HAVE_MQUEUE_H -# include -# endif - -#include -#include -#include -#include -#include - -#ifndef MSG_STAT -#define MSG_STAT 11 -#endif -#ifndef MSG_INFO -#define MSG_INFO 12 -#endif -#ifndef SHM_STAT -#define SHM_STAT 13 -#endif -#ifndef SHM_INFO -#define SHM_INFO 14 -#endif -#ifndef SEM_STAT -#define SEM_STAT 18 -#endif -#ifndef SEM_INFO -#define SEM_INFO 19 -#endif - -#if defined LINUX && !defined IPC_64 -# define IPC_64 0x100 -#endif - -extern const struct xlat openmodes[]; -extern void printsigevent(struct tcb *tcp, long arg); - -static const struct xlat msgctl_flags[] = { - { IPC_RMID, "IPC_RMID" }, - { IPC_SET, "IPC_SET" }, - { IPC_STAT, "IPC_STAT" }, -#ifdef LINUX - { IPC_INFO, "IPC_INFO" }, - { MSG_STAT, "MSG_STAT" }, - { MSG_INFO, "MSG_INFO" }, -#endif /* LINUX */ - { 0, NULL }, -}; - -static const struct xlat semctl_flags[] = { - { IPC_RMID, "IPC_RMID" }, - { IPC_SET, "IPC_SET" }, - { IPC_STAT, "IPC_STAT" }, -#ifdef LINUX - { IPC_INFO, "IPC_INFO" }, - { SEM_STAT, "SEM_STAT" }, - { SEM_INFO, "SEM_INFO" }, -#endif /* LINUX */ - { GETPID, "GETPID" }, - { GETVAL, "GETVAL" }, - { GETALL, "GETALL" }, - { GETNCNT, "GETNCNT" }, - { GETZCNT, "GETZCNT" }, - { SETVAL, "SETVAL" }, - { SETALL, "SETALL" }, - { 0, NULL }, -}; - -static const struct xlat shmctl_flags[] = { - { IPC_RMID, "IPC_RMID" }, - { IPC_SET, "IPC_SET" }, - { IPC_STAT, "IPC_STAT" }, -#ifdef LINUX - { IPC_INFO, "IPC_INFO" }, - { SHM_STAT, "SHM_STAT" }, - { SHM_INFO, "SHM_INFO" }, -#endif /* LINUX */ -#ifdef SHM_LOCK - { SHM_LOCK, "SHM_LOCK" }, -#endif -#ifdef SHM_UNLOCK - { SHM_UNLOCK, "SHM_UNLOCK" }, -#endif - { 0, NULL }, -}; - -static const struct xlat resource_flags[] = { - { IPC_CREAT, "IPC_CREAT" }, - { IPC_EXCL, "IPC_EXCL" }, - { IPC_NOWAIT, "IPC_NOWAIT" }, - { 0, NULL }, -}; - -static const struct xlat shm_resource_flags[] = { - { IPC_CREAT, "IPC_CREAT" }, - { IPC_EXCL, "IPC_EXCL" }, -#ifdef SHM_HUGETLB - { SHM_HUGETLB, "SHM_HUGETLB" }, -#endif - { 0, NULL }, -}; - -static const struct xlat shm_flags[] = { -#ifdef LINUX - { SHM_REMAP, "SHM_REMAP" }, -#endif /* LINUX */ - { SHM_RDONLY, "SHM_RDONLY" }, - { SHM_RND, "SHM_RND" }, - { 0, NULL }, -}; - -static const struct xlat msg_flags[] = { - { MSG_NOERROR, "MSG_NOERROR" }, -#ifdef LINUX - { MSG_EXCEPT, "MSG_EXCEPT" }, -#endif /* LINUX */ - { IPC_NOWAIT, "IPC_NOWAIT" }, - { 0, NULL }, -}; - -int sys_msgget(tcp) -struct tcb *tcp; +SYS_FUNC(ipc) { - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%lu", tcp->u_arg[0]); - else - tprintf("IPC_PRIVATE"); - tprintf(", "); - if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0) - tprintf("|"); - tprintf("%#lo", tcp->u_arg[1] & 0777); - } - return 0; -} + unsigned int call = tcp->u_arg[0]; + unsigned int version = call >> 16; + call &= 0xffff; -#ifdef IPC_64 -# define PRINTCTL(flagset, arg, dflt) \ - if ((arg) & IPC_64) tprintf("IPC_64|"); \ - printxval((flagset), (arg) &~ IPC_64, dflt) -#else -# define PRINTCTL printxval -#endif + if (version) + tprintf("%u<<16|", version); -static int -indirect_ipccall(tcp) -struct tcb *tcp; -{ -#ifdef LINUX -#ifdef X86_64 - return current_personality > 0; -#endif -#if defined IA64 - return tcp->scno < 1024; /* ia32 emulation syscalls are low */ -#endif - return 0; -} + printxval_u(ipccalls, call, NULL); -int sys_msgctl(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%lu, ", tcp->u_arg[0]); - PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???"); - tprintf(", %#lx", tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2]); - } - return 0; -} - -int sys_msgsnd(tcp) -struct tcb *tcp; -{ - long mtype; - - if (entering(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - umove(tcp, tcp->u_arg[3], &mtype); - tprintf(", {%lu, ", mtype); - printstr(tcp, tcp->u_arg[3] + sizeof(long), - tcp->u_arg[1]); - tprintf("}, %lu", tcp->u_arg[1]); - tprintf(", "); - printflags(msg_flags, tcp->u_arg[2], "MSG_???"); - } else { - umove(tcp, tcp->u_arg[1], &mtype); - tprintf(", {%lu, ", mtype); - printstr(tcp, tcp->u_arg[1] + sizeof(long), - tcp->u_arg[2]); - tprintf("}, %lu", tcp->u_arg[2]); - tprintf(", "); - printflags(msg_flags, tcp->u_arg[3], "MSG_???"); - } - } - return 0; -} - -int sys_msgrcv(tcp) -struct tcb *tcp; -{ - long mtype; - - if (entering(tcp)) { - tprintf("%lu, ", tcp->u_arg[0]); - } else { - tprintf("%lu", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - struct ipc_wrapper { - struct msgbuf *msgp; - long msgtyp; - } tmp; - umove(tcp, tcp->u_arg[3], &tmp); - umove(tcp, (long) tmp.msgp, &mtype); - tprintf(", {%lu, ", mtype); - printstr(tcp, (long) (tmp.msgp) + sizeof(long), - tcp->u_arg[1]); - tprintf("}, %lu", tcp->u_arg[1]); - tprintf(", %ld", tmp.msgtyp); - tprintf(", "); - printflags(msg_flags, tcp->u_arg[2], "MSG_???"); - } else { - umove(tcp, tcp->u_arg[1], &mtype); - tprintf("{%lu, ", mtype); - printstr(tcp, tcp->u_arg[1] + sizeof(long), - tcp->u_arg[2]); - tprintf("}, %lu", tcp->u_arg[2]); - tprintf(", %ld", tcp->u_arg[3]); - tprintf(", "); - printflags(msg_flags, tcp->u_arg[4], "MSG_???"); - } - } - return 0; -} + unsigned int i; + for (i = 1; i < tcp->s_ent->nargs; ++i) + tprintf(", %#" PRI_klx, tcp->u_arg[i]); -int sys_semop(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprintf(", %#lx", tcp->u_arg[3]); - tprintf(", %lu", tcp->u_arg[1]); - } else { - tprintf(", %#lx", tcp->u_arg[1]); - tprintf(", %lu", tcp->u_arg[2]); - } - } - return 0; -} - -#ifdef LINUX -int sys_semtimedop(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - if (!indirect_ipccall(tcp)) { - tprintf(", %#lx", tcp->u_arg[3]); - tprintf(", %lu, ", tcp->u_arg[1]); - printtv(tcp, tcp->u_arg[5]); - } else { - tprintf(", %#lx", tcp->u_arg[1]); - tprintf(", %lu, ", tcp->u_arg[2]); - printtv(tcp, tcp->u_arg[3]); - } - } - return 0; -} -#endif - -int sys_semget(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%lu", tcp->u_arg[0]); - else - tprintf("IPC_PRIVATE"); - tprintf(", %lu", tcp->u_arg[1]); - tprintf(", "); - if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) - tprintf("|"); - tprintf("%#lo", tcp->u_arg[2] & 0777); - } - return 0; -} - -int sys_semctl(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - tprintf(", %lu, ", tcp->u_arg[1]); - PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???"); - tprintf(", %#lx", tcp->u_arg[3]); - } - return 0; -} - -int sys_shmget(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%lu", tcp->u_arg[0]); - else - tprintf("IPC_PRIVATE"); - tprintf(", %lu", tcp->u_arg[1]); - tprintf(", "); - if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) - tprintf("|"); - tprintf("%#lo", tcp->u_arg[2] & 0777); - } - return 0; -} - -int sys_shmctl(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%lu, ", tcp->u_arg[0]); - PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???"); - if (indirect_ipccall(tcp)) { - tprintf(", %#lx", tcp->u_arg[3]); - } else { - tprintf(", %#lx", tcp->u_arg[2]); - } - } - return 0; -} - -int sys_shmat(tcp) -struct tcb *tcp; -{ -#ifdef LINUX - unsigned long raddr; -#endif /* LINUX */ - - if (exiting(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprintf(", %#lx", tcp->u_arg[3]); - tprintf(", "); - printflags(shm_flags, tcp->u_arg[1], "SHM_???"); - } else { - tprintf(", %#lx", tcp->u_arg[1]); - tprintf(", "); - printflags(shm_flags, tcp->u_arg[2], "SHM_???"); - } - if (syserror(tcp)) - return 0; -#ifdef LINUX - if (umove(tcp, tcp->u_arg[2], &raddr) < 0) - return RVAL_NONE; - tcp->u_rval = raddr; -#endif /* LINUX */ - return RVAL_HEX; - } - return 0; -} - -int sys_shmdt(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - if (indirect_ipccall(tcp)) { - tprintf("%#lx", tcp->u_arg[3]); - } else { - tprintf("%#lx", tcp->u_arg[0]); - } - } - return 0; -} - -#endif /* defined(LINUX) || defined(SUNOS4) || defined(FREEBSD) */ - -#ifdef LINUX -int sys_mq_open(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - printpath(tcp, tcp->u_arg[0]); - tprintf(", "); - /* flags */ - printflags(openmodes, tcp->u_arg[1] + 1, "O_???"); - if (tcp->u_arg[1] & O_CREAT) { -# ifndef HAVE_MQUEUE_H - tprintf(", %lx", tcp->u_arg[2]); -# else - struct mq_attr attr; - /* mode */ - tprintf(", %#lo, ", tcp->u_arg[2]); - if (umove(tcp, tcp->u_arg[3], &attr) < 0) - tprintf("{ ??? }"); - else - tprintf("{mq_maxmsg=%ld, mq_msgsize=%ld}", - attr.mq_maxmsg, attr.mq_msgsize); -# endif - } - } - return 0; -} - -int sys_mq_timedsend(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%ld, ", tcp->u_arg[0]); - printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); - tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); - printtv(tcp, tcp->u_arg[4]); - } - return 0; -} - -int sys_mq_timedreceive(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) - tprintf("%ld, ", tcp->u_arg[0]); - else { - printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); - tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); - printtv(tcp, tcp->u_arg[4]); - } - return 0; -} - -int sys_mq_notify(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%ld, ", tcp->u_arg[0]); - printsigevent(tcp, tcp->u_arg[1]); - } - return 0; -} - -static void printmqattr(tcp, addr) -struct tcb *tcp; -long addr; -{ - if (addr == 0) - tprintf("NULL"); - else { -# ifndef HAVE_MQUEUE_H - tprintf("%#lx", addr); -# else - struct mq_attr attr; - if (umove(tcp, addr, &attr) < 0) { - tprintf("{...}"); - return; - } - tprintf("{mq_flags="); - printflags(openmodes, attr.mq_flags + 1, "O_???"); - tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}", - attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); -# endif - } -} - -int sys_mq_getsetattr(tcp) -struct tcb *tcp; -{ - if (entering(tcp)) { - tprintf("%ld, ", tcp->u_arg[0]); - printmqattr(tcp, tcp->u_arg[1]); - tprintf(", "); - } else - printmqattr(tcp, tcp->u_arg[2]); - return 0; + return RVAL_DECODED; } -#endif