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 int sys_msgget(struct tcb *tcp) 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 #ifdef X86_64 101 return current_personality == 1; 102 #endif 103 #if defined IA64 104 return tcp->scno < 1024; /* ia32 emulation syscalls are low */ 105 #endif 106 #if defined(ALPHA) || defined(MIPS) || defined(HPPA) || defined(__ARM_EABI__) || defined(AARCH64) 107 return 0; 108 #endif 109 return 1; 110 } 111 112 int sys_msgctl(struct tcb *tcp) 113 { 114 if (entering(tcp)) { 115 tprintf("%lu, ", tcp->u_arg[0]); 116 PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???"); 117 tprintf(", %#lx", tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2]); 118 } 119 return 0; 120 } 121 122 static void 123 tprint_msgsnd(struct tcb *tcp, long addr, unsigned long count, 124 unsigned long flags) 125 { 126 long mtype; 127 128 if (umove(tcp, addr, &mtype) < 0) { 129 tprintf("%#lx", addr); 130 } else { 131 tprintf("{%lu, ", mtype); 132 printstr(tcp, addr + sizeof(mtype), count); 133 tprints("}"); 134 } 135 tprintf(", %lu, ", count); 136 printflags(ipc_msg_flags, flags, "MSG_???"); 137 } 138 139 int sys_msgsnd(struct tcb *tcp) 140 { 141 if (entering(tcp)) { 142 tprintf("%d, ", (int) tcp->u_arg[0]); 143 if (indirect_ipccall(tcp)) { 144 tprint_msgsnd(tcp, tcp->u_arg[3], tcp->u_arg[1], 145 tcp->u_arg[2]); 146 } else { 147 tprint_msgsnd(tcp, tcp->u_arg[1], tcp->u_arg[2], 148 tcp->u_arg[3]); 149 } 150 } 151 return 0; 152 } 153 154 static void 155 tprint_msgrcv(struct tcb *tcp, long addr, unsigned long count, long msgtyp) 156 { 157 long mtype; 158 159 if (syserror(tcp) || umove(tcp, addr, &mtype) < 0) { 160 tprintf("%#lx", addr); 161 } else { 162 tprintf("{%lu, ", mtype); 163 printstr(tcp, addr + sizeof(mtype), count); 164 tprints("}"); 165 } 166 tprintf(", %lu, %ld, ", count, msgtyp); 167 } 168 169 int sys_msgrcv(struct tcb *tcp) 170 { 171 if (entering(tcp)) { 172 tprintf("%d, ", (int) tcp->u_arg[0]); 173 } else { 174 if (indirect_ipccall(tcp)) { 175 struct ipc_wrapper { 176 struct msgbuf *msgp; 177 long msgtyp; 178 } tmp; 179 180 if (umove(tcp, tcp->u_arg[3], &tmp) < 0) { 181 tprintf("%#lx, %lu, ", 182 tcp->u_arg[3], tcp->u_arg[1]); 183 } else { 184 tprint_msgrcv(tcp, (long) tmp.msgp, 185 tcp->u_arg[1], tmp.msgtyp); 186 } 187 printflags(ipc_msg_flags, tcp->u_arg[2], "MSG_???"); 188 } else { 189 tprint_msgrcv(tcp, tcp->u_arg[1], 190 tcp->u_arg[2], tcp->u_arg[3]); 191 printflags(ipc_msg_flags, tcp->u_arg[4], "MSG_???"); 192 } 193 } 194 return 0; 195 } 196 197 static void 198 tprint_sembuf(struct tcb *tcp, long addr, unsigned long count) 199 { 200 unsigned long i, max_count; 201 202 if (abbrev(tcp)) 203 max_count = (max_strlen < count) ? max_strlen : count; 204 else 205 max_count = count; 206 207 if (!max_count) { 208 tprintf("%#lx, %lu", addr, count); 209 return; 210 } 211 212 for (i = 0; i < max_count; ++i) { 213 struct sembuf sb; 214 if (i) 215 tprints(", "); 216 if (umove(tcp, addr + i * sizeof(struct sembuf), &sb) < 0) { 217 if (i) { 218 tprints("{???}"); 219 break; 220 } else { 221 tprintf("%#lx, %lu", addr, count); 222 return; 223 } 224 } else { 225 if (!i) 226 tprints("{"); 227 tprintf("{%u, %d, ", sb.sem_num, sb.sem_op); 228 printflags(semop_flags, sb.sem_flg, "SEM_???"); 229 tprints("}"); 230 } 231 } 232 233 if (i < max_count || max_count < count) 234 tprints(", ..."); 235 236 tprintf("}, %lu", count); 237 } 238 239 int sys_semop(struct tcb *tcp) 240 { 241 if (entering(tcp)) { 242 tprintf("%lu, ", tcp->u_arg[0]); 243 if (indirect_ipccall(tcp)) { 244 tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); 245 } else { 246 tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); 247 } 248 } 249 return 0; 250 } 251 252 int sys_semtimedop(struct tcb *tcp) 253 { 254 if (entering(tcp)) { 255 tprintf("%lu, ", tcp->u_arg[0]); 256 if (indirect_ipccall(tcp)) { 257 tprint_sembuf(tcp, tcp->u_arg[3], tcp->u_arg[1]); 258 tprints(", "); 259 #if defined(S390) || defined(S390X) 260 printtv(tcp, tcp->u_arg[2]); 261 #else 262 printtv(tcp, tcp->u_arg[4]); 263 #endif 264 } else { 265 tprint_sembuf(tcp, tcp->u_arg[1], tcp->u_arg[2]); 266 tprints(", "); 267 printtv(tcp, tcp->u_arg[3]); 268 } 269 } 270 return 0; 271 } 272 273 int sys_semget(struct tcb *tcp) 274 { 275 if (entering(tcp)) { 276 if (tcp->u_arg[0]) 277 tprintf("%#lx", tcp->u_arg[0]); 278 else 279 tprints("IPC_PRIVATE"); 280 tprintf(", %lu, ", tcp->u_arg[1]); 281 if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0) 282 tprints("|"); 283 tprintf("%#lo", tcp->u_arg[2] & 0777); 284 } 285 return 0; 286 } 287 288 int sys_semctl(struct tcb *tcp) 289 { 290 if (entering(tcp)) { 291 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 292 PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???"); 293 tprintf(", %#lx", tcp->u_arg[3]); 294 } 295 return 0; 296 } 297 298 int sys_shmget(struct tcb *tcp) 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 int sys_shmctl(struct tcb *tcp) 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 int sys_shmat(struct tcb *tcp) 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 int sys_shmdt(struct tcb *tcp) 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 int 364 sys_mq_open(struct tcb *tcp) 365 { 366 if (entering(tcp)) { 367 printpath(tcp, tcp->u_arg[0]); 368 tprints(", "); 369 /* flags */ 370 tprint_open_modes(tcp->u_arg[1]); 371 if (tcp->u_arg[1] & O_CREAT) { 372 # ifndef HAVE_MQUEUE_H 373 tprintf(", %lx", tcp->u_arg[2]); 374 # else 375 struct mq_attr attr; 376 /* mode */ 377 tprintf(", %#lo, ", tcp->u_arg[2]); 378 if (umove(tcp, tcp->u_arg[3], &attr) < 0) 379 tprints("{???}"); 380 else 381 tprintf("{mq_maxmsg=%ld, mq_msgsize=%ld}", 382 (long) attr.mq_maxmsg, 383 (long) attr.mq_msgsize); 384 # endif 385 } 386 } 387 return 0; 388 } 389 390 int 391 sys_mq_timedsend(struct tcb *tcp) 392 { 393 if (entering(tcp)) { 394 tprintf("%ld, ", tcp->u_arg[0]); 395 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 396 tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); 397 printtv(tcp, tcp->u_arg[4]); 398 } 399 return 0; 400 } 401 402 int 403 sys_mq_timedreceive(struct tcb *tcp) 404 { 405 if (entering(tcp)) 406 tprintf("%ld, ", tcp->u_arg[0]); 407 else { 408 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 409 tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]); 410 printtv(tcp, tcp->u_arg[4]); 411 } 412 return 0; 413 } 414 415 int 416 sys_mq_notify(struct tcb *tcp) 417 { 418 if (entering(tcp)) { 419 tprintf("%ld, ", tcp->u_arg[0]); 420 printsigevent(tcp, tcp->u_arg[1]); 421 } 422 return 0; 423 } 424 425 static void 426 printmqattr(struct tcb *tcp, long addr) 427 { 428 if (addr == 0) 429 tprints("NULL"); 430 else { 431 # ifndef HAVE_MQUEUE_H 432 tprintf("%#lx", addr); 433 # else 434 struct mq_attr attr; 435 if (umove(tcp, addr, &attr) < 0) { 436 tprints("{...}"); 437 return; 438 } 439 tprints("{mq_flags="); 440 tprint_open_modes(attr.mq_flags); 441 tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}", 442 (long) attr.mq_maxmsg, (long) attr.mq_msgsize, 443 (long) attr.mq_curmsgs); 444 # endif 445 } 446 } 447 448 int 449 sys_mq_getsetattr(struct tcb *tcp) 450 { 451 if (entering(tcp)) { 452 tprintf("%ld, ", tcp->u_arg[0]); 453 printmqattr(tcp, tcp->u_arg[1]); 454 tprints(", "); 455 } else 456 printmqattr(tcp, tcp->u_arg[2]); 457 return 0; 458 } 459 460 int 461 sys_ipc(struct tcb *tcp) 462 { 463 return printargs(tcp); 464 } 465