]> granicus.if.org Git - strace/blob - epoll.c
Robustify mpers.awk against invalid input
[strace] / epoll.c
1 #include "defs.h"
2 #include <fcntl.h>
3 #ifdef HAVE_SYS_EPOLL_H
4 # include <sys/epoll.h>
5 #endif
6
7 SYS_FUNC(epoll_create)
8 {
9         tprintf("%d", (int) tcp->u_arg[0]);
10
11         return RVAL_DECODED | RVAL_FD;
12 }
13
14 #include "xlat/epollflags.h"
15
16 SYS_FUNC(epoll_create1)
17 {
18         printflags(epollflags, tcp->u_arg[0], "EPOLL_???");
19
20         return RVAL_DECODED | RVAL_FD;
21 }
22
23 #ifdef HAVE_SYS_EPOLL_H
24 # include "xlat/epollevents.h"
25
26 static void
27 print_epoll_event(struct epoll_event *ev)
28 {
29         tprints("{");
30         printflags(epollevents, ev->events, "EPOLL???");
31         /* We cannot know what format the program uses, so print u32 and u64
32            which will cover every value.  */
33         tprintf(", {u32=%" PRIu32 ", u64=%" PRIu64 "}}",
34                 ev->data.u32, ev->data.u64);
35 }
36 #endif
37
38 #include "xlat/epollctls.h"
39
40 SYS_FUNC(epoll_ctl)
41 {
42         struct epoll_event ev;
43
44         printfd(tcp, tcp->u_arg[0]);
45         tprints(", ");
46         printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???");
47         tprints(", ");
48         printfd(tcp, tcp->u_arg[2]);
49         tprints(", ");
50 #ifdef HAVE_SYS_EPOLL_H
51         if (EPOLL_CTL_DEL == tcp->u_arg[1])
52                 printaddr(tcp->u_arg[3]);
53         else if (!umove_or_printaddr(tcp, tcp->u_arg[3], &ev))
54                 print_epoll_event(&ev);
55 #else
56         printaddr(tcp->u_arg[3]);
57 #endif
58
59         return RVAL_DECODED;
60 }
61
62 static void
63 print_epoll_event_array(struct tcb *tcp, const long addr, const long len)
64 {
65 #ifdef HAVE_SYS_EPOLL_H
66         struct epoll_event ev, *start, *cur, *end;
67
68         if (!len) {
69                 tprints("[]");
70                 return;
71         }
72
73         if (umove_or_printaddr(tcp, addr, &ev))
74                 return;
75
76         tprints("[");
77         print_epoll_event(&ev);
78
79         start = (struct epoll_event *) addr;
80         end = start + len;
81         for (cur = start + 1; cur < end; ++cur) {
82                 tprints(", ");
83                 if (umove_or_printaddr(tcp, (long) cur, &ev))
84                         break;
85                 print_epoll_event(&ev);
86         }
87         tprints("]");
88 #else
89         printaddr(addr);
90 #endif
91 }
92
93 static void
94 epoll_wait_common(struct tcb *tcp)
95 {
96         if (entering(tcp)) {
97                 printfd(tcp, tcp->u_arg[0]);
98                 tprints(", ");
99         } else {
100                 print_epoll_event_array(tcp, tcp->u_arg[1], tcp->u_rval);
101                 tprintf(", %d, %d", (int) tcp->u_arg[2], (int) tcp->u_arg[3]);
102         }
103 }
104
105 SYS_FUNC(epoll_wait)
106 {
107         epoll_wait_common(tcp);
108         return 0;
109 }
110
111 SYS_FUNC(epoll_pwait)
112 {
113         epoll_wait_common(tcp);
114         if (exiting(tcp)) {
115                 tprints(", ");
116                 /* NB: kernel requires arg[5] == NSIG / 8 */
117                 print_sigset_addr_len(tcp, tcp->u_arg[4], tcp->u_arg[5]);
118                 tprintf(", %lu", tcp->u_arg[5]);
119         }
120         return 0;
121 }