]> granicus.if.org Git - strace/blob - desc.c
sys_io_submit: simplify iocb_cmd_lookup() helper.
[strace] / desc.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@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 #include <fcntl.h>
33 #include <sys/file.h>
34 #ifdef HAVE_SYS_EPOLL_H
35 # include <sys/epoll.h>
36 #endif
37 #ifdef HAVE_LIBAIO_H
38 # include <libaio.h>
39 #endif
40 #ifdef HAVE_LINUX_PERF_EVENT_H
41 # include  <linux/perf_event.h>
42 #endif
43
44 static const struct xlat fcntlcmds[] = {
45         { F_DUPFD,      "F_DUPFD"       },
46         { F_GETFD,      "F_GETFD"       },
47         { F_SETFD,      "F_SETFD"       },
48         { F_GETFL,      "F_GETFL"       },
49         { F_SETFL,      "F_SETFL"       },
50         { F_GETLK,      "F_GETLK"       },
51         { F_SETLK,      "F_SETLK"       },
52         { F_SETLKW,     "F_SETLKW"      },
53         { F_GETOWN,     "F_GETOWN"      },
54         { F_SETOWN,     "F_SETOWN"      },
55 #ifdef F_RSETLK
56         { F_RSETLK,     "F_RSETLK"      },
57 #endif
58 #ifdef F_RSETLKW
59         { F_RSETLKW,    "F_RSETLKW"     },
60 #endif
61 #ifdef F_RGETLK
62         { F_RGETLK,     "F_RGETLK"      },
63 #endif
64 #ifdef F_CNVT
65         { F_CNVT,       "F_CNVT"        },
66 #endif
67 #ifdef F_SETSIG
68         { F_SETSIG,     "F_SETSIG"      },
69 #endif
70 #ifdef F_GETSIG
71         { F_GETSIG,     "F_GETSIG"      },
72 #endif
73 #ifdef F_CHKFL
74         { F_CHKFL,      "F_CHKFL"       },
75 #endif
76 #ifdef F_DUP2FD
77         { F_DUP2FD,     "F_DUP2FD"      },
78 #endif
79 #ifdef F_ALLOCSP
80         { F_ALLOCSP,    "F_ALLOCSP"     },
81 #endif
82 #ifdef F_ISSTREAM
83         { F_ISSTREAM,   "F_ISSTREAM"    },
84 #endif
85 #ifdef F_PRIV
86         { F_PRIV,       "F_PRIV"        },
87 #endif
88 #ifdef F_NPRIV
89         { F_NPRIV,      "F_NPRIV"       },
90 #endif
91 #ifdef F_QUOTACL
92         { F_QUOTACL,    "F_QUOTACL"     },
93 #endif
94 #ifdef F_BLOCKS
95         { F_BLOCKS,     "F_BLOCKS"      },
96 #endif
97 #ifdef F_BLKSIZE
98         { F_BLKSIZE,    "F_BLKSIZE"     },
99 #endif
100 #ifdef F_GETOWN
101         { F_GETOWN,     "F_GETOWN"      },
102 #endif
103 #ifdef F_SETOWN
104         { F_SETOWN,     "F_SETOWN"      },
105 #endif
106 #ifdef F_REVOKE
107         { F_REVOKE,     "F_REVOKE"      },
108 #endif
109 #ifdef F_SETLK
110         { F_SETLK,      "F_SETLK"       },
111 #endif
112 #ifdef F_SETLKW
113         { F_SETLKW,     "F_SETLKW"      },
114 #endif
115 #ifdef F_FREESP
116         { F_FREESP,     "F_FREESP"      },
117 #endif
118 #ifdef F_GETLK
119         { F_GETLK,      "F_GETLK"       },
120 #endif
121 #ifdef F_SETLK64
122         { F_SETLK64,    "F_SETLK64"     },
123 #endif
124 #ifdef F_SETLKW64
125         { F_SETLKW64,   "F_SETLKW64"    },
126 #endif
127 #ifdef F_FREESP64
128         { F_FREESP64,   "F_FREESP64"    },
129 #endif
130 #ifdef F_GETLK64
131         { F_GETLK64,    "F_GETLK64"     },
132 #endif
133 #ifdef F_SHARE
134         { F_SHARE,      "F_SHARE"       },
135 #endif
136 #ifdef F_UNSHARE
137         { F_UNSHARE,    "F_UNSHARE"     },
138 #endif
139 #ifdef F_SETLEASE
140         { F_SETLEASE,   "F_SETLEASE"    },
141 #endif
142 #ifdef F_GETLEASE
143         { F_GETLEASE,   "F_GETLEASE"    },
144 #endif
145 #ifdef F_NOTIFY
146         { F_NOTIFY,     "F_NOTIFY"      },
147 #endif
148 #ifdef F_DUPFD_CLOEXEC
149         { F_DUPFD_CLOEXEC,"F_DUPFD_CLOEXEC"},
150 #endif
151         { 0,            NULL            },
152 };
153
154 static const struct xlat fdflags[] = {
155 #ifdef FD_CLOEXEC
156         { FD_CLOEXEC,   "FD_CLOEXEC"    },
157 #endif
158         { 0,            NULL            },
159 };
160
161 #ifdef LOCK_SH
162
163 static const struct xlat flockcmds[] = {
164         { LOCK_SH,      "LOCK_SH"       },
165         { LOCK_EX,      "LOCK_EX"       },
166         { LOCK_NB,      "LOCK_NB"       },
167         { LOCK_UN,      "LOCK_UN"       },
168         { 0,            NULL            },
169 };
170
171 #endif /* LOCK_SH */
172
173 static const struct xlat lockfcmds[] = {
174         { F_RDLCK,      "F_RDLCK"       },
175         { F_WRLCK,      "F_WRLCK"       },
176         { F_UNLCK,      "F_UNLCK"       },
177 #ifdef F_EXLCK
178         { F_EXLCK,      "F_EXLCK"       },
179 #endif
180 #ifdef F_SHLCK
181         { F_SHLCK,      "F_SHLCK"       },
182 #endif
183         { 0,            NULL            },
184 };
185
186 #ifdef F_NOTIFY
187 static const struct xlat notifyflags[] = {
188 #ifdef DN_ACCESS
189         { DN_ACCESS,    "DN_ACCESS"     },
190 #endif
191 #ifdef DN_MODIFY
192         { DN_MODIFY,    "DN_MODIFY"     },
193 #endif
194 #ifdef DN_CREATE
195         { DN_CREATE,    "DN_CREATE"     },
196 #endif
197 #ifdef DN_DELETE
198         { DN_DELETE,    "DN_DELETE"     },
199 #endif
200 #ifdef DN_RENAME
201         { DN_RENAME,    "DN_RENAME"     },
202 #endif
203 #ifdef DN_ATTRIB
204         { DN_ATTRIB,    "DN_ATTRIB"     },
205 #endif
206 #ifdef DN_MULTISHOT
207         { DN_MULTISHOT, "DN_MULTISHOT"  },
208 #endif
209         { 0,            NULL            },
210 };
211 #endif
212
213 static const struct xlat perf_event_open_flags[] = {
214 #ifdef PERF_FLAG_FD_NO_GROUP
215         { PERF_FLAG_FD_NO_GROUP,        "PERF_FLAG_FD_NO_GROUP" },
216 #endif
217 #ifdef PERF_FLAG_FD_OUTPUT
218         { PERF_FLAG_FD_OUTPUT,          "PERF_FLAG_FD_OUTPUT"   },
219 #endif
220 #ifdef PERF_FLAG_PID_CGROUP
221         { PERF_FLAG_PID_CGROUP,         "PERF_FLAG_PID_CGROUP"  },
222 #endif
223         { 0,                            NULL                    },
224 };
225
226 #if _LFS64_LARGEFILE
227 /* fcntl/lockf */
228 static void
229 printflock64(struct tcb *tcp, long addr, int getlk)
230 {
231         struct flock64 fl;
232
233         if (umove(tcp, addr, &fl) < 0) {
234                 tprints("{...}");
235                 return;
236         }
237         tprints("{type=");
238         printxval(lockfcmds, fl.l_type, "F_???");
239         tprints(", whence=");
240         printxval(whence_codes, fl.l_whence, "SEEK_???");
241         tprintf(", start=%lld, len=%lld", (long long) fl.l_start, (long long) fl.l_len);
242         if (getlk)
243                 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
244         else
245                 tprints("}");
246 }
247 #endif
248
249 /* fcntl/lockf */
250 static void
251 printflock(struct tcb *tcp, long addr, int getlk)
252 {
253         struct flock fl;
254
255 #if SUPPORTED_PERSONALITIES > 1
256 # ifdef X32
257         if (current_personality == 0) {
258                 printflock64(tcp, addr, getlk);
259                 return;
260         }
261 # endif
262         if (current_wordsize != sizeof(fl.l_start)) {
263                 if (current_wordsize == 4) {
264                         /* 32-bit x86 app on x86_64 and similar cases */
265                         struct {
266                                 short int l_type;
267                                 short int l_whence;
268                                 int32_t l_start; /* off_t */
269                                 int32_t l_len; /* off_t */
270                                 int32_t l_pid; /* pid_t */
271                         } fl32;
272                         if (umove(tcp, addr, &fl32) < 0) {
273                                 tprints("{...}");
274                                 return;
275                         }
276                         fl.l_type = fl32.l_type;
277                         fl.l_whence = fl32.l_whence;
278                         fl.l_start = fl32.l_start;
279                         fl.l_len = fl32.l_len;
280                         fl.l_pid = fl32.l_pid;
281                 } else {
282                         /* let people know we have a problem here */
283                         tprintf("<decode error: unsupported wordsize %d>",
284                                 current_wordsize);
285                         return;
286                 }
287         } else
288 #endif
289         {
290                 if (umove(tcp, addr, &fl) < 0) {
291                         tprints("{...}");
292                         return;
293                 }
294         }
295         tprints("{type=");
296         printxval(lockfcmds, fl.l_type, "F_???");
297         tprints(", whence=");
298         printxval(whence_codes, fl.l_whence, "SEEK_???");
299 #ifdef X32
300         tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len);
301 #else
302         tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
303 #endif
304         if (getlk)
305                 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
306         else
307                 tprints("}");
308 }
309
310 int
311 sys_fcntl(struct tcb *tcp)
312 {
313         if (entering(tcp)) {
314                 printfd(tcp, tcp->u_arg[0]);
315                 tprints(", ");
316                 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
317                 switch (tcp->u_arg[1]) {
318                 case F_SETFD:
319                         tprints(", ");
320                         printflags(fdflags, tcp->u_arg[2], "FD_???");
321                         break;
322                 case F_SETOWN: case F_DUPFD:
323 #ifdef F_DUPFD_CLOEXEC
324                 case F_DUPFD_CLOEXEC:
325 #endif
326                         tprintf(", %ld", tcp->u_arg[2]);
327                         break;
328                 case F_SETFL:
329                         tprints(", ");
330                         tprint_open_modes(tcp->u_arg[2]);
331                         break;
332                 case F_SETLK: case F_SETLKW:
333 #ifdef F_FREESP
334                 case F_FREESP:
335 #endif
336                         tprints(", ");
337                         printflock(tcp, tcp->u_arg[2], 0);
338                         break;
339 #if _LFS64_LARGEFILE
340 #ifdef F_FREESP64
341                 case F_FREESP64:
342 #endif
343                 /* Linux glibc defines SETLK64 as SETLK,
344                    even though the kernel has different values - as does Solaris. */
345 #if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK
346                 case F_SETLK64:
347 #endif
348 #if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW
349                 case F_SETLKW64:
350 #endif
351                         tprints(", ");
352                         printflock64(tcp, tcp->u_arg[2], 0);
353                         break;
354 #endif
355 #ifdef F_NOTIFY
356                 case F_NOTIFY:
357                         tprints(", ");
358                         printflags(notifyflags, tcp->u_arg[2], "DN_???");
359                         break;
360 #endif
361 #ifdef F_SETLEASE
362                 case F_SETLEASE:
363                         tprints(", ");
364                         printxval(lockfcmds, tcp->u_arg[2], "F_???");
365                         break;
366 #endif
367                 }
368         }
369         else {
370                 switch (tcp->u_arg[1]) {
371                 case F_DUPFD:
372 #ifdef F_DUPFD_CLOEXEC
373                 case F_DUPFD_CLOEXEC:
374 #endif
375                 case F_SETFD: case F_SETFL:
376                 case F_SETLK: case F_SETLKW:
377                 case F_SETOWN: case F_GETOWN:
378 #ifdef F_NOTIFY
379                 case F_NOTIFY:
380 #endif
381 #ifdef F_SETLEASE
382                 case F_SETLEASE:
383 #endif
384                         break;
385                 case F_GETFD:
386                         if (syserror(tcp) || tcp->u_rval == 0)
387                                 return 0;
388                         tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
389                         return RVAL_HEX|RVAL_STR;
390                 case F_GETFL:
391                         if (syserror(tcp))
392                                 return 0;
393                         tcp->auxstr = sprint_open_modes(tcp->u_rval);
394                         return RVAL_HEX|RVAL_STR;
395                 case F_GETLK:
396                         tprints(", ");
397                         printflock(tcp, tcp->u_arg[2], 1);
398                         break;
399 #if _LFS64_LARGEFILE
400 #if defined(F_GETLK64) && F_GETLK64+0 != F_GETLK
401                 case F_GETLK64:
402 #endif
403                         tprints(", ");
404                         printflock64(tcp, tcp->u_arg[2], 1);
405                         break;
406 #endif
407 #ifdef F_GETLEASE
408                 case F_GETLEASE:
409                         if (syserror(tcp))
410                                 return 0;
411                         tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
412                         return RVAL_HEX|RVAL_STR;
413 #endif
414                 default:
415                         tprintf(", %#lx", tcp->u_arg[2]);
416                         break;
417                 }
418         }
419         return 0;
420 }
421
422 #ifdef LOCK_SH
423
424 int
425 sys_flock(struct tcb *tcp)
426 {
427         if (entering(tcp)) {
428                 printfd(tcp, tcp->u_arg[0]);
429                 tprints(", ");
430                 printflags(flockcmds, tcp->u_arg[1], "LOCK_???");
431         }
432         return 0;
433 }
434 #endif /* LOCK_SH */
435
436 int
437 sys_close(struct tcb *tcp)
438 {
439         if (entering(tcp)) {
440                 printfd(tcp, tcp->u_arg[0]);
441         }
442         return 0;
443 }
444
445 static int
446 do_dup2(struct tcb *tcp, int flags_arg)
447 {
448         if (entering(tcp)) {
449                 printfd(tcp, tcp->u_arg[0]);
450                 tprints(", ");
451                 printfd(tcp, tcp->u_arg[1]);
452                 if (flags_arg >= 0) {
453                         tprints(", ");
454                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
455                 }
456         }
457         return 0;
458 }
459
460 int
461 sys_dup2(struct tcb *tcp)
462 {
463         return do_dup2(tcp, -1);
464 }
465
466 int
467 sys_dup3(struct tcb *tcp)
468 {
469         return do_dup2(tcp, 2);
470 }
471
472 #if defined(ALPHA)
473 int
474 sys_getdtablesize(struct tcb *tcp)
475 {
476         return 0;
477 }
478 #endif
479
480 static int
481 decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
482 {
483         int i, j;
484         int nfds, fdsize;
485         fd_set *fds;
486         const char *sep;
487         long arg;
488
489         /* Kernel truncates arg[0] to int, we do the same. */
490         nfds = (int) args[0];
491
492         /* Kernel rejects negative nfds, so we don't parse it either. */
493         if (nfds < 0) {
494                 nfds = 0;
495                 fds = NULL;
496         }
497         /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
498         if (nfds > 1024*1024)
499                 nfds = 1024*1024;
500
501         /*
502          * We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
503          * Instead of args[0], use nfds for fd count, fdsize for array lengths.
504          */
505         fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
506
507         if (entering(tcp)) {
508                 tprintf("%d", (int) args[0]);
509
510                 if (fdsize > 0) {
511                         fds = malloc(fdsize);
512                         if (!fds)
513                                 die_out_of_memory();
514                 }
515                 for (i = 0; i < 3; i++) {
516                         arg = args[i+1];
517                         if (arg == 0) {
518                                 tprints(", NULL");
519                                 continue;
520                         }
521                         if (!verbose(tcp) || !fds) {
522                                 tprintf(", %#lx", arg);
523                                 continue;
524                         }
525                         if (umoven(tcp, arg, fdsize, (char *) fds) < 0) {
526                                 tprints(", [?]");
527                                 continue;
528                         }
529                         tprints(", [");
530                         for (j = 0, sep = "";; j++) {
531                                 j = next_set_bit(fds, j, nfds);
532                                 if (j < 0)
533                                         break;
534                                 tprints(sep);
535                                 printfd(tcp, j);
536                                 sep = " ";
537                         }
538                         tprints("]");
539                 }
540                 free(fds);
541                 tprints(", ");
542                 printtv_bitness(tcp, args[4], bitness, 0);
543         }
544         else {
545                 static char outstr[1024];
546                 char *outptr;
547 #define end_outstr (outstr + sizeof(outstr))
548                 int ready_fds;
549
550                 if (syserror(tcp))
551                         return 0;
552
553                 ready_fds = tcp->u_rval;
554                 if (ready_fds == 0) {
555                         tcp->auxstr = "Timeout";
556                         return RVAL_STR;
557                 }
558
559                 fds = malloc(fdsize);
560                 if (!fds)
561                         die_out_of_memory();
562
563                 outptr = outstr;
564                 sep = "";
565                 for (i = 0; i < 3 && ready_fds > 0; i++) {
566                         int first = 1;
567
568                         arg = args[i+1];
569                         if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0)
570                                 continue;
571                         for (j = 0;; j++) {
572                                 j = next_set_bit(fds, j, nfds);
573                                 if (j < 0)
574                                         break;
575                                 /* +2 chars needed at the end: ']',NUL */
576                                 if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) {
577                                         if (first) {
578                                                 outptr += sprintf(outptr, "%s%s [%u",
579                                                         sep,
580                                                         i == 0 ? "in" : i == 1 ? "out" : "except",
581                                                         j
582                                                 );
583                                                 first = 0;
584                                                 sep = ", ";
585                                         }
586                                         else {
587                                                 outptr += sprintf(outptr, " %u", j);
588                                         }
589                                 }
590                                 if (--ready_fds == 0)
591                                         break;
592                         }
593                         if (outptr != outstr)
594                                 *outptr++ = ']';
595                 }
596                 free(fds);
597                 /* This contains no useful information on SunOS.  */
598                 if (args[4]) {
599                         if (outptr < end_outstr - (10 + TIMEVAL_TEXT_BUFSIZE)) {
600                                 outptr += sprintf(outptr, "%sleft ", sep);
601                                 outptr = sprinttv(outptr, tcp, args[4], bitness, /*special:*/ 0);
602                         }
603                 }
604                 *outptr = '\0';
605                 tcp->auxstr = outstr;
606                 return RVAL_STR;
607 #undef end_outstr
608         }
609         return 0;
610 }
611
612 int
613 sys_oldselect(struct tcb *tcp)
614 {
615         long args[5];
616
617         if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
618                 tprints("[...]");
619                 return 0;
620         }
621         return decode_select(tcp, args, BITNESS_CURRENT);
622 }
623
624 #ifdef ALPHA
625 int
626 sys_osf_select(struct tcb *tcp)
627 {
628         long *args = tcp->u_arg;
629         return decode_select(tcp, args, BITNESS_32);
630 }
631 #endif
632
633 static const struct xlat epollctls[] = {
634 #ifdef EPOLL_CTL_ADD
635         { EPOLL_CTL_ADD,        "EPOLL_CTL_ADD" },
636 #endif
637 #ifdef EPOLL_CTL_MOD
638         { EPOLL_CTL_MOD,        "EPOLL_CTL_MOD" },
639 #endif
640 #ifdef EPOLL_CTL_DEL
641         { EPOLL_CTL_DEL,        "EPOLL_CTL_DEL" },
642 #endif
643         { 0,                    NULL            }
644 };
645
646 static const struct xlat epollevents[] = {
647 #ifdef EPOLLIN
648         { EPOLLIN,      "EPOLLIN"       },
649 #endif
650 #ifdef EPOLLPRI
651         { EPOLLPRI,     "EPOLLPRI"      },
652 #endif
653 #ifdef EPOLLOUT
654         { EPOLLOUT,     "EPOLLOUT"      },
655 #endif
656 #ifdef EPOLLRDNORM
657         { EPOLLRDNORM,  "EPOLLRDNORM"   },
658 #endif
659 #ifdef EPOLLRDBAND
660         { EPOLLRDBAND,  "EPOLLRDBAND"   },
661 #endif
662 #ifdef EPOLLWRNORM
663         { EPOLLWRNORM,  "EPOLLWRNORM"   },
664 #endif
665 #ifdef EPOLLWRBAND
666         { EPOLLWRBAND,  "EPOLLWRBAND"   },
667 #endif
668 #ifdef EPOLLMSG
669         { EPOLLMSG,     "EPOLLMSG"      },
670 #endif
671 #ifdef EPOLLERR
672         { EPOLLERR,     "EPOLLERR"      },
673 #endif
674 #ifdef EPOLLHUP
675         { EPOLLHUP,     "EPOLLHUP"      },
676 #endif
677 #ifdef EPOLLRDHUP
678         { EPOLLRDHUP,   "EPOLLRDHUP"    },
679 #endif
680 #ifdef EPOLLONESHOT
681         { EPOLLONESHOT, "EPOLLONESHOT"  },
682 #endif
683 #ifdef EPOLLET
684         { EPOLLET,      "EPOLLET"       },
685 #endif
686         { 0,            NULL            }
687 };
688
689 /* Not aliased to printargs_ld: we want it to have a distinct address */
690 int
691 sys_epoll_create(struct tcb *tcp)
692 {
693         return printargs_ld(tcp);
694 }
695
696 static const struct xlat epollflags[] = {
697 #ifdef EPOLL_CLOEXEC
698         { EPOLL_CLOEXEC,        "EPOLL_CLOEXEC" },
699 #endif
700 #ifdef EPOLL_NONBLOCK
701         { EPOLL_NONBLOCK,       "EPOLL_NONBLOCK"        },
702 #endif
703         { 0,            NULL            }
704 };
705
706 int
707 sys_epoll_create1(struct tcb *tcp)
708 {
709         if (entering(tcp))
710                 printflags(epollflags, tcp->u_arg[0], "EPOLL_???");
711         return 0;
712 }
713
714 #ifdef HAVE_SYS_EPOLL_H
715 static void
716 print_epoll_event(struct epoll_event *ev)
717 {
718         tprints("{");
719         printflags(epollevents, ev->events, "EPOLL???");
720         /* We cannot know what format the program uses, so print u32 and u64
721            which will cover every value.  */
722         tprintf(", {u32=%" PRIu32 ", u64=%" PRIu64 "}}",
723                 ev->data.u32, ev->data.u64);
724 }
725 #endif
726
727 int
728 sys_epoll_ctl(struct tcb *tcp)
729 {
730         if (entering(tcp)) {
731                 printfd(tcp, tcp->u_arg[0]);
732                 tprints(", ");
733                 printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???");
734                 tprints(", ");
735                 printfd(tcp, tcp->u_arg[2]);
736                 tprints(", ");
737                 if (tcp->u_arg[3] == 0)
738                         tprints("NULL");
739                 else {
740 #ifdef HAVE_SYS_EPOLL_H
741                         struct epoll_event ev;
742                         if (umove(tcp, tcp->u_arg[3], &ev) == 0)
743                                 print_epoll_event(&ev);
744                         else
745 #endif
746                                 tprints("{...}");
747                 }
748         }
749         return 0;
750 }
751
752 static void
753 epoll_wait_common(struct tcb *tcp)
754 {
755         if (entering(tcp)) {
756                 printfd(tcp, tcp->u_arg[0]);
757                 tprints(", ");
758         } else {
759                 if (syserror(tcp))
760                         tprintf("%lx", tcp->u_arg[1]);
761                 else if (tcp->u_rval == 0)
762                         tprints("{}");
763                 else {
764 #ifdef HAVE_SYS_EPOLL_H
765                         struct epoll_event ev, *start, *cur, *end;
766                         int failed = 0;
767
768                         tprints("{");
769                         start = (struct epoll_event *) tcp->u_arg[1];
770                         end = start + tcp->u_rval;
771                         for (cur = start; cur < end; ++cur) {
772                                 if (cur > start)
773                                         tprints(", ");
774                                 if (umove(tcp, (long) cur, &ev) == 0)
775                                         print_epoll_event(&ev);
776                                 else {
777                                         tprints("?");
778                                         failed = 1;
779                                         break;
780                                 }
781                         }
782                         tprints("}");
783                         if (failed)
784                                 tprintf(" %#lx", (long) start);
785 #else
786                         tprints("{...}");
787 #endif
788                 }
789                 tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]);
790         }
791 }
792
793 int
794 sys_epoll_wait(struct tcb *tcp)
795 {
796         epoll_wait_common(tcp);
797         return 0;
798 }
799
800 int
801 sys_epoll_pwait(struct tcb *tcp)
802 {
803         epoll_wait_common(tcp);
804         if (exiting(tcp)) {
805                 tprints(", ");
806                 /* NB: kernel requires arg[5] == NSIG / 8 */
807                 print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]);
808                 tprintf(", %lu", tcp->u_arg[5]);
809         }
810         return 0;
811 }
812
813 int
814 sys_io_setup(struct tcb *tcp)
815 {
816         if (entering(tcp))
817                 tprintf("%ld, ", tcp->u_arg[0]);
818         else {
819                 if (syserror(tcp))
820                         tprintf("0x%0lx", tcp->u_arg[1]);
821                 else {
822                         unsigned long user_id;
823                         if (umove(tcp, tcp->u_arg[1], &user_id) == 0)
824                                 tprintf("{%lu}", user_id);
825                         else
826                                 tprints("{...}");
827                 }
828         }
829         return 0;
830 }
831
832 int
833 sys_io_destroy(struct tcb *tcp)
834 {
835         if (entering(tcp))
836                 tprintf("%lu", tcp->u_arg[0]);
837         return 0;
838 }
839
840 #ifdef HAVE_LIBAIO_H
841
842 enum iocb_sub {
843         SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR
844 };
845
846 static enum iocb_sub
847 tprint_lio_opcode(unsigned cmd)
848 {
849         static const struct {
850                 const char *name;
851                 enum iocb_sub sub;
852         } cmds[] = {
853                 { "pread", SUB_COMMON },
854                 { "pwrite", SUB_COMMON },
855                 { "fsync", SUB_NONE },
856                 { "fdsync", SUB_NONE },
857                 { "op4", SUB_NONE },
858                 { "poll", SUB_POLL },
859                 { "noop", SUB_NONE },
860                 { "preadv", SUB_VECTOR },
861                 { "pwritev", SUB_VECTOR },
862         };
863
864         if (cmd < ARRAY_SIZE(cmds)) {
865                 tprints(cmds[cmd].name);
866                 return cmds[cmd].sub;
867         }
868         tprintf("%u /* SUB_??? */", cmd);
869         return SUB_NONE;
870 }
871
872 /* Not defined in libaio.h */
873 #ifndef IOCB_RESFD
874 # define IOCB_RESFD (1 << 0)
875 #endif
876
877 static void
878 print_common_flags(struct iocb *iocb)
879 {
880 #if HAVE_STRUCT_IOCB_U_C_FLAGS
881         if (iocb->u.c.flags & IOCB_RESFD)
882                 tprintf(", resfd=%d", iocb->u.c.resfd);
883         if (iocb->u.c.flags & ~IOCB_RESFD)
884                 tprintf(", flags=%x", iocb->u.c.flags);
885 #else
886 # warning "libaio.h is too old => limited io_submit decoding"
887 #endif
888 }
889
890 #endif /* HAVE_LIBAIO_H */
891
892 int
893 sys_io_submit(struct tcb *tcp)
894 {
895         if (entering(tcp)) {
896 #ifdef HAVE_LIBAIO_H
897                 long nr = tcp->u_arg[1];
898                 /* if nr <= 0, we end up printing just "{}" */
899                 tprintf("%lu, %ld, {", tcp->u_arg[0], tcp->u_arg[1]);
900                 {
901                         long i;
902                         struct iocb **iocbs = (void *)tcp->u_arg[2];
903
904                         for (i = 0; i < nr; i++, iocbs++) {
905                                 enum iocb_sub sub;
906                                 struct iocb *iocbp;
907                                 struct iocb iocb;
908                                 if (i)
909                                         tprints(", ");
910
911                                 if (umove(tcp, (unsigned long)iocbs, &iocbp)) {
912                                         tprintf("%#lx", (unsigned long)iocbs);
913                                         /* No point in trying to read iocbs+1 etc */
914                                         /* (nr can be ridiculously large): */
915                                         break;
916                                 }
917                                 if (umove(tcp, (unsigned long)iocbp, &iocb)) {
918                                         tprintf("{%#lx}", (unsigned long)iocbp);
919                                         continue;
920                                 }
921                                 tprints("{");
922                                 if (iocb.data)
923                                         tprintf("data:%p, ", iocb.data);
924                                 if (iocb.key)
925                                         tprintf("key:%u, ", iocb.key);
926                                 sub = tprint_lio_opcode(iocb.aio_lio_opcode);
927                                 if (iocb.aio_reqprio)
928                                         tprintf(", reqprio:%d", iocb.aio_reqprio);
929                                 tprintf(", filedes:%d", iocb.aio_fildes);
930                                 switch (sub) {
931                                 case SUB_COMMON:
932 #if HAVE_DECL_IO_CMD_PWRITE
933                                         if (iocb.aio_lio_opcode == IO_CMD_PWRITE) {
934                                                 tprints(", str:");
935                                                 printstr(tcp, (unsigned long)iocb.u.c.buf,
936                                                          iocb.u.c.nbytes);
937                                         } else
938 #endif
939                                                 tprintf(", buf:%p", iocb.u.c.buf);
940                                         tprintf(", nbytes:%lu, offset:%lld",
941                                                 iocb.u.c.nbytes,
942                                                 iocb.u.c.offset);
943                                         print_common_flags(&iocb);
944                                         break;
945                                 case SUB_VECTOR:
946                                         tprintf(", %lld", iocb.u.v.offset);
947                                         print_common_flags(&iocb);
948                                         tprints(", ");
949                                         tprint_iov(tcp, iocb.u.v.nr,
950                                                    (unsigned long)iocb.u.v.vec,
951 #if HAVE_DECL_IO_CMD_PWRITEV
952                                                    iocb.aio_lio_opcode == IO_CMD_PWRITEV
953 #else
954                                                    0
955 #endif
956                                                   );
957                                         break;
958                                 case SUB_POLL:
959                                         tprintf(", %x", iocb.u.poll.events);
960                                         break;
961                                 case SUB_NONE:
962                                         break;
963                                 }
964                                 tprints("}");
965                         }
966                 }
967                 tprints("}");
968 #else
969 #warning "libaio.h is not available => no io_submit decoding"
970                 tprintf("%lu, %ld, %#lx", tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
971 #endif
972         }
973         return 0;
974 }
975
976 int
977 sys_io_cancel(struct tcb *tcp)
978 {
979         if (entering(tcp)) {
980 #ifdef HAVE_LIBAIO_H
981                 struct iocb iocb;
982 #endif
983                 tprintf("%lu, ", tcp->u_arg[0]);
984 #ifdef HAVE_LIBAIO_H
985                 if (umove(tcp, tcp->u_arg[1], &iocb) == 0) {
986                         tprintf("{%p, %u, %u, %u, %d}, ",
987                                 iocb.data, iocb.key,
988                                 (unsigned)iocb.aio_lio_opcode,
989                                 (unsigned)iocb.aio_reqprio, iocb.aio_fildes);
990                 } else
991 #endif
992                         tprints("{...}, ");
993         } else {
994                 if (tcp->u_rval < 0)
995                         tprints("{...}");
996                 else {
997 #ifdef HAVE_LIBAIO_H
998                         struct io_event event;
999                         if (umove(tcp, tcp->u_arg[2], &event) == 0)
1000                                 tprintf("{%p, %p, %ld, %ld}",
1001                                         event.data, event.obj,
1002                                         event.res, event.res2);
1003                         else
1004 #endif
1005                                 tprints("{...}");
1006                 }
1007         }
1008         return 0;
1009 }
1010
1011 int
1012 sys_io_getevents(struct tcb *tcp)
1013 {
1014         if (entering(tcp)) {
1015                 tprintf("%ld, %ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1],
1016                         tcp->u_arg[2]);
1017         } else {
1018                 if (tcp->u_rval == 0) {
1019                         tprints("{}");
1020                 } else {
1021 #ifdef HAVE_LIBAIO_H
1022                         struct io_event *events = (void *)tcp->u_arg[3];
1023                         long i, nr = tcp->u_rval;
1024
1025                         for (i = 0; i < nr; i++, events++) {
1026                                 struct io_event event;
1027
1028                                 if (i == 0)
1029                                         tprints("{");
1030                                 else
1031                                         tprints(", ");
1032
1033                                 if (umove(tcp, (unsigned long)events, &event) != 0) {
1034                                         tprints("{...}");
1035                                         continue;
1036                                 }
1037                                 tprintf("{%p, %p, %ld, %ld}", event.data,
1038                                         event.obj, event.res, event.res2);
1039                         }
1040                         tprints("}, ");
1041 #else
1042                         tprints("{...}");
1043 #endif
1044                 }
1045
1046                 print_timespec(tcp, tcp->u_arg[4]);
1047         }
1048         return 0;
1049 }
1050
1051 int
1052 sys_select(struct tcb *tcp)
1053 {
1054         return decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
1055 }
1056
1057 int
1058 sys_pselect6(struct tcb *tcp)
1059 {
1060         int rc = decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
1061         if (entering(tcp)) {
1062                 long r;
1063                 struct {
1064                         unsigned long ptr;
1065                         unsigned long len;
1066                 } data;
1067 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
1068                 if (current_wordsize == 4) {
1069                         struct {
1070                                 uint32_t ptr;
1071                                 uint32_t len;
1072                         } data32;
1073                         r = umove(tcp, tcp->u_arg[5], &data32);
1074                         data.ptr = data32.ptr;
1075                         data.len = data32.len;
1076                 } else
1077 #endif
1078                         r = umove(tcp, tcp->u_arg[5], &data);
1079                 if (r < 0)
1080                         tprintf(", %#lx", tcp->u_arg[5]);
1081                 else {
1082                         tprints(", {");
1083                         /* NB: kernel requires data.len == NSIG / 8 */
1084                         print_sigset_addr_len(tcp, data.ptr, data.len);
1085                         tprintf(", %lu}", data.len);
1086                 }
1087         }
1088         return rc;
1089 }
1090
1091 static int
1092 do_eventfd(struct tcb *tcp, int flags_arg)
1093 {
1094         if (entering(tcp)) {
1095                 tprintf("%lu", tcp->u_arg[0]);
1096                 if (flags_arg >= 0) {
1097                         tprints(", ");
1098                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
1099                 }
1100         }
1101         return 0;
1102 }
1103
1104 int
1105 sys_eventfd(struct tcb *tcp)
1106 {
1107         return do_eventfd(tcp, -1);
1108 }
1109
1110 int
1111 sys_eventfd2(struct tcb *tcp)
1112 {
1113         return do_eventfd(tcp, 1);
1114 }
1115
1116 int
1117 sys_perf_event_open(struct tcb *tcp)
1118 {
1119         if (entering(tcp)) {
1120                 tprintf("%#lx, %d, %d, %d, ",
1121                         tcp->u_arg[0],
1122                         (int) tcp->u_arg[1],
1123                         (int) tcp->u_arg[2],
1124                         (int) tcp->u_arg[3]);
1125                 printflags(perf_event_open_flags, tcp->u_arg[4],
1126                            "PERF_FLAG_???");
1127         }
1128         return 0;
1129 }