d4c7ab04dc4dc7db74a85be30f3a0983e0643496
[lttng-modules.git] / instrumentation / syscalls / headers / syscalls_pointers_override.h
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) */
2
3 #ifndef CREATE_SYSCALL_TABLE
4
5 #define OVERRIDE_32_execve
6 #define OVERRIDE_64_execve
7 SC_LTTNG_TRACEPOINT_EVENT(execve,
8 TP_PROTO(sc_exit(long ret,) const char *filename, char *const *argv, char *const *envp),
9 TP_ARGS(sc_exit(ret,) filename, argv, envp),
10 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
11 sc_in(ctf_user_string(filename, filename))
12 sc_in(ctf_integer_hex(char *const *, argv, argv))
13 sc_in(ctf_integer_hex(char *const *, envp, envp))
14 )
15 )
16
17 #define OVERRIDE_32_clone
18 #define OVERRIDE_64_clone
19 SC_LTTNG_TRACEPOINT_EVENT(clone,
20 TP_PROTO(sc_exit(long ret,) unsigned long clone_flags, unsigned long newsp,
21 void __user *parent_tid,
22 void __user *child_tid),
23 TP_ARGS(sc_exit(ret,) clone_flags, newsp, parent_tid, child_tid),
24 TP_FIELDS(
25 sc_exit(ctf_integer(long, ret, ret))
26 sc_in(ctf_integer_hex(unsigned long, clone_flags, clone_flags))
27 sc_in(ctf_integer_hex(unsigned long, newsp, newsp))
28 sc_in(ctf_integer_hex(void *, parent_tid, parent_tid))
29 sc_in(ctf_integer_hex(void *, child_tid, child_tid))
30 )
31 )
32
33 /* present in 32, missing in 64 due to old kernel headers */
34 #define OVERRIDE_32_getcpu
35 #define OVERRIDE_64_getcpu
36 SC_LTTNG_TRACEPOINT_EVENT(getcpu,
37 TP_PROTO(sc_exit(long ret,) unsigned __user *cpup, unsigned __user *nodep, void *tcache),
38 TP_ARGS(sc_exit(ret,) cpup, nodep, tcache),
39 TP_FIELDS(
40 sc_exit(ctf_integer(long, ret, ret))
41 sc_out(ctf_integer_hex(unsigned *, cpup, cpup))
42 sc_out(ctf_integer_hex(unsigned *, nodep, nodep))
43 sc_inout(ctf_integer_hex(void *, tcache, tcache))
44 )
45 )
46
47 #define OVERRIDE_32_pipe2
48 #define OVERRIDE_64_pipe2
49 SC_LTTNG_TRACEPOINT_EVENT(pipe2,
50 TP_PROTO(sc_exit(long ret,) int * fildes, int flags),
51 TP_ARGS(sc_exit(ret,) fildes, flags),
52 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
53 sc_out(ctf_user_array(int, fildes, fildes, 2))
54 sc_in(ctf_integer(int, flags, flags))
55 )
56 )
57
58 #define LTTNG_SYSCALL_SELECT_locvar \
59 unsigned long *fds_in, *fds_out, *fds_ex; \
60 unsigned long nr_bytes, nr_ulong; \
61 uint8_t overflow;
62
63 #define LTTNG_SYSCALL_SELECT_code_pre \
64 sc_inout( \
65 { \
66 int err; \
67 unsigned int n_in_bytes; \
68 \
69 tp_locvar->fds_in = NULL; \
70 tp_locvar->fds_out = NULL; \
71 tp_locvar->fds_ex = NULL; \
72 tp_locvar->overflow = 0; \
73 \
74 sc_out( \
75 if (ret <= 0) \
76 goto error; \
77 ) \
78 \
79 if (n <= 0) \
80 goto error; \
81 \
82 /* On error or bogus input, don't copy anything. */ \
83 if (n >__FD_SETSIZE) \
84 goto error; \
85 \
86 n_in_bytes = DIV_ROUND_UP((unsigned int) n, BITS_PER_BYTE); \
87 \
88 /* \
89 * Limit atomic memory allocation to one page, since n \
90 * is limited to 1024 and the smallest page size on Linux \
91 * is 4k, this should not happen, don't try to make it work. \
92 */ \
93 if (n_in_bytes > PAGE_SIZE) { \
94 WARN_ON_ONCE(1); \
95 /* Inform the user that we did not output everything. */ \
96 tp_locvar->overflow = 1; \
97 goto error; \
98 } else { \
99 tp_locvar->nr_bytes = n_in_bytes; \
100 tp_locvar->nr_ulong = DIV_ROUND_UP(n_in_bytes, \
101 sizeof(unsigned long)); \
102 } \
103 \
104 if (inp) { \
105 tp_locvar->fds_in = lttng_tp_mempool_alloc( \
106 tp_locvar->nr_ulong * sizeof(unsigned long)); \
107 if (!tp_locvar->fds_in) \
108 goto error; \
109 \
110 err = lib_ring_buffer_copy_from_user_check_nofault( \
111 tp_locvar->fds_in, inp, \
112 tp_locvar->nr_ulong * sizeof(unsigned long)); \
113 if (err != 0) \
114 goto error; \
115 } \
116 if (outp) { \
117 tp_locvar->fds_out = lttng_tp_mempool_alloc( \
118 tp_locvar->nr_ulong * sizeof(unsigned long)); \
119 if (!tp_locvar->fds_out) \
120 goto error; \
121 \
122 err = lib_ring_buffer_copy_from_user_check_nofault( \
123 tp_locvar->fds_out, outp, \
124 tp_locvar->nr_ulong * sizeof(unsigned long)); \
125 if (err != 0) \
126 goto error; \
127 } \
128 if (exp) { \
129 tp_locvar->fds_ex = lttng_tp_mempool_alloc( \
130 tp_locvar->nr_ulong * sizeof(unsigned long)); \
131 if (!tp_locvar->fds_ex) \
132 goto error; \
133 \
134 err = lib_ring_buffer_copy_from_user_check_nofault( \
135 tp_locvar->fds_ex, exp, \
136 tp_locvar->nr_ulong * sizeof(unsigned long)); \
137 if (err != 0) \
138 goto error; \
139 } \
140 goto end; \
141 \
142 error: \
143 tp_locvar->nr_bytes = 0; \
144 tp_locvar->nr_ulong = 0; \
145 end: ; /* Label at end of compound statement. */ \
146 } \
147 )
148
149 #define LTTNG_SYSCALL_SELECT_fds_field_LE(name, input) \
150 ctf_custom_field( \
151 ctf_custom_type( \
152 .atype = atype_sequence, \
153 .u.sequence.length_type = __type_integer( \
154 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
155 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
156 __BYTE_ORDER, 16, none), \
157 ), \
158 name, \
159 ctf_custom_code( \
160 unsigned int src; \
161 unsigned int nr_bytes_out = 0; \
162 \
163 if (input) { \
164 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
165 ctf_align(uint8_t) \
166 } else { \
167 ctf_integer_type(uint8_t, 0) \
168 ctf_align(uint8_t) \
169 goto skip_##name; \
170 } \
171 \
172 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
173 int dst; \
174 for (dst = 0; dst < sizeof(long); dst++) { \
175 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
176 goto skip_##name; \
177 } \
178 ctf_user_integer_type(uint8_t, \
179 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
180 } \
181 } \
182 skip_##name: ; \
183 ) \
184 )
185
186 #define LTTNG_SYSCALL_SELECT_fds_field_BE(name, input) \
187 ctf_custom_field( \
188 ctf_custom_type( \
189 .atype = atype_sequence, \
190 .u.sequence.length_type = __type_integer( \
191 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
192 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
193 __BYTE_ORDER, 16, none), \
194 ), \
195 name, \
196 ctf_custom_code( \
197 unsigned int src, nr_bytes_out = 0; \
198 \
199 if (input) { \
200 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
201 ctf_align(uint8_t) \
202 } else { \
203 ctf_integer_type(uint8_t, 0) \
204 ctf_align(uint8_t) \
205 goto skip_##name; \
206 } \
207 \
208 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
209 int dst; \
210 for (dst = sizeof(long); dst >= 0; dst--) { \
211 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
212 goto skip_##name; \
213 } \
214 ctf_user_integer_type(uint8_t, \
215 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
216 } \
217 } \
218 skip_##name: ; \
219 ) \
220 )
221
222 #define LTTNG_SYSCALL_SELECT_code_post \
223 lttng_tp_mempool_free(tp_locvar->fds_in); \
224 lttng_tp_mempool_free(tp_locvar->fds_out); \
225 lttng_tp_mempool_free(tp_locvar->fds_ex);
226
227 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
228 #define OVERRIDE_32_select
229 #define OVERRIDE_64_select
230 SC_LTTNG_TRACEPOINT_EVENT_CODE(select,
231 TP_PROTO(sc_exit(long ret,) int n, fd_set __user *inp, fd_set __user *outp,
232 fd_set __user *exp, struct timeval *tvp),
233 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp),
234 TP_locvar(
235 LTTNG_SYSCALL_SELECT_locvar
236 ),
237 TP_code_pre(
238 LTTNG_SYSCALL_SELECT_code_pre
239 ),
240 TP_FIELDS(
241 sc_exit(ctf_integer(long, ret, ret))
242 sc_in(ctf_integer(int, n, n))
243 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
244 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
245
246 sc_inout(
247 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
248 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
249 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
250 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
251 #else
252 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
253 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
254 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
255 #endif
256 )
257 ),
258 TP_code_post(
259 LTTNG_SYSCALL_SELECT_code_post
260 )
261 )
262 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
263
264 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
265 #define OVERRIDE_32_pselect6
266 #define OVERRIDE_64_pselect6
267 SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6,
268 TP_PROTO(sc_exit(long ret,) int n, fd_set __user * inp, fd_set __user * outp,
269 fd_set __user * exp, struct timeval __user * tvp, void __user * sig),
270 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp, sig),
271 TP_locvar(
272 LTTNG_SYSCALL_SELECT_locvar
273 ),
274 TP_code_pre(
275 LTTNG_SYSCALL_SELECT_code_pre
276 ),
277 TP_FIELDS(
278 sc_exit(ctf_integer(long, ret, ret))
279 sc_in(ctf_integer(int, n, n))
280 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
281 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
282 sc_in(ctf_integer_hex(void *, sig, sig))
283
284 sc_inout(
285 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
286 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
287 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
288 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
289 #else
290 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
291 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
292 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
293 #endif
294 )
295 ),
296 TP_code_post(
297 LTTNG_SYSCALL_SELECT_code_post
298 )
299 )
300 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
301
302 #ifndef ONCE_LTTNG_TRACE_POLL_H
303 #define ONCE_LTTNG_TRACE_POLL_H
304
305 #define LTTNG_POLL_NRFLAGS (POLLNVAL + 1)
306 #define POLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \
307 ilog2(LTTNG_POLL_NRFLAGS - 1)
308
309 /*
310 * Only extract the values specified by iBCS2 for now.
311 */
312 static struct lttng_event_field lttng_pollfd_flag_fields[] = {
313 [ilog2(POLLIN)] = {
314 .name = "POLLIN",
315 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
316 },
317 [ilog2(POLLPRI)] = {
318 .name = "POLLPRI",
319 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
320 },
321 [ilog2(POLLOUT)] = {
322 .name = "POLLOUT",
323 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
324 },
325 [ilog2(POLLERR)] = {
326 .name = "POLLERR",
327 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
328 },
329 [ilog2(POLLHUP)] = {
330 .name = "POLLHUP",
331 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
332 },
333 [ilog2(POLLNVAL)] = {
334 .name = "POLLNVAL",
335 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
336 },
337 [ilog2(LTTNG_POLL_NRFLAGS)] = {
338 .name = "padding",
339 .type = __type_integer(int, POLL_FLAGS_PADDING_SIZE, 1, 0,
340 __LITTLE_ENDIAN, 10, none),
341 },
342 };
343
344 static struct lttng_event_field lttng_pollfd_fields[] = {
345 [0] = {
346 .name = "fd",
347 .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none),
348 },
349 [1] = {
350 .name = "raw_events",
351 .type = __type_integer(short, 0, 0, 0, __BYTE_ORDER, 16, none),
352 },
353 [2] = {
354 .name = "events",
355 .type = {
356 .atype = atype_struct,
357 .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_flag_fields),
358 .u._struct.fields = lttng_pollfd_flag_fields,
359 }
360 },
361 };
362
363 static struct lttng_type lttng_pollfd_elem = {
364 .atype = atype_struct,
365 .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_fields),
366 .u._struct.fields = lttng_pollfd_fields,
367 };
368 #endif /* ONCE_LTTNG_TRACE_POLL_H */
369
370 #define LTTNG_SYSCALL_POLL_locvar \
371 unsigned int fds_length, fds_max_len, alloc_fds; \
372 struct pollfd *fds; \
373 uint8_t overflow;
374
375 #define LTTNG_SYSCALL_POLL_code_pre \
376 BUILD_BUG_ON(((ARRAY_SIZE(lttng_pollfd_flag_fields) - 1) + \
377 POLL_FLAGS_PADDING_SIZE) != \
378 sizeof(uint8_t) * BITS_PER_BYTE); \
379 tp_locvar->fds = NULL; \
380 tp_locvar->overflow = 0; \
381 \
382 sc_in( \
383 if (nfds > PAGE_SIZE / sizeof(struct pollfd)) { \
384 tp_locvar->fds_length = PAGE_SIZE / sizeof(struct pollfd); \
385 tp_locvar->fds_max_len = PAGE_SIZE / sizeof(struct pollfd); \
386 tp_locvar->overflow = 1; \
387 } else { \
388 tp_locvar->fds_length = nfds; \
389 tp_locvar->fds_max_len = nfds; \
390 } \
391 tp_locvar->alloc_fds = tp_locvar->fds_length * sizeof(struct pollfd); \
392 ) \
393 /* \
394 * On exit, the number of active FDs is determined by ret, \
395 * nfds stays the same as the entry, but we only want to \
396 * output the FDs that are relevant. \
397 */ \
398 sc_out( \
399 if (ret <= 0 || ret > nfds) \
400 goto error; \
401 \
402 if (nfds > PAGE_SIZE / sizeof(struct pollfd)) { \
403 tp_locvar->fds_length = PAGE_SIZE / sizeof(struct pollfd); \
404 tp_locvar->fds_max_len = PAGE_SIZE / sizeof(struct pollfd); \
405 tp_locvar->overflow = 1; \
406 } else { \
407 tp_locvar->fds_length = ret; \
408 tp_locvar->fds_max_len = nfds; \
409 } \
410 tp_locvar->alloc_fds = tp_locvar->fds_max_len * sizeof(struct pollfd); \
411 ) \
412 { \
413 int err; \
414 \
415 tp_locvar->fds = lttng_tp_mempool_alloc(tp_locvar->alloc_fds); \
416 if (!tp_locvar->fds) \
417 goto error; \
418 err = lib_ring_buffer_copy_from_user_check_nofault( \
419 tp_locvar->fds, ufds, tp_locvar->alloc_fds); \
420 if (err != 0) \
421 goto error; \
422 } \
423 goto end; \
424 \
425 error: \
426 tp_locvar->fds_length = 0; \
427 tp_locvar->fds_max_len = 0; \
428 end: \
429 ;
430
431 #define LTTNG_SYSCALL_POLL_fds_field \
432 sc_in( \
433 ctf_custom_field( \
434 ctf_custom_type( \
435 .atype = atype_sequence_compound, \
436 .u.sequence_compound.length_name = "fds_length", \
437 .u.sequence_compound.elem_type = &lttng_pollfd_elem, \
438 ), \
439 fds, \
440 ctf_custom_code( \
441 uint32_t i; \
442 \
443 ctf_align(int) /* Align on largest field in struct. */ \
444 for (i = 0; i < tp_locvar->fds_length; i++) { \
445 ctf_integer_type(int, tp_locvar->fds[i].fd) \
446 ctf_integer_type(short, tp_locvar->fds[i].events) \
447 ctf_integer_bitfield_type(uint8_t, \
448 (uint8_t) tp_locvar->fds[i].events) \
449 } \
450 ) \
451 ) \
452 ) \
453 sc_out( \
454 ctf_custom_field( \
455 ctf_custom_type( \
456 .atype = atype_sequence_compound, \
457 .u.sequence_compound.length_name = "fds_length", \
458 .u.sequence_compound.elem_type = &lttng_pollfd_elem, \
459 ), \
460 fds, \
461 ctf_custom_code( \
462 unsigned int i, nr = 0; \
463 \
464 ctf_align(int) /* Align on largest field in struct. */ \
465 /* \
466 * Iterate over the complete array, but only output \
467 * "ret" active FDs. \
468 */ \
469 for (i = 0; i < tp_locvar->fds_max_len; i++) { \
470 if (!tp_locvar->fds[i].revents) \
471 continue; \
472 if (nr++ >= tp_locvar->fds_length) \
473 break; \
474 ctf_integer_type(int, tp_locvar->fds[i].fd) \
475 ctf_integer_type(short, tp_locvar->fds[i].revents) \
476 ctf_integer_bitfield_type(uint8_t, \
477 (uint8_t) tp_locvar->fds[i].revents) \
478 } \
479 /* \
480 * If there is a discrepancy between ret and the \
481 * content of revents (e.g. caused by userspace corrupting \
482 * the array from a concurrent thread), we have to output \
483 * zeros to keep the trace readable. \
484 */ \
485 for (i = nr; i < tp_locvar->fds_length; i++) { \
486 ctf_integer_type(int, 0) \
487 ctf_integer_type(short, 0) \
488 ctf_integer_bitfield_type(uint8_t, 0) \
489 } \
490 ) \
491 ) \
492 )
493
494 #define LTTNG_SYSCALL_POLL_code_post \
495 lttng_tp_mempool_free(tp_locvar->fds);
496
497 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
498 #define OVERRIDE_32_poll
499 #define OVERRIDE_64_poll
500 SC_LTTNG_TRACEPOINT_EVENT_CODE(poll,
501 TP_PROTO(sc_exit(long ret,) struct pollfd __user * ufds,
502 unsigned int nfds, int timeout_msecs),
503 TP_ARGS(sc_exit(ret,) ufds, nfds, timeout_msecs),
504 TP_locvar(
505 LTTNG_SYSCALL_POLL_locvar
506 ),
507 TP_code_pre(
508 LTTNG_SYSCALL_POLL_code_pre
509 ),
510 TP_FIELDS(
511 sc_exit(ctf_integer(long, ret, ret))
512 sc_in(ctf_integer(int, timeout_msecs, timeout_msecs))
513 sc_inout(ctf_integer(unsigned int, nfds, nfds))
514 sc_inout(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
515 sc_in(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
516 LTTNG_SYSCALL_POLL_fds_field
517 ),
518 TP_code_post(
519 LTTNG_SYSCALL_POLL_code_post
520 )
521 )
522 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
523
524 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
525 #define OVERRIDE_32_ppoll
526 #define OVERRIDE_64_ppoll
527 SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll,
528 TP_PROTO(sc_exit(long ret,) struct pollfd __user * ufds,
529 unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize),
530 TP_ARGS(sc_exit(ret,) ufds, nfds, tsp, sigmask, sigsetsize),
531 TP_locvar(
532 LTTNG_SYSCALL_POLL_locvar
533 ),
534 TP_code_pre(
535 LTTNG_SYSCALL_POLL_code_pre
536 ),
537 TP_FIELDS(
538 sc_exit(ctf_integer(long, ret, ret))
539 sc_in(ctf_integer(struct timespec *, tsp, tsp))
540 sc_in(ctf_integer(const sigset_t *, sigmask, sigmask))
541 sc_in(ctf_integer(size_t, sigsetsize, sigsetsize))
542 sc_inout(ctf_integer(unsigned int, nfds, nfds))
543 sc_inout(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
544 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
545 LTTNG_SYSCALL_POLL_fds_field
546 ),
547 TP_code_post(
548 LTTNG_SYSCALL_POLL_code_post
549 )
550 )
551 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
552
553 #include <linux/eventpoll.h>
554
555 SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op,
556 TP_ENUM_VALUES(
557 ctf_enum_value("EPOLL_CTL_ADD", EPOLL_CTL_ADD)
558 ctf_enum_value("EPOLL_CTL_DEL", EPOLL_CTL_DEL)
559 ctf_enum_value("EPOLL_CTL_MOD", EPOLL_CTL_MOD)
560 )
561 )
562
563 #ifndef ONCE_LTTNG_TRACE_EPOLL_CTL_H
564 #define ONCE_LTTNG_TRACE_EPOLL_CTL_H
565
566 #define LTTNG_EPOLL_NRFLAGS (POLLHUP + 1)
567 #define EPOLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \
568 ilog2(LTTNG_EPOLL_NRFLAGS - 1)
569
570 /*
571 * Only extract the values specified by iBCS2 for now.
572 */
573 static struct lttng_event_field lttng_epoll_ctl_events_fields[] = {
574 /* 0x0001 */
575 [ilog2(POLLIN)] = {
576 .name = "EPOLLIN",
577 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
578 },
579 /* 0x0002 */
580 [ilog2(POLLPRI)] = {
581 .name = "EPOLLPRI",
582 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
583 },
584 /* 0x0004 */
585 [ilog2(POLLOUT)] = {
586 .name = "EPOLLOUT",
587 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
588 },
589 /* 0x0008 */
590 [ilog2(POLLERR)] = {
591 .name = "EPOLLERR",
592 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
593 },
594 /* 0x0010 */
595 [ilog2(POLLHUP)] = {
596 .name = "EPOLLHUP",
597 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
598 },
599 [ilog2(LTTNG_EPOLL_NRFLAGS)] = {
600 .name = "padding",
601 .type = __type_integer(int, EPOLL_FLAGS_PADDING_SIZE, 1, 0,
602 __LITTLE_ENDIAN, 10, none),
603 },
604
605 };
606
607 static struct lttng_event_field lttng_epoll_data_fields[] = {
608 [0] = {
609 .name = "u64",
610 .type = __type_integer(uint64_t, 0, 0, 0, __BYTE_ORDER, 16, none),
611 },
612 [1] = {
613 .name = "fd",
614 .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none),
615 },
616 };
617
618 static struct lttng_event_field epoll_ctl_fields[] = {
619 [0] = {
620 .name = "data_union",
621 .type = {
622 .atype = atype_struct,
623 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields),
624 .u._struct.fields = lttng_epoll_data_fields,
625 }
626 },
627 [1] = {
628 .name = "raw_events",
629 .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none),
630 },
631 [2] = {
632 .name = "events",
633 .type = {
634 .atype = atype_struct,
635 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields),
636 .u._struct.fields = lttng_epoll_ctl_events_fields,
637 }
638 },
639 };
640 #endif /* ONCE_LTTNG_TRACE_EPOLL_CTL_H */
641
642 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
643 #define OVERRIDE_32_epoll_ctl
644 #define OVERRIDE_64_epoll_ctl
645 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_ctl,
646 TP_PROTO(sc_exit(long ret,) int epfd, int op, int fd,
647 struct epoll_event __user * uevent),
648 TP_ARGS(sc_exit(ret,) epfd, op, fd, uevent),
649 TP_locvar(
650 struct epoll_event event;
651 int err;
652 ),
653 TP_code_pre(
654 tp_locvar->err = lib_ring_buffer_copy_from_user_check_nofault(
655 &tp_locvar->event, uevent, sizeof(struct epoll_event));
656 ),
657 TP_FIELDS(
658 sc_exit(ctf_integer(long, ret, ret))
659 sc_in(ctf_integer(int, epfd, epfd))
660 sc_in(ctf_enum(lttng_epoll_op, int, op_enum, op))
661 sc_in(ctf_integer(int, fd, fd))
662 sc_in(
663 ctf_custom_field(
664 ctf_custom_type(
665 .atype = atype_struct,
666 .u._struct.nr_fields = ARRAY_SIZE(epoll_ctl_fields),
667 .u._struct.fields = epoll_ctl_fields,
668 ),
669 event,
670 ctf_custom_code(
671 ctf_align(uint64_t)
672 if (!tp_locvar->err) {
673 ctf_integer_type(uint64_t, tp_locvar->event.data)
674 ctf_integer_type(int, tp_locvar->event.data)
675 ctf_integer_bitfield_type(uint32_t,
676 tp_locvar->event.events)
677 ctf_integer_bitfield_type(uint8_t,
678 (uint8_t) tp_locvar->event.events)
679 } else {
680 ctf_integer_type(uint64_t, 0)
681 ctf_integer_type(int, 0)
682 ctf_integer_bitfield_type(uint32_t, 0)
683 ctf_integer_bitfield_type(uint8_t, 0)
684 }
685 )
686 )
687 )
688 ),
689 TP_code_post()
690 )
691 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
692
693 #ifndef ONCE_LTTNG_TRACE_EPOLL_H
694 #define ONCE_LTTNG_TRACE_EPOLL_H
695
696 static struct lttng_event_field lttng_epoll_wait_fields[] = {
697 [0] = {
698 .name = "data_union",
699 .type = {
700 .atype = atype_struct,
701 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields),
702 .u._struct.fields = lttng_epoll_data_fields,
703 }
704 },
705 [1] = {
706 .name = "raw_events",
707 .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none),
708 },
709 [2] = {
710 .name = "events",
711 .type = {
712 .atype = atype_struct,
713 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields),
714 .u._struct.fields = lttng_epoll_ctl_events_fields,
715 }
716 },
717 };
718
719 static struct lttng_type lttng_epoll_wait_elem = {
720 .atype = atype_struct,
721 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_wait_fields),
722 .u._struct.fields = lttng_epoll_wait_fields,
723 };
724
725 #endif /* ONCE_LTTNG_TRACE_EPOLL_H */
726
727 #define LTTNG_SYSCALL_EPOLL_WAIT_locvar \
728 sc_out( \
729 unsigned int fds_length; \
730 uint8_t overflow; \
731 struct epoll_event *events; \
732 )
733
734 #define LTTNG_SYSCALL_EPOLL_WAIT_code_pre \
735 BUILD_BUG_ON(((ARRAY_SIZE(lttng_epoll_ctl_events_fields) - 1) + \
736 EPOLL_FLAGS_PADDING_SIZE) != \
737 sizeof(uint8_t) * BITS_PER_BYTE); \
738 sc_out({ \
739 int err; \
740 unsigned long maxalloc; \
741 \
742 tp_locvar->fds_length = 0; \
743 tp_locvar->events = NULL; \
744 tp_locvar->overflow = 0; \
745 \
746 if (maxevents <= 0 || ret <= 0 || ret > maxevents) \
747 goto skip_code; \
748 \
749 if (maxevents > PAGE_SIZE / sizeof(struct epoll_event)) { \
750 maxalloc = PAGE_SIZE / sizeof(struct epoll_event); \
751 } else { \
752 maxalloc = maxevents; \
753 } \
754 \
755 if (ret > maxalloc) { \
756 tp_locvar->fds_length = maxalloc; \
757 tp_locvar->overflow = 1; \
758 } else { \
759 tp_locvar->fds_length = ret; \
760 } \
761 \
762 tp_locvar->events = lttng_tp_mempool_alloc( \
763 maxalloc * sizeof(struct epoll_event)); \
764 if (!tp_locvar->events) { \
765 tp_locvar->fds_length = 0; \
766 goto skip_code; \
767 } \
768 \
769 err = lib_ring_buffer_copy_from_user_check_nofault( \
770 tp_locvar->events, uevents, \
771 maxalloc * sizeof(struct epoll_event)); \
772 if (err != 0) \
773 tp_locvar->fds_length = 0; \
774 } \
775 skip_code: \
776 )
777
778 #define LTTNG_SYSCALL_EPOLL_WAIT_fds_field \
779 ctf_custom_field( \
780 ctf_custom_type( \
781 .atype = atype_sequence_compound, \
782 .u.sequence_compound.length_name = \
783 "fds_length", \
784 .u.sequence_compound.elem_type = \
785 &lttng_epoll_wait_elem, \
786 ), \
787 fds, \
788 ctf_custom_code( \
789 uint32_t i; \
790 \
791 ctf_align(uint64_t) \
792 for (i = 0; i < tp_locvar->fds_length; i++) { \
793 ctf_integer_type(uint64_t, tp_locvar->events[i].data) \
794 ctf_integer_type(int, tp_locvar->events[i].data) \
795 ctf_integer_bitfield_type(uint32_t, \
796 tp_locvar->events[i].events) \
797 ctf_integer_bitfield_type(uint8_t, \
798 (uint8_t) tp_locvar->events[i].events) \
799 } \
800 ) \
801 )
802
803 #define LTTNG_SYSCALL_EPOLL_WAIT_code_post \
804 sc_out( \
805 lttng_tp_mempool_free(tp_locvar->events); \
806 )
807
808
809 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
810 #define OVERRIDE_32_epoll_wait
811 #define OVERRIDE_64_epoll_wait
812 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_wait,
813 TP_PROTO(sc_exit(long ret,) int epfd, struct epoll_event __user * uevents,
814 int maxevents, int timeout),
815 TP_ARGS(sc_exit(ret,) epfd, uevents, maxevents, timeout),
816 TP_locvar(
817 LTTNG_SYSCALL_EPOLL_WAIT_locvar
818 ),
819 TP_code_pre(
820 LTTNG_SYSCALL_EPOLL_WAIT_code_pre
821 ),
822 TP_FIELDS(
823 sc_exit(ctf_integer(long, ret, ret))
824 sc_in(ctf_integer(int, epfd, epfd))
825 sc_in(ctf_integer(int, maxevents, maxevents))
826 sc_in(ctf_integer(int, timeout, timeout))
827 sc_out(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
828 sc_out(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
829 sc_out(
830 LTTNG_SYSCALL_EPOLL_WAIT_fds_field
831 )
832 ),
833 TP_code_post(
834 LTTNG_SYSCALL_EPOLL_WAIT_code_post
835 )
836 )
837 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
838
839 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
840 #define OVERRIDE_32_epoll_pwait
841 #define OVERRIDE_64_epoll_pwait
842 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_pwait,
843 TP_PROTO(sc_exit(long ret,) int epfd, struct epoll_event __user * uevents,
844 int maxevents, int timeout, const sigset_t __user * sigmask, size_t sigsetsize),
845 TP_ARGS(sc_exit(ret,) epfd, uevents, maxevents, timeout, sigmask, sigsetsize),
846 TP_locvar(
847 LTTNG_SYSCALL_EPOLL_WAIT_locvar
848 ),
849 TP_code_pre(
850 LTTNG_SYSCALL_EPOLL_WAIT_code_pre
851 ),
852 TP_FIELDS(
853 sc_exit(ctf_integer(long, ret, ret))
854 sc_in(ctf_integer(int, epfd, epfd))
855 sc_in(ctf_integer(int, maxevents, maxevents))
856 sc_in(ctf_integer(int, timeout, timeout))
857 sc_in(ctf_integer_hex(const sigset_t *, sigmask, sigmask))
858 sc_in(ctf_integer(size_t, sigsetsize, sigsetsize))
859 sc_out(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
860 sc_out(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
861 sc_out(
862 LTTNG_SYSCALL_EPOLL_WAIT_fds_field
863 )
864 ),
865 TP_code_post(
866 LTTNG_SYSCALL_EPOLL_WAIT_code_post
867 )
868 )
869 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
870
871 #if (defined(CONFIG_X86_64) && !defined(LTTNG_SC_COMPAT)) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
872 #define OVERRIDE_32_socketpair
873 #define OVERRIDE_64_socketpair
874 SC_LTTNG_TRACEPOINT_EVENT(socketpair,
875 TP_PROTO(sc_exit(long ret,) int family, int type, int protocol, int *usockvec),
876 TP_ARGS(sc_exit(ret,) family, type, protocol, usockvec),
877 TP_FIELDS(
878 sc_exit(ctf_integer(long, ret, ret))
879 sc_in(ctf_integer(int, family, family))
880 sc_in(ctf_integer(int, type, type))
881 sc_in(ctf_integer(int, protocol, protocol))
882 sc_out(ctf_user_array(int, socket, usockvec, 2))
883 )
884 )
885 #endif /* (defined(CONFIG_X86_64) && !defined(LTTNG_SC_COMPAT)) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
886
887 /*
888 * Enumeration of the open flags, as described in the 'open'
889 * system call man page.
890 */
891 SC_LTTNG_TRACEPOINT_ENUM(lttng_file_status_flags,
892 TP_ENUM_VALUES(
893 ctf_enum_value("O_RDONLY", O_RDONLY)
894 ctf_enum_value("O_WRONLY", O_WRONLY)
895 ctf_enum_value("O_RDWR", O_RDWR)
896 ctf_enum_value("O_CREAT", O_CREAT)
897 ctf_enum_value("O_EXCL", O_EXCL)
898 ctf_enum_value("O_NOCTTY", O_NOCTTY)
899 ctf_enum_value("O_TRUNC", O_TRUNC)
900 ctf_enum_value("O_APPEND", O_APPEND)
901 ctf_enum_value("O_NONBLOCK", O_NONBLOCK)
902 ctf_enum_value("O_DSYNC", O_DSYNC)
903 ctf_enum_value("FASYNC", FASYNC)
904 ctf_enum_value("O_DIRECT", O_DIRECT)
905 ctf_enum_value("O_LARGEFILE", O_LARGEFILE)
906 ctf_enum_value("O_DIRECTORY", O_DIRECTORY)
907 ctf_enum_value("O_NOFOLLOW", O_NOFOLLOW)
908 ctf_enum_value("O_NOATIME", O_NOATIME)
909 ctf_enum_value("O_CLOEXEC", O_CLOEXEC)
910 ctf_enum_value("O_SYNC", __O_SYNC)
911 ctf_enum_value("O_PATH", O_PATH)
912 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0))
913 ctf_enum_value("O_TMPFILE", __O_TMPFILE)
914 #endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) */
915 )
916 )
917
918 /*
919 * Enumeration of the open flags, as described in the 'open'
920 * system call man page.
921 */
922 SC_LTTNG_TRACEPOINT_ENUM(lttng_file_mode,
923 TP_ENUM_VALUES(
924 ctf_enum_value("S_IRWXU", S_IRWXU)
925 ctf_enum_value("S_IRUSR", S_IRUSR)
926 ctf_enum_value("S_IWUSR", S_IWUSR)
927 ctf_enum_value("S_IXUSR", S_IXUSR)
928 ctf_enum_value("S_IRWXG", S_IRWXG)
929 ctf_enum_value("S_IRGRP", S_IRGRP)
930 ctf_enum_value("S_IWGRP", S_IWGRP)
931 ctf_enum_value("S_IXGRP", S_IXGRP)
932 ctf_enum_value("S_IRWXO", S_IRWXO)
933 ctf_enum_value("S_IROTH", S_IROTH)
934 ctf_enum_value("S_IWOTH", S_IWOTH)
935 ctf_enum_value("S_IXOTH", S_IXOTH)
936 ctf_enum_value("S_ISUID", S_ISUID)
937 ctf_enum_value("S_ISGID", S_ISGID)
938 ctf_enum_value("S_ISVTX", S_ISVTX)
939 )
940 )
941
942 #define OVERRIDE_32_openat
943 #define OVERRIDE_64_openat
944 SC_LTTNG_TRACEPOINT_EVENT(openat,
945 TP_PROTO(sc_exit(long ret,) int dfd, const char * filename, int flags, umode_t mode),
946 TP_ARGS(sc_exit(ret,) dfd, filename, flags, mode),
947 TP_FIELDS(
948 sc_exit(ctf_integer(long, ret, ret))
949 sc_in(ctf_integer(int, dfd, dfd))
950 sc_in(ctf_user_string(filename, filename))
951 sc_in(ctf_enum(lttng_file_status_flags, int, flags, flags))
952 sc_in(ctf_enum(lttng_file_mode, umode_t, mode, mode))
953 )
954 )
955
956 #define OVERRIDE_32_open
957 #define OVERRIDE_64_open
958 SC_LTTNG_TRACEPOINT_EVENT(open,
959 TP_PROTO(sc_exit(long ret,) const char * filename, int flags, umode_t mode),
960 TP_ARGS(sc_exit(ret,) filename, flags, mode),
961 TP_FIELDS(
962 sc_exit(ctf_integer(long, ret, ret))
963 sc_in(ctf_user_string(filename, filename))
964 sc_in(ctf_enum(lttng_file_status_flags, int, flags, flags))
965 sc_in(ctf_enum(lttng_file_mode, umode_t, mode, mode))
966 )
967 )
968
969 #endif /* CREATE_SYSCALL_TABLE */
This page took 0.055918 seconds and 3 git commands to generate.