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 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "defs.h" 32 #ifdef HAVE_MQUEUE_H 33 # include <mqueue.h> 34 #endif 35 #include <fcntl.h> 36 #include <sys/ipc.h> 37 #include <sys/sem.h> 38 #include <sys/msg.h> 39 #include <sys/shm.h> 40 41 #ifndef MSG_STAT 42 #define MSG_STAT 11 43 #endif 44 #ifndef MSG_INFO 45 #define MSG_INFO 12 46 #endif 47 #ifndef SHM_STAT 48 #define SHM_STAT 13 49 #endif 50 #ifndef SHM_INFO 51 #define SHM_INFO 14 52 #endif 53 #ifndef SEM_STAT 54 #define SEM_STAT 18 55 #endif 56 #ifndef SEM_INFO 57 #define SEM_INFO 19 58 #endif 59 60 #if !defined IPC_64 61 # define IPC_64 0x100 62 #endif 63 64 extern void printsigevent(struct tcb *tcp, long arg); 65 66 #include "xlat/msgctl_flags.h" 67 #include "xlat/semctl_flags.h" 68 #include "xlat/shmctl_flags.h" 69 #include "xlat/resource_flags.h" 70 #include "xlat/shm_resource_flags.h" 71 #include "xlat/shm_flags.h" 72 #include "xlat/ipc_msg_flags.h" 73 #include "xlat/semop_flags.h" 74 75 SYS_FUNC(msgget) 76 { 77 if (entering(tcp)) { 78 if (tcp->u_arg[0]) 79 tprintf("%#lx, ", tcp->u_arg[0]); 80 else 81 tprints("IPC_PRIVATE, "); 82 if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0) 83 tprints("|"); 84 tprintf("%#lo", tcp->u_arg[1] & 0777); 85 } 86 return 0; 87 } 88 89 #ifdef IPC_64 90 # define PRINTCTL(flagset, arg, dflt) \ 91 if ((arg) & IPC_64) tprints("IPC_64|"); \ 92 printxval((flagset), (arg) &~ IPC_64, dflt) 93 #else 94 # define PRINTCTL printxval 95 #endif 96 97 static int 98 indirect_ipccall(struct tcb *tcp) 99 { 100 return tcp->s_ent->sys_flags & TRACE_INDIRECT_SUBCALL; 101 } 102 103 SYS_FUNC(msgctl) 104 { 105 if (entering(tcp)) { 106 tprintf("%lu, ", tcp->u_arg[0]); 107 PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???"); 108 tprintf(", %#lx", tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2]); 109 } 110 return 0; 111 } 112 113 static void 114 tprint_msgsnd(struct tcb *tcp, long addr, unsigned long count, 115 unsigned long flags) 116 { 117 long mtype; 118 119 if (umove(tcp, addr, &mtype) < 0) { 120 tprintf("%#lx", addr); 121 } else { 122 tprintf("{%lu, ", mtype); 123 printstr(tcp, addr + sizeof(mtype), count); 124 tprints("}"); 125 } 126 tprintf(", %lu, ", count); 127 printflags(ipc_msg_flags, flags, "MSG_???"); 128 } 129 130 SYS_FUNC(msgsnd) 131 { 132 if (entering(tcp)) { 133 tprintf("%d, ", (int) tcp->u_arg[0]); 134 if (indirect_ipccall(tcp)) { 135 tprint_msgsnd(tcp, tcp->u_arg[3], tcp->u_arg[1], 136 tcp->u_arg[2]); 137 } else { 138 tprint_msgsnd(tcp, tcp->u_arg[1], tcp->u_arg[2], 139 tcp->u_arg[3]); 140 } 141 } 142 return 0; 143 } 144 145 static void 146 tprint_msgrcv(struct tcb *tcp, long addr, unsigned long count, long msgtyp) 147 { 148 long mtype; 149 150 if (syserror(tcp) || umove(tcp, addr, &mtype) < 0) { 151 tprintf("%#lx", addr); 152 } else { 153 tprintf("{%lu, ", mtype); 154 printstr(tcp, addr + sizeof(mtype), count); 155 tprints("}"); 156 } 157 tprintf(", %lu, %ld, ", count, msgtyp); 158 } 159 160 SYS_FUNC(msgrcv) 161 { 162 if (entering(tcp)) { 163 tprintf("%d, ", (int) tcp->u_arg[0]); 164 } else { 165 if (indirect_ipccall(tcp)) { 166 struct ipc_wrapper { 167 struct msgbuf *msgp; 168 long msgtyp; 169 } tmp; 170 171 if (umove(tcp, tcp->u_arg[3], &tmp) < 0) { 172 tprintf("%#lx, %lu, ", 173 tcp->u_arg[3], tcp->u_arg[1]); 174 } else { 175 tprint_msgrcv(tcp, (long) tmp.msgp, 176 tcp->u_arg[1], tmp.msgtyp); 177 } 178 printflags(ipc_msg_flags, tcp->u_arg[2], "MSG_???"); 179 } else { 180 tprint_msgrcv(tcp, tcp->u_arg[1], 181 tcp->u_arg[2], tcp->u_arg[3]); 182 printflags(ipc_msg_flags, tcp->u_arg[4], "MSG_???"); 183 } 184 } 185 return 0; 186 } 187 188 static void 189 tprint_sembuf(struct tcb *tcp, long addr, unsigned long count) 190 { 191 unsigned long i, max_count; 192 193 if (abbrev(tcp)) 194 max_count = (max_strlen < count) ? max_strlen : count; 195 else 196 max_count = count; 197 198 if (!max_count) { 199 tprintf("%#lx, %lu", addr, count); 200 return; 201 } 202 203 for (i = 0; i < max_count; ++i) { 204 struct sembuf sb; 205 if (i) 206 tprints(", "); 207 if (umove(tcp, addr + i * sizeof(struct sembuf), &sb) < 0) { 208 if (i) { 209 tprints("{???}"); 210 break; 211 } else { 212 tprintf("%#lx, %lu", addr, count); 213 return; 214 } 215 } else { 216 if (!i) 217 tprints("{"); 218 tprintf("{%u, %d, ", sb.sem_num, sb.sem_op); 219 printflags(semop_flags, sb.sem_flg, "SEM_???"); 220 tprints("}"); 221 } 222 } 223 224 if (i < max_count || max_count < count) 225 tprints(", ..."); 226 227 tprintf("}, %lu", count); 228 } 229 230 SYS_FUNC(semop) 231 { 232 if (entering(tcp)) { 233 tprintf("%lu, ", tcp->u_arg[0]); 234 if (indirect_ipccall(tcp)) { 235 tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); 236 } else { 237 tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); 238 } 239 } 240 return 0; 241 } 242 243 SYS_FUNC(semtimedop) 244 { 245 if (entering(tcp)) { 246 tprintf("%lu, ", tcp->u_arg[0]); 247 if (indirect_ipccall(tcp)) { 248 tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); 249 tprints(", "); 250 #if defined(S390) || defined(S390X) 251 printtv(tcp, tcp->u_arg[2]); 252 #else 253 printtv(tcp, tcp->u_arg[4]); 254 #endif 255 } else { 256 tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); 257 tprints(", "); 258 printtv(tcp, tcp->u_arg[3]); 259 } 260 } 261 return 0; 262 } 263 264 SYS_FUNC(semget) 265 { 266 if (entering(tcp)) { 267 if (tcp->u_arg[0]) 268 tprintf("%#lx", tcp->u_arg[0]); 269 else 270 tprints("IPC_PRIVATE"); 271 tprintf(", %lu, ", tcp->u_arg[1]); 272 if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) 273 tprints("|"); 274 tprintf("%#lo", tcp->u_arg[2] & 0777); 275 } 276 return 0; 277 } 278 279 SYS_FUNC(semctl) 280 { 281 if (entering(tcp)) { 282 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 283 PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???"); 284 tprints(", "); 285 if (indirect_ipccall(tcp)) { 286 if (current_wordsize == sizeof(int)) { 287 printnum_int(tcp, tcp->u_arg[3], "%#x"); 288 } else { 289 printnum_long(tcp, tcp->u_arg[3], "%#lx"); 290 } 291 } else { 292 tprintf("%#lx", tcp->u_arg[3]); 293 } 294 } 295 return 0; 296 } 297 298 SYS_FUNC(shmget) 299 { 300 if (entering(tcp)) { 301 if (tcp->u_arg[0]) 302 tprintf("%#lx", tcp->u_arg[0]); 303 else 304 tprints("IPC_PRIVATE"); 305 tprintf(", %lu, ", tcp->u_arg[1]); 306 if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) 307 tprints("|"); 308 tprintf("%#lo", tcp->u_arg[2] & 0777); 309 } 310 return 0; 311 } 312 313 SYS_FUNC(shmctl) 314 { 315 if (entering(tcp)) { 316 tprintf("%lu, ", tcp->u_arg[0]); 317 PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???"); 318 if (indirect_ipccall(tcp)) { 319 tprintf(", %#lx", tcp->u_arg[3]); 320 } else { 321 tprintf(", %#lx", tcp->u_arg[2]); 322 } 323 } 324 return 0; 325 } 326 327 SYS_FUNC(shmat) 328 { 329 if (exiting(tcp)) { 330 tprintf("%lu", tcp->u_arg[0]); 331 if (indirect_ipccall(tcp)) { 332 tprintf(", %#lx, ", tcp->u_arg[3]); 333 printflags(shm_flags, tcp->u_arg[1], "SHM_???"); 334 } else { 335 tprintf(", %#lx, ", tcp->u_arg[1]); 336 printflags(shm_flags, tcp->u_arg[2], "SHM_???"); 337 } 338 if (syserror(tcp)) 339 return 0; 340 if (indirect_ipccall(tcp)) { 341 unsigned long raddr; 342 if (umove(tcp, tcp->u_arg[2], &raddr) < 0) 343 return RVAL_NONE; 344 tcp->u_rval = raddr; 345 } 346 return RVAL_HEX; 347 } 348 return 0; 349 } 350 351 SYS_FUNC(shmdt) 352 { 353 if (entering(tcp)) { 354 if (indirect_ipccall(tcp)) { 355 tprintf("%#lx", tcp->u_arg[3]); 356 } else { 357 tprintf("%#lx", tcp->u_arg[0]); 358 } 359 } 360 return 0; 361 } 362 363 SYS_FUNC(mq_open) 364 { 365 if (entering(tcp)) { 366 printpath(tcp, tcp->u_arg[0]); 367 tprints(", "); 368 /* flags */ 369 tprint_open_modes(tcp->u_arg[1]); 370 if (tcp->u_arg[1] & O_CREAT) { 371 # ifndef HAVE_MQUEUE_H 372 tprintf(", %lx", tcp->u_arg[2]); 373 # else 374 struct mq_attr attr; 375 /* mode */ 376 tprintf(", %#lo, ", tcp->u_arg[2]); 377 if (umove(tcp, tcp->u_arg[3], &attr) < 0) 378 tprints("{???}"); 379 else 380 tprintf("{mq_maxmsg=%ld, mq_msgsize=%ld}", 381 (long) attr.mq_maxmsg, 382 (long) attr.mq_msgsize); 383 # endif 384 } 385 } 386 return 0; 387 } 388 389 SYS_FUNC(mq_timedsend) 390 { 391 if (entering(tcp)) { 392 tprintf("%ld, ", tcp->u_arg[0]); 393 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 394 tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); 395 printtv(tcp, tcp->u_arg[4]); 396 } 397 return 0; 398 } 399 400 SYS_FUNC(mq_timedreceive) 401 { 402 if (entering(tcp)) 403 tprintf("%ld, ", tcp->u_arg[0]); 404 else { 405 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 406 tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); 407 printtv(tcp, tcp->u_arg[4]); 408 } 409 return 0; 410 } 411 412 SYS_FUNC(mq_notify) 413 { 414 if (entering(tcp)) { 415 tprintf("%ld, ", tcp->u_arg[0]); 416 printsigevent(tcp, tcp->u_arg[1]); 417 } 418 return 0; 419 } 420 421 static void 422 printmqattr(struct tcb *tcp, long addr) 423 { 424 if (addr == 0) 425 tprints("NULL"); 426 else { 427 # ifndef HAVE_MQUEUE_H 428 tprintf("%#lx", addr); 429 # else 430 struct mq_attr attr; 431 if (umove(tcp, addr, &attr) < 0) { 432 tprints("{...}"); 433 return; 434 } 435 tprints("{mq_flags="); 436 tprint_open_modes(attr.mq_flags); 437 tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}", 438 (long) attr.mq_maxmsg, (long) attr.mq_msgsize, 439 (long) attr.mq_curmsgs); 440 # endif 441 } 442 } 443 444 SYS_FUNC(mq_getsetattr) 445 { 446 if (entering(tcp)) { 447 tprintf("%ld, ", tcp->u_arg[0]); 448 printmqattr(tcp, tcp->u_arg[1]); 449 tprints(", "); 450 } else 451 printmqattr(tcp, tcp->u_arg[2]); 452 return 0; 453 } 454 455 SYS_FUNC(ipc) 456 { 457 return printargs(tcp); 458 } 459