]> granicus.if.org Git - strace/blob - desc.c
58c9f1376427048366c812c6bda80780d59e8635
[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_LINUX_PERF_EVENT_H
38 # include  <linux/perf_event.h>
39 #endif
40
41 static const struct xlat fcntlcmds[] = {
42         { F_DUPFD,      "F_DUPFD"       },
43         { F_GETFD,      "F_GETFD"       },
44         { F_SETFD,      "F_SETFD"       },
45         { F_GETFL,      "F_GETFL"       },
46         { F_SETFL,      "F_SETFL"       },
47         { F_GETLK,      "F_GETLK"       },
48         { F_SETLK,      "F_SETLK"       },
49         { F_SETLKW,     "F_SETLKW"      },
50         { F_GETOWN,     "F_GETOWN"      },
51         { F_SETOWN,     "F_SETOWN"      },
52 #ifdef F_RSETLK
53         { F_RSETLK,     "F_RSETLK"      },
54 #endif
55 #ifdef F_RSETLKW
56         { F_RSETLKW,    "F_RSETLKW"     },
57 #endif
58 #ifdef F_RGETLK
59         { F_RGETLK,     "F_RGETLK"      },
60 #endif
61 #ifdef F_CNVT
62         { F_CNVT,       "F_CNVT"        },
63 #endif
64 #ifdef F_SETSIG
65         { F_SETSIG,     "F_SETSIG"      },
66 #endif
67 #ifdef F_GETSIG
68         { F_GETSIG,     "F_GETSIG"      },
69 #endif
70 #ifdef F_CHKFL
71         { F_CHKFL,      "F_CHKFL"       },
72 #endif
73 #ifdef F_DUP2FD
74         { F_DUP2FD,     "F_DUP2FD"      },
75 #endif
76 #ifdef F_ALLOCSP
77         { F_ALLOCSP,    "F_ALLOCSP"     },
78 #endif
79 #ifdef F_ISSTREAM
80         { F_ISSTREAM,   "F_ISSTREAM"    },
81 #endif
82 #ifdef F_PRIV
83         { F_PRIV,       "F_PRIV"        },
84 #endif
85 #ifdef F_NPRIV
86         { F_NPRIV,      "F_NPRIV"       },
87 #endif
88 #ifdef F_QUOTACL
89         { F_QUOTACL,    "F_QUOTACL"     },
90 #endif
91 #ifdef F_BLOCKS
92         { F_BLOCKS,     "F_BLOCKS"      },
93 #endif
94 #ifdef F_BLKSIZE
95         { F_BLKSIZE,    "F_BLKSIZE"     },
96 #endif
97 #ifdef F_GETOWN
98         { F_GETOWN,     "F_GETOWN"      },
99 #endif
100 #ifdef F_SETOWN
101         { F_SETOWN,     "F_SETOWN"      },
102 #endif
103 #ifdef F_REVOKE
104         { F_REVOKE,     "F_REVOKE"      },
105 #endif
106 #ifdef F_SETLK
107         { F_SETLK,      "F_SETLK"       },
108 #endif
109 #ifdef F_SETLKW
110         { F_SETLKW,     "F_SETLKW"      },
111 #endif
112 #ifdef F_FREESP
113         { F_FREESP,     "F_FREESP"      },
114 #endif
115 #ifdef F_GETLK
116         { F_GETLK,      "F_GETLK"       },
117 #endif
118 #ifdef F_SETLK64
119         { F_SETLK64,    "F_SETLK64"     },
120 #endif
121 #ifdef F_SETLKW64
122         { F_SETLKW64,   "F_SETLKW64"    },
123 #endif
124 #ifdef F_FREESP64
125         { F_FREESP64,   "F_FREESP64"    },
126 #endif
127 #ifdef F_GETLK64
128         { F_GETLK64,    "F_GETLK64"     },
129 #endif
130 #ifdef F_SHARE
131         { F_SHARE,      "F_SHARE"       },
132 #endif
133 #ifdef F_UNSHARE
134         { F_UNSHARE,    "F_UNSHARE"     },
135 #endif
136 #ifdef F_SETLEASE
137         { F_SETLEASE,   "F_SETLEASE"    },
138 #endif
139 #ifdef F_GETLEASE
140         { F_GETLEASE,   "F_GETLEASE"    },
141 #endif
142 #ifdef F_NOTIFY
143         { F_NOTIFY,     "F_NOTIFY"      },
144 #endif
145 #ifdef F_DUPFD_CLOEXEC
146         { F_DUPFD_CLOEXEC,"F_DUPFD_CLOEXEC"},
147 #endif
148         { 0,            NULL            },
149 };
150
151 static const struct xlat fdflags[] = {
152 #ifdef FD_CLOEXEC
153         { FD_CLOEXEC,   "FD_CLOEXEC"    },
154 #endif
155         { 0,            NULL            },
156 };
157
158 #ifdef LOCK_SH
159
160 static const struct xlat flockcmds[] = {
161         { LOCK_SH,      "LOCK_SH"       },
162         { LOCK_EX,      "LOCK_EX"       },
163         { LOCK_NB,      "LOCK_NB"       },
164         { LOCK_UN,      "LOCK_UN"       },
165         { 0,            NULL            },
166 };
167
168 #endif /* LOCK_SH */
169
170 static const struct xlat lockfcmds[] = {
171         { F_RDLCK,      "F_RDLCK"       },
172         { F_WRLCK,      "F_WRLCK"       },
173         { F_UNLCK,      "F_UNLCK"       },
174 #ifdef F_EXLCK
175         { F_EXLCK,      "F_EXLCK"       },
176 #endif
177 #ifdef F_SHLCK
178         { F_SHLCK,      "F_SHLCK"       },
179 #endif
180         { 0,            NULL            },
181 };
182
183 #ifdef F_NOTIFY
184 static const struct xlat notifyflags[] = {
185 #ifdef DN_ACCESS
186         { DN_ACCESS,    "DN_ACCESS"     },
187 #endif
188 #ifdef DN_MODIFY
189         { DN_MODIFY,    "DN_MODIFY"     },
190 #endif
191 #ifdef DN_CREATE
192         { DN_CREATE,    "DN_CREATE"     },
193 #endif
194 #ifdef DN_DELETE
195         { DN_DELETE,    "DN_DELETE"     },
196 #endif
197 #ifdef DN_RENAME
198         { DN_RENAME,    "DN_RENAME"     },
199 #endif
200 #ifdef DN_ATTRIB
201         { DN_ATTRIB,    "DN_ATTRIB"     },
202 #endif
203 #ifdef DN_MULTISHOT
204         { DN_MULTISHOT, "DN_MULTISHOT"  },
205 #endif
206         { 0,            NULL            },
207 };
208 #endif
209
210 static const struct xlat perf_event_open_flags[] = {
211 #ifdef PERF_FLAG_FD_NO_GROUP
212         { PERF_FLAG_FD_NO_GROUP,        "PERF_FLAG_FD_NO_GROUP" },
213 #endif
214 #ifdef PERF_FLAG_FD_OUTPUT
215         { PERF_FLAG_FD_OUTPUT,          "PERF_FLAG_FD_OUTPUT"   },
216 #endif
217 #ifdef PERF_FLAG_PID_CGROUP
218         { PERF_FLAG_PID_CGROUP,         "PERF_FLAG_PID_CGROUP"  },
219 #endif
220         { 0,                            NULL                    },
221 };
222
223 #if _LFS64_LARGEFILE
224 /* fcntl/lockf */
225 static void
226 printflock64(struct tcb *tcp, long addr, int getlk)
227 {
228         struct flock64 fl;
229
230         if (umove(tcp, addr, &fl) < 0) {
231                 tprints("{...}");
232                 return;
233         }
234         tprints("{type=");
235         printxval(lockfcmds, fl.l_type, "F_???");
236         tprints(", whence=");
237         printxval(whence_codes, fl.l_whence, "SEEK_???");
238         tprintf(", start=%lld, len=%lld", (long long) fl.l_start, (long long) fl.l_len);
239         if (getlk)
240                 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
241         else
242                 tprints("}");
243 }
244 #endif
245
246 /* fcntl/lockf */
247 static void
248 printflock(struct tcb *tcp, long addr, int getlk)
249 {
250         struct flock fl;
251
252 #if SUPPORTED_PERSONALITIES > 1
253 # ifdef X32
254         if (current_personality == 0) {
255                 printflock64(tcp, addr, getlk);
256                 return;
257         }
258 # endif
259         if (current_wordsize != sizeof(fl.l_start)) {
260                 if (current_wordsize == 4) {
261                         /* 32-bit x86 app on x86_64 and similar cases */
262                         struct {
263                                 short int l_type;
264                                 short int l_whence;
265                                 int32_t l_start; /* off_t */
266                                 int32_t l_len; /* off_t */
267                                 int32_t l_pid; /* pid_t */
268                         } fl32;
269                         if (umove(tcp, addr, &fl32) < 0) {
270                                 tprints("{...}");
271                                 return;
272                         }
273                         fl.l_type = fl32.l_type;
274                         fl.l_whence = fl32.l_whence;
275                         fl.l_start = fl32.l_start;
276                         fl.l_len = fl32.l_len;
277                         fl.l_pid = fl32.l_pid;
278                 } else {
279                         /* let people know we have a problem here */
280                         tprintf("<decode error: unsupported wordsize %d>",
281                                 current_wordsize);
282                         return;
283                 }
284         } else
285 #endif
286         {
287                 if (umove(tcp, addr, &fl) < 0) {
288                         tprints("{...}");
289                         return;
290                 }
291         }
292         tprints("{type=");
293         printxval(lockfcmds, fl.l_type, "F_???");
294         tprints(", whence=");
295         printxval(whence_codes, fl.l_whence, "SEEK_???");
296 #ifdef X32
297         tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len);
298 #else
299         tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
300 #endif
301         if (getlk)
302                 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
303         else
304                 tprints("}");
305 }
306
307 int
308 sys_fcntl(struct tcb *tcp)
309 {
310         if (entering(tcp)) {
311                 printfd(tcp, tcp->u_arg[0]);
312                 tprints(", ");
313                 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
314                 switch (tcp->u_arg[1]) {
315                 case F_SETFD:
316                         tprints(", ");
317                         printflags(fdflags, tcp->u_arg[2], "FD_???");
318                         break;
319                 case F_SETOWN: case F_DUPFD:
320 #ifdef F_DUPFD_CLOEXEC
321                 case F_DUPFD_CLOEXEC:
322 #endif
323                         tprintf(", %ld", tcp->u_arg[2]);
324                         break;
325                 case F_SETFL:
326                         tprints(", ");
327                         tprint_open_modes(tcp->u_arg[2]);
328                         break;
329                 case F_SETLK: case F_SETLKW:
330 #ifdef F_FREESP
331                 case F_FREESP:
332 #endif
333                         tprints(", ");
334                         printflock(tcp, tcp->u_arg[2], 0);
335                         break;
336 #if _LFS64_LARGEFILE
337 #ifdef F_FREESP64
338                 case F_FREESP64:
339 #endif
340                 /* Linux glibc defines SETLK64 as SETLK,
341                    even though the kernel has different values - as does Solaris. */
342 #if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK
343                 case F_SETLK64:
344 #endif
345 #if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW
346                 case F_SETLKW64:
347 #endif
348                         tprints(", ");
349                         printflock64(tcp, tcp->u_arg[2], 0);
350                         break;
351 #endif
352 #ifdef F_NOTIFY
353                 case F_NOTIFY:
354                         tprints(", ");
355                         printflags(notifyflags, tcp->u_arg[2], "DN_???");
356                         break;
357 #endif
358 #ifdef F_SETLEASE
359                 case F_SETLEASE:
360                         tprints(", ");
361                         printxval(lockfcmds, tcp->u_arg[2], "F_???");
362                         break;
363 #endif
364                 }
365         }
366         else {
367                 switch (tcp->u_arg[1]) {
368                 case F_DUPFD:
369 #ifdef F_DUPFD_CLOEXEC
370                 case F_DUPFD_CLOEXEC:
371 #endif
372                 case F_SETFD: case F_SETFL:
373                 case F_SETLK: case F_SETLKW:
374                 case F_SETOWN: case F_GETOWN:
375 #ifdef F_NOTIFY
376                 case F_NOTIFY:
377 #endif
378 #ifdef F_SETLEASE
379                 case F_SETLEASE:
380 #endif
381                         break;
382                 case F_GETFD:
383                         if (syserror(tcp) || tcp->u_rval == 0)
384                                 return 0;
385                         tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
386                         return RVAL_HEX|RVAL_STR;
387                 case F_GETFL:
388                         if (syserror(tcp))
389                                 return 0;
390                         tcp->auxstr = sprint_open_modes(tcp->u_rval);
391                         return RVAL_HEX|RVAL_STR;
392                 case F_GETLK:
393                         tprints(", ");
394                         printflock(tcp, tcp->u_arg[2], 1);
395                         break;
396 #if _LFS64_LARGEFILE
397 #if defined(F_GETLK64) && F_GETLK64+0 != F_GETLK
398                 case F_GETLK64:
399 #endif
400                         tprints(", ");
401                         printflock64(tcp, tcp->u_arg[2], 1);
402                         break;
403 #endif
404 #ifdef F_GETLEASE
405                 case F_GETLEASE:
406                         if (syserror(tcp))
407                                 return 0;
408                         tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
409                         return RVAL_HEX|RVAL_STR;
410 #endif
411                 default:
412                         tprintf(", %#lx", tcp->u_arg[2]);
413                         break;
414                 }
415         }
416         return 0;
417 }
418
419 #ifdef LOCK_SH
420
421 int
422 sys_flock(struct tcb *tcp)
423 {
424         if (entering(tcp)) {
425                 printfd(tcp, tcp->u_arg[0]);
426                 tprints(", ");
427                 printflags(flockcmds, tcp->u_arg[1], "LOCK_???");
428         }
429         return 0;
430 }
431 #endif /* LOCK_SH */
432
433 int
434 sys_close(struct tcb *tcp)
435 {
436         if (entering(tcp)) {
437                 printfd(tcp, tcp->u_arg[0]);
438         }
439         return 0;
440 }
441
442 static int
443 do_dup2(struct tcb *tcp, int flags_arg)
444 {
445         if (entering(tcp)) {
446                 printfd(tcp, tcp->u_arg[0]);
447                 tprints(", ");
448                 printfd(tcp, tcp->u_arg[1]);
449                 if (flags_arg >= 0) {
450                         tprints(", ");
451                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
452                 }
453         }
454         return 0;
455 }
456
457 int
458 sys_dup2(struct tcb *tcp)
459 {
460         return do_dup2(tcp, -1);
461 }
462
463 int
464 sys_dup3(struct tcb *tcp)
465 {
466         return do_dup2(tcp, 2);
467 }
468
469 #if defined(ALPHA)
470 int
471 sys_getdtablesize(struct tcb *tcp)
472 {
473         return 0;
474 }
475 #endif
476
477 static int
478 decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
479 {
480         int i, j;
481         int nfds, fdsize;
482         fd_set *fds;
483         const char *sep;
484         long arg;
485
486         /* Kernel truncates arg[0] to int, we do the same. */
487         nfds = (int) args[0];
488
489         /* Kernel rejects negative nfds, so we don't parse it either. */
490         if (nfds < 0) {
491                 nfds = 0;
492                 fds = NULL;
493         }
494         /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
495         if (nfds > 1024*1024)
496                 nfds = 1024*1024;
497
498         /*
499          * We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
500          * Instead of args[0], use nfds for fd count, fdsize for array lengths.
501          */
502         fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
503
504         if (entering(tcp)) {
505                 tprintf("%d", (int) args[0]);
506
507                 if (fdsize > 0) {
508                         fds = malloc(fdsize);
509                         if (!fds)
510                                 die_out_of_memory();
511                 }
512                 for (i = 0; i < 3; i++) {
513                         arg = args[i+1];
514                         if (arg == 0) {
515                                 tprints(", NULL");
516                                 continue;
517                         }
518                         if (!verbose(tcp) || !fds) {
519                                 tprintf(", %#lx", arg);
520                                 continue;
521                         }
522                         if (umoven(tcp, arg, fdsize, (char *) fds) < 0) {
523                                 tprints(", [?]");
524                                 continue;
525                         }
526                         tprints(", [");
527                         for (j = 0, sep = "";; j++) {
528                                 j = next_set_bit(fds, j, nfds);
529                                 if (j < 0)
530                                         break;
531                                 tprints(sep);
532                                 printfd(tcp, j);
533                                 sep = " ";
534                         }
535                         tprints("]");
536                 }
537                 free(fds);
538                 tprints(", ");
539                 printtv_bitness(tcp, args[4], bitness, 0);
540         }
541         else {
542                 static char outstr[1024];
543                 char *outptr;
544 #define end_outstr (outstr + sizeof(outstr))
545                 int ready_fds;
546
547                 if (syserror(tcp))
548                         return 0;
549
550                 ready_fds = tcp->u_rval;
551                 if (ready_fds == 0) {
552                         tcp->auxstr = "Timeout";
553                         return RVAL_STR;
554                 }
555
556                 fds = malloc(fdsize);
557                 if (!fds)
558                         die_out_of_memory();
559
560                 outptr = outstr;
561                 sep = "";
562                 for (i = 0; i < 3 && ready_fds > 0; i++) {
563                         int first = 1;
564
565                         arg = args[i+1];
566                         if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0)
567                                 continue;
568                         for (j = 0;; j++) {
569                                 j = next_set_bit(fds, j, nfds);
570                                 if (j < 0)
571                                         break;
572                                 /* +2 chars needed at the end: ']',NUL */
573                                 if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) {
574                                         if (first) {
575                                                 outptr += sprintf(outptr, "%s%s [%u",
576                                                         sep,
577                                                         i == 0 ? "in" : i == 1 ? "out" : "except",
578                                                         j
579                                                 );
580                                                 first = 0;
581                                                 sep = ", ";
582                                         }
583                                         else {
584                                                 outptr += sprintf(outptr, " %u", j);
585                                         }
586                                 }
587                                 if (--ready_fds == 0)
588                                         break;
589                         }
590                         if (outptr != outstr)
591                                 *outptr++ = ']';
592                 }
593                 free(fds);
594                 /* This contains no useful information on SunOS.  */
595                 if (args[4]) {
596                         if (outptr < end_outstr - (10 + TIMEVAL_TEXT_BUFSIZE)) {
597                                 outptr += sprintf(outptr, "%sleft ", sep);
598                                 outptr = sprinttv(outptr, tcp, args[4], bitness, /*special:*/ 0);
599                         }
600                 }
601                 *outptr = '\0';
602                 tcp->auxstr = outstr;
603                 return RVAL_STR;
604 #undef end_outstr
605         }
606         return 0;
607 }
608
609 int
610 sys_oldselect(struct tcb *tcp)
611 {
612         long args[5];
613
614         if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
615                 tprints("[...]");
616                 return 0;
617         }
618         return decode_select(tcp, args, BITNESS_CURRENT);
619 }
620
621 #ifdef ALPHA
622 int
623 sys_osf_select(struct tcb *tcp)
624 {
625         long *args = tcp->u_arg;
626         return decode_select(tcp, args, BITNESS_32);
627 }
628 #endif
629
630 static const struct xlat epollctls[] = {
631 #ifdef EPOLL_CTL_ADD
632         { EPOLL_CTL_ADD,        "EPOLL_CTL_ADD" },
633 #endif
634 #ifdef EPOLL_CTL_MOD
635         { EPOLL_CTL_MOD,        "EPOLL_CTL_MOD" },
636 #endif
637 #ifdef EPOLL_CTL_DEL
638         { EPOLL_CTL_DEL,        "EPOLL_CTL_DEL" },
639 #endif
640         { 0,                    NULL            }
641 };
642
643 static const struct xlat epollevents[] = {
644 #ifdef EPOLLIN
645         { EPOLLIN,      "EPOLLIN"       },
646 #endif
647 #ifdef EPOLLPRI
648         { EPOLLPRI,     "EPOLLPRI"      },
649 #endif
650 #ifdef EPOLLOUT
651         { EPOLLOUT,     "EPOLLOUT"      },
652 #endif
653 #ifdef EPOLLRDNORM
654         { EPOLLRDNORM,  "EPOLLRDNORM"   },
655 #endif
656 #ifdef EPOLLRDBAND
657         { EPOLLRDBAND,  "EPOLLRDBAND"   },
658 #endif
659 #ifdef EPOLLWRNORM
660         { EPOLLWRNORM,  "EPOLLWRNORM"   },
661 #endif
662 #ifdef EPOLLWRBAND
663         { EPOLLWRBAND,  "EPOLLWRBAND"   },
664 #endif
665 #ifdef EPOLLMSG
666         { EPOLLMSG,     "EPOLLMSG"      },
667 #endif
668 #ifdef EPOLLERR
669         { EPOLLERR,     "EPOLLERR"      },
670 #endif
671 #ifdef EPOLLHUP
672         { EPOLLHUP,     "EPOLLHUP"      },
673 #endif
674 #ifdef EPOLLRDHUP
675         { EPOLLRDHUP,   "EPOLLRDHUP"    },
676 #endif
677 #ifdef EPOLLONESHOT
678         { EPOLLONESHOT, "EPOLLONESHOT"  },
679 #endif
680 #ifdef EPOLLET
681         { EPOLLET,      "EPOLLET"       },
682 #endif
683         { 0,            NULL            }
684 };
685
686 /* Not aliased to printargs_ld: we want it to have a distinct address */
687 int
688 sys_epoll_create(struct tcb *tcp)
689 {
690         return printargs_ld(tcp);
691 }
692
693 static const struct xlat epollflags[] = {
694 #ifdef EPOLL_CLOEXEC
695         { EPOLL_CLOEXEC,        "EPOLL_CLOEXEC" },
696 #endif
697 #ifdef EPOLL_NONBLOCK
698         { EPOLL_NONBLOCK,       "EPOLL_NONBLOCK"        },
699 #endif
700         { 0,            NULL            }
701 };
702
703 int
704 sys_epoll_create1(struct tcb *tcp)
705 {
706         if (entering(tcp))
707                 printflags(epollflags, tcp->u_arg[0], "EPOLL_???");
708         return 0;
709 }
710
711 #ifdef HAVE_SYS_EPOLL_H
712 static void
713 print_epoll_event(struct epoll_event *ev)
714 {
715         tprints("{");
716         printflags(epollevents, ev->events, "EPOLL???");
717         /* We cannot know what format the program uses, so print u32 and u64
718            which will cover every value.  */
719         tprintf(", {u32=%" PRIu32 ", u64=%" PRIu64 "}}",
720                 ev->data.u32, ev->data.u64);
721 }
722 #endif
723
724 int
725 sys_epoll_ctl(struct tcb *tcp)
726 {
727         if (entering(tcp)) {
728                 printfd(tcp, tcp->u_arg[0]);
729                 tprints(", ");
730                 printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???");
731                 tprints(", ");
732                 printfd(tcp, tcp->u_arg[2]);
733                 tprints(", ");
734                 if (tcp->u_arg[3] == 0)
735                         tprints("NULL");
736                 else {
737 #ifdef HAVE_SYS_EPOLL_H
738                         struct epoll_event ev;
739                         if (umove(tcp, tcp->u_arg[3], &ev) == 0)
740                                 print_epoll_event(&ev);
741                         else
742 #endif
743                                 tprints("{...}");
744                 }
745         }
746         return 0;
747 }
748
749 static void
750 epoll_wait_common(struct tcb *tcp)
751 {
752         if (entering(tcp)) {
753                 printfd(tcp, tcp->u_arg[0]);
754                 tprints(", ");
755         } else {
756                 if (syserror(tcp))
757                         tprintf("%lx", tcp->u_arg[1]);
758                 else if (tcp->u_rval == 0)
759                         tprints("{}");
760                 else {
761 #ifdef HAVE_SYS_EPOLL_H
762                         struct epoll_event ev, *start, *cur, *end;
763                         int failed = 0;
764
765                         tprints("{");
766                         start = (struct epoll_event *) tcp->u_arg[1];
767                         end = start + tcp->u_rval;
768                         for (cur = start; cur < end; ++cur) {
769                                 if (cur > start)
770                                         tprints(", ");
771                                 if (umove(tcp, (long) cur, &ev) == 0)
772                                         print_epoll_event(&ev);
773                                 else {
774                                         tprints("?");
775                                         failed = 1;
776                                         break;
777                                 }
778                         }
779                         tprints("}");
780                         if (failed)
781                                 tprintf(" %#lx", (long) start);
782 #else
783                         tprints("{...}");
784 #endif
785                 }
786                 tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]);
787         }
788 }
789
790 int
791 sys_epoll_wait(struct tcb *tcp)
792 {
793         epoll_wait_common(tcp);
794         return 0;
795 }
796
797 int
798 sys_epoll_pwait(struct tcb *tcp)
799 {
800         epoll_wait_common(tcp);
801         if (exiting(tcp)) {
802                 tprints(", ");
803                 /* NB: kernel requires arg[5] == NSIG / 8 */
804                 print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]);
805                 tprintf(", %lu", tcp->u_arg[5]);
806         }
807         return 0;
808 }
809
810 int
811 sys_select(struct tcb *tcp)
812 {
813         return decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
814 }
815
816 int
817 sys_pselect6(struct tcb *tcp)
818 {
819         int rc = decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
820         if (entering(tcp)) {
821                 long r;
822                 struct {
823                         unsigned long ptr;
824                         unsigned long len;
825                 } data;
826 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
827                 if (current_wordsize == 4) {
828                         struct {
829                                 uint32_t ptr;
830                                 uint32_t len;
831                         } data32;
832                         r = umove(tcp, tcp->u_arg[5], &data32);
833                         data.ptr = data32.ptr;
834                         data.len = data32.len;
835                 } else
836 #endif
837                         r = umove(tcp, tcp->u_arg[5], &data);
838                 if (r < 0)
839                         tprintf(", %#lx", tcp->u_arg[5]);
840                 else {
841                         tprints(", {");
842                         /* NB: kernel requires data.len == NSIG / 8 */
843                         print_sigset_addr_len(tcp, data.ptr, data.len);
844                         tprintf(", %lu}", data.len);
845                 }
846         }
847         return rc;
848 }
849
850 static int
851 do_eventfd(struct tcb *tcp, int flags_arg)
852 {
853         if (entering(tcp)) {
854                 tprintf("%lu", tcp->u_arg[0]);
855                 if (flags_arg >= 0) {
856                         tprints(", ");
857                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
858                 }
859         }
860         return 0;
861 }
862
863 int
864 sys_eventfd(struct tcb *tcp)
865 {
866         return do_eventfd(tcp, -1);
867 }
868
869 int
870 sys_eventfd2(struct tcb *tcp)
871 {
872         return do_eventfd(tcp, 1);
873 }
874
875 int
876 sys_perf_event_open(struct tcb *tcp)
877 {
878         if (entering(tcp)) {
879                 tprintf("%#lx, %d, %d, %d, ",
880                         tcp->u_arg[0],
881                         (int) tcp->u_arg[1],
882                         (int) tcp->u_arg[2],
883                         (int) tcp->u_arg[3]);
884                 printflags(perf_event_open_flags, tcp->u_arg[4],
885                            "PERF_FLAG_???");
886         }
887         return 0;
888 }