1 /* 2 * Copyright (c) 1993 Ulrich Pegelow <pegelow (at) moorea.uni-muenster.de> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 2003-2006 Roland McGrath <roland (at) redhat.com> 7 * Copyright (c) 2006-2015 Dmitry V. Levin <ldv (at) altlinux.org> 8 * Copyright (c) 2015-2017 The strace developers. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "defs.h" 35 #include "ipc_defs.h" 36 37 #ifdef HAVE_SYS_SEM_H 38 # include <sys/sem.h> 39 #elif defined HAVE_LINUX_SEM_H 40 # include <linux/sem.h> 41 #endif 42 43 #include "xlat/semctl_flags.h" 44 #include "xlat/semop_flags.h" 45 46 #if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H 47 static bool 48 print_sembuf(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data) 49 { 50 const struct sembuf *sb = elem_buf; 51 52 tprintf("{%u, %d, ", sb->sem_num, sb->sem_op); 53 printflags(semop_flags, (unsigned short) sb->sem_flg, "SEM_???"); 54 tprints("}"); 55 56 return true; 57 } 58 #endif 59 60 static void 61 tprint_sembuf_array(struct tcb *const tcp, const kernel_ulong_t addr, 62 const unsigned int count) 63 { 64 #if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H 65 struct sembuf sb; 66 print_array(tcp, addr, count, &sb, sizeof(sb), 67 umoven_or_printaddr, print_sembuf, 0); 68 #else 69 printaddr(addr); 70 #endif 71 tprintf(", %u", count); 72 } 73 74 SYS_FUNC(semop) 75 { 76 tprintf("%d, ", (int) tcp->u_arg[0]); 77 if (indirect_ipccall(tcp)) { 78 tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]); 79 } else { 80 tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]); 81 } 82 return RVAL_DECODED; 83 } 84 85 SYS_FUNC(semtimedop) 86 { 87 tprintf("%d, ", (int) tcp->u_arg[0]); 88 if (indirect_ipccall(tcp)) { 89 tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]); 90 tprints(", "); 91 #if defined(S390) || defined(S390X) 92 print_timespec(tcp, tcp->u_arg[2]); 93 #else 94 print_timespec(tcp, tcp->u_arg[4]); 95 #endif 96 } else { 97 tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]); 98 tprints(", "); 99 print_timespec(tcp, tcp->u_arg[3]); 100 } 101 return RVAL_DECODED; 102 } 103 104 SYS_FUNC(semget) 105 { 106 const int key = (int) tcp->u_arg[0]; 107 if (key) 108 tprintf("%#x", key); 109 else 110 tprints("IPC_PRIVATE"); 111 tprintf(", %d, ", (int) tcp->u_arg[1]); 112 if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) 113 tprints("|"); 114 print_numeric_umode_t(tcp->u_arg[2] & 0777); 115 return RVAL_DECODED; 116 } 117 118 SYS_FUNC(semctl) 119 { 120 tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]); 121 PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???"); 122 tprints(", "); 123 if (indirect_ipccall(tcp) 124 #ifdef SPARC64 125 && current_personality != 0 126 #endif 127 ) { 128 printnum_ptr(tcp, tcp->u_arg[3]); 129 } else { 130 printaddr(tcp->u_arg[3]); 131 } 132 return RVAL_DECODED; 133 } 134