X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=ipc.c;h=dd5358e930e95f581e37847d2753650713478ffb;hb=090bd651d3b8ae02241006bb3f725600d61e480f;hp=0bde1cf89a5aa1ca909f0796e23eb8f501f51fcf;hpb=d8d3bd3709eb52581c8ce86cec5a7a9c43c3c5b9;p=strace diff --git a/ipc.c b/ipc.c index 0bde1cf8..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 @@ -29,512 +27,22 @@ */ #include "defs.h" -#ifdef HAVE_MQUEUE_H -# include -#endif -#include -#include -#include -#include -#include +#include "xlat/ipccalls.h" -#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 IPC_64 -# define IPC_64 0x100 -#endif - -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" }, - { IPC_INFO, "IPC_INFO" }, - { MSG_STAT, "MSG_STAT" }, - { MSG_INFO, "MSG_INFO" }, - { 0, NULL }, -}; - -static const struct xlat semctl_flags[] = { - { IPC_RMID, "IPC_RMID" }, - { IPC_SET, "IPC_SET" }, - { IPC_STAT, "IPC_STAT" }, - { IPC_INFO, "IPC_INFO" }, - { SEM_STAT, "SEM_STAT" }, - { SEM_INFO, "SEM_INFO" }, - { 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" }, - { IPC_INFO, "IPC_INFO" }, - { SHM_STAT, "SHM_STAT" }, - { SHM_INFO, "SHM_INFO" }, -#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[] = { - { SHM_REMAP, "SHM_REMAP" }, - { SHM_RDONLY, "SHM_RDONLY" }, - { SHM_RND, "SHM_RND" }, - { 0, NULL }, -}; - -static const struct xlat msg_flags[] = { - { MSG_NOERROR, "MSG_NOERROR" }, - { MSG_EXCEPT, "MSG_EXCEPT" }, - { IPC_NOWAIT, "IPC_NOWAIT" }, - { 0, NULL }, -}; - -static const struct xlat semop_flags[] = { - { SEM_UNDO, "SEM_UNDO" }, - { IPC_NOWAIT, "IPC_NOWAIT" }, - { 0, NULL }, -}; - -int sys_msgget(struct tcb *tcp) -{ - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%#lx", tcp->u_arg[0]); - else - tprints("IPC_PRIVATE"); - tprints(", "); - if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0) - tprints("|"); - tprintf("%#lo", tcp->u_arg[1] & 0777); - } - return 0; -} - -#ifdef IPC_64 -# define PRINTCTL(flagset, arg, dflt) \ - if ((arg) & IPC_64) tprints("IPC_64|"); \ - printxval((flagset), (arg) &~ IPC_64, dflt) -#else -# define PRINTCTL printxval -#endif - -static int -indirect_ipccall(struct tcb *tcp) -{ -#ifdef X86_64 - return current_personality == 1; -#endif -#if defined IA64 - return tcp->scno < 1024; /* ia32 emulation syscalls are low */ -#endif -#if defined(ALPHA) || defined(MIPS) || defined(HPPA) || defined(__ARM_EABI__) || defined(AARCH64) - return 0; -#endif - return 1; -} - -int sys_msgctl(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; -} - -static void -tprint_msgsnd(struct tcb *tcp, long addr, unsigned long count, - unsigned long flags) -{ - long mtype; - - if (umove(tcp, addr, &mtype) < 0) { - tprintf("%#lx", addr); - } else { - tprintf("{%lu, ", mtype); - printstr(tcp, addr + sizeof(mtype), count); - tprints("}"); - } - tprintf(", %lu, ", count); - printflags(msg_flags, flags, "MSG_???"); -} - -int sys_msgsnd(struct tcb *tcp) -{ - if (entering(tcp)) { - tprintf("%d, ", (int) tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprint_msgsnd(tcp, tcp->u_arg[3], tcp->u_arg[1], - tcp->u_arg[2]); - } else { - tprint_msgsnd(tcp, tcp->u_arg[1], tcp->u_arg[2], - tcp->u_arg[3]); - } - } - return 0; -} - -static void -tprint_msgrcv(struct tcb *tcp, long addr, unsigned long count, long msgtyp) -{ - long mtype; - - if (syserror(tcp) || umove(tcp, addr, &mtype) < 0) { - tprintf("%#lx", addr); - } else { - tprintf("{%lu, ", mtype); - printstr(tcp, addr + sizeof(mtype), count); - tprints("}"); - } - tprintf(", %lu, %ld, ", count, msgtyp); -} - -int sys_msgrcv(struct tcb *tcp) -{ - if (entering(tcp)) { - tprintf("%d, ", (int) tcp->u_arg[0]); - } else { - if (indirect_ipccall(tcp)) { - struct ipc_wrapper { - struct msgbuf *msgp; - long msgtyp; - } tmp; - - if (umove(tcp, tcp->u_arg[3], &tmp) < 0) { - tprintf("%#lx, %lu, ", - tcp->u_arg[3], tcp->u_arg[1]); - } else { - tprint_msgrcv(tcp, (long) tmp.msgp, - tcp->u_arg[1], tmp.msgtyp); - } - printflags(msg_flags, tcp->u_arg[2], "MSG_???"); - } else { - tprint_msgrcv(tcp, tcp->u_arg[1], - tcp->u_arg[2], tcp->u_arg[3]); - printflags(msg_flags, tcp->u_arg[4], "MSG_???"); - } - } - return 0; -} - -static void -tprint_sembuf(struct tcb *tcp, long addr, unsigned long count) -{ - unsigned long i, max_count; - - if (abbrev(tcp)) - max_count = (max_strlen < count) ? max_strlen : count; - else - max_count = count; - - if (!max_count) { - tprintf("%#lx, %lu", addr, count); - return; - } - - for (i = 0; i < max_count; ++i) { - struct sembuf sb; - if (i) - tprints(", "); - if (umove(tcp, addr + i * sizeof(struct sembuf), &sb) < 0) { - if (i) { - tprints("{???}"); - break; - } else { - tprintf("%#lx, %lu", addr, count); - return; - } - } else { - if (!i) - tprints("{"); - tprintf("{%u, %d, ", sb.sem_num, sb.sem_op); - printflags(semop_flags, sb.sem_flg, "SEM_???"); - tprints("}"); - } - } - - if (i < max_count || max_count < count) - tprints(", ..."); - - tprintf("}, %lu", count); -} - -int sys_semop(struct tcb *tcp) +SYS_FUNC(ipc) { - if (entering(tcp)) { - tprintf("%lu, ", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); - } else { - tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); - } - } - return 0; -} + unsigned int call = tcp->u_arg[0]; + unsigned int version = call >> 16; + call &= 0xffff; -int sys_semtimedop(struct tcb *tcp) -{ - if (entering(tcp)) { - tprintf("%lu, ", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); - tprints(", "); -#if defined(S390) - printtv(tcp, tcp->u_arg[2]); -#else - printtv(tcp, tcp->u_arg[5]); -#endif - } else { - tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); - tprints(", "); - printtv(tcp, tcp->u_arg[3]); - } - } - return 0; -} + if (version) + tprintf("%u<<16|", version); -int sys_semget(struct tcb *tcp) -{ - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%#lx", tcp->u_arg[0]); - else - tprints("IPC_PRIVATE"); - tprintf(", %lu", tcp->u_arg[1]); - tprints(", "); - if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) - tprints("|"); - tprintf("%#lo", tcp->u_arg[2] & 0777); - } - return 0; -} + printxval_u(ipccalls, call, NULL); -int sys_semctl(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; -} + unsigned int i; + for (i = 1; i < tcp->s_ent->nargs; ++i) + tprintf(", %#" PRI_klx, tcp->u_arg[i]); -int sys_shmget(struct tcb *tcp) -{ - if (entering(tcp)) { - if (tcp->u_arg[0]) - tprintf("%#lx", tcp->u_arg[0]); - else - tprints("IPC_PRIVATE"); - tprintf(", %lu", tcp->u_arg[1]); - tprints(", "); - if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) - tprints("|"); - tprintf("%#lo", tcp->u_arg[2] & 0777); - } - return 0; -} - -int sys_shmctl(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(struct tcb *tcp) -{ - if (exiting(tcp)) { - tprintf("%lu", tcp->u_arg[0]); - if (indirect_ipccall(tcp)) { - tprintf(", %#lx", tcp->u_arg[3]); - tprints(", "); - printflags(shm_flags, tcp->u_arg[1], "SHM_???"); - } else { - tprintf(", %#lx", tcp->u_arg[1]); - tprints(", "); - printflags(shm_flags, tcp->u_arg[2], "SHM_???"); - } - if (syserror(tcp)) - return 0; - if (indirect_ipccall(tcp)) { - unsigned long raddr; - if (umove(tcp, tcp->u_arg[2], &raddr) < 0) - return RVAL_NONE; - tcp->u_rval = raddr; - } - return RVAL_HEX; - } - return 0; -} - -int sys_shmdt(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; -} - -int -sys_mq_open(struct tcb *tcp) -{ - if (entering(tcp)) { - printpath(tcp, tcp->u_arg[0]); - tprints(", "); - /* flags */ - tprint_open_modes(tcp->u_arg[1]); - 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) - tprints("{ ??? }"); - else - tprintf("{mq_maxmsg=%ld, mq_msgsize=%ld}", - (long) attr.mq_maxmsg, - (long) attr.mq_msgsize); -# endif - } - } - return 0; -} - -int -sys_mq_timedsend(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(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(struct tcb *tcp) -{ - if (entering(tcp)) { - tprintf("%ld, ", tcp->u_arg[0]); - printsigevent(tcp, tcp->u_arg[1]); - } - return 0; -} - -static void -printmqattr(struct tcb *tcp, long addr) -{ - if (addr == 0) - tprints("NULL"); - else { -# ifndef HAVE_MQUEUE_H - tprintf("%#lx", addr); -# else - struct mq_attr attr; - if (umove(tcp, addr, &attr) < 0) { - tprints("{...}"); - return; - } - tprints("{mq_flags="); - tprint_open_modes(attr.mq_flags); - tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}", - (long) attr.mq_maxmsg, (long) attr.mq_msgsize, - (long) attr.mq_curmsgs); -# endif - } -} - -int -sys_mq_getsetattr(struct tcb *tcp) -{ - if (entering(tcp)) { - tprintf("%ld, ", tcp->u_arg[0]); - printmqattr(tcp, tcp->u_arg[1]); - tprints(", "); - } else - printmqattr(tcp, tcp->u_arg[2]); - return 0; -} - -int -sys_ipc(struct tcb *tcp) -{ - return printargs(tcp); + return RVAL_DECODED; }