Extract the FD sets in select and pselect6
[lttng-modules.git] / instrumentation / syscalls / headers / syscalls_pointers_override.h
CommitLineData
e42e81fd
MD
1#ifndef CREATE_SYSCALL_TABLE
2
769ad370
MD
3#define OVERRIDE_32_execve
4#define OVERRIDE_64_execve
cb3ef14c 5SC_LTTNG_TRACEPOINT_EVENT(execve,
e17f92ba
MD
6 TP_PROTO(sc_exit(long ret,) const char *filename, char *const *argv, char *const *envp),
7 TP_ARGS(sc_exit(ret,) filename, argv, envp),
57ede728
MD
8 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
9 sc_in(ctf_user_string(filename, filename))
10 sc_in(ctf_integer_hex(char *const *, argv, argv))
11 sc_in(ctf_integer_hex(char *const *, envp, envp))
12 )
e42e81fd
MD
13)
14
769ad370
MD
15#define OVERRIDE_32_clone
16#define OVERRIDE_64_clone
cb3ef14c 17SC_LTTNG_TRACEPOINT_EVENT(clone,
e17f92ba 18 TP_PROTO(sc_exit(long ret,) unsigned long clone_flags, unsigned long newsp,
ba21566b 19 void __user *parent_tid,
b5aa4b6a 20 void __user *child_tid),
e17f92ba 21 TP_ARGS(sc_exit(ret,) clone_flags, newsp, parent_tid, child_tid),
57ede728
MD
22 TP_FIELDS(
23 sc_exit(ctf_integer(long, ret, ret))
24 sc_in(ctf_integer_hex(unsigned long, clone_flags, clone_flags))
25 sc_in(ctf_integer_hex(unsigned long, newsp, newsp))
26 sc_in(ctf_integer_hex(void *, parent_tid, parent_tid))
27 sc_in(ctf_integer_hex(void *, child_tid, child_tid))
28 )
ba21566b
MD
29)
30
b5aa4b6a 31/* present in 32, missing in 64 due to old kernel headers */
644d6e9c
MD
32#define OVERRIDE_32_getcpu
33#define OVERRIDE_64_getcpu
cb3ef14c 34SC_LTTNG_TRACEPOINT_EVENT(getcpu,
e17f92ba
MD
35 TP_PROTO(sc_exit(long ret,) unsigned __user *cpup, unsigned __user *nodep, void *tcache),
36 TP_ARGS(sc_exit(ret,) cpup, nodep, tcache),
57ede728
MD
37 TP_FIELDS(
38 sc_exit(ctf_integer(long, ret, ret))
39 sc_out(ctf_integer_hex(unsigned *, cpup, cpup))
40 sc_out(ctf_integer_hex(unsigned *, nodep, nodep))
41 sc_inout(ctf_integer_hex(void *, tcache, tcache))
42 )
b5aa4b6a
MD
43)
44
af44bd3a
MD
45#define OVERRIDE_32_pipe2
46#define OVERRIDE_64_pipe2
cb3ef14c 47SC_LTTNG_TRACEPOINT_EVENT(pipe2,
af44bd3a
MD
48 TP_PROTO(sc_exit(long ret,) int * fildes, int flags),
49 TP_ARGS(sc_exit(ret,) fildes, flags),
57ede728
MD
50 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
51 sc_out(ctf_user_array(int, fildes, fildes, 2))
52 sc_in(ctf_integer(int, flags, flags))
53 )
af44bd3a
MD
54)
55
29751f7c
JD
56#define LTTNG_SYSCALL_SELECT_locvar \
57 unsigned long *fds_in, *fds_out, *fds_ex; \
58 unsigned long nr_bytes, nr_ulong; \
59 uint8_t overflow;
60
61#define LTTNG_SYSCALL_SELECT_code_pre \
62 sc_inout( \
63 { \
64 int err; \
65 unsigned int n_in_bytes; \
66 \
67 tp_locvar->fds_in = NULL; \
68 tp_locvar->fds_out = NULL; \
69 tp_locvar->fds_ex = NULL; \
70 tp_locvar->overflow = 0; \
71 \
72 sc_out( \
73 if (ret <= 0) \
74 goto error; \
75 ) \
76 \
77 if (n <= 0) \
78 goto error; \
79 \
80 /* On error or bogus input, don't copy anything. */ \
81 if (n >__FD_SETSIZE) \
82 goto error; \
83 \
84 n_in_bytes = DIV_ROUND_UP((unsigned int) n, BITS_PER_BYTE); \
85 \
86 /* \
87 * Limit atomic memory allocation to one page, since n \
88 * is limited to 1024 and the smallest page size on Linux \
89 * is 4k, this should not happen, don't try to make it work. \
90 */ \
91 if (n_in_bytes > PAGE_SIZE) { \
92 WARN_ON_ONCE(1); \
93 /* Inform the user that we did not output everything. */ \
94 tp_locvar->overflow = 1; \
95 goto error; \
96 } else { \
97 tp_locvar->nr_bytes = n_in_bytes; \
98 tp_locvar->nr_ulong = DIV_ROUND_UP(n_in_bytes, \
99 sizeof(unsigned long)); \
100 } \
101 \
102 if (inp) { \
103 tp_locvar->fds_in = kmalloc( \
104 tp_locvar->nr_ulong * sizeof(unsigned long), \
105 GFP_ATOMIC | GFP_NOWAIT); \
106 if (!tp_locvar->fds_in) \
107 goto error; \
108 \
109 err = lib_ring_buffer_copy_from_user_check_nofault( \
110 tp_locvar->fds_in, inp, \
111 tp_locvar->nr_ulong * sizeof(unsigned long)); \
112 if (err != 0) \
113 goto error; \
114 } \
115 if (outp) { \
116 tp_locvar->fds_out = kmalloc( \
117 tp_locvar->nr_ulong * sizeof(unsigned long), \
118 GFP_ATOMIC | GFP_NOWAIT); \
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 = kmalloc( \
130 tp_locvar->nr_ulong * sizeof(unsigned long), \
131 GFP_ATOMIC | GFP_NOWAIT); \
132 if (!tp_locvar->fds_ex) \
133 goto error; \
134 \
135 err = lib_ring_buffer_copy_from_user_check_nofault( \
136 tp_locvar->fds_ex, exp, \
137 tp_locvar->nr_ulong * sizeof(unsigned long)); \
138 if (err != 0) \
139 goto error; \
140 } \
141 goto end; \
142 \
143error: \
144 tp_locvar->nr_bytes = 0; \
145 tp_locvar->nr_ulong = 0; \
146end: ; /* Label at end of compound statement. */ \
147 } \
148 )
149
150#define LTTNG_SYSCALL_SELECT_fds_field_LE(name, input) \
151 ctf_custom_field( \
152 ctf_custom_type( \
153 .atype = atype_sequence, \
154 .u.sequence.length_type = __type_integer( \
155 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
156 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
157 __BYTE_ORDER, 16, none), \
158 ), \
159 name, \
160 ctf_custom_code( \
161 unsigned int src; \
162 unsigned int nr_bytes_out = 0; \
163 \
164 if (input) { \
165 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
166 ctf_align(uint8_t) \
167 } else { \
168 ctf_integer_type(uint8_t, 0) \
169 ctf_align(uint8_t) \
170 goto skip_##name; \
171 } \
172 \
173 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
174 int dst; \
175 for (dst = 0; dst < sizeof(long); dst++) { \
176 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
177 goto skip_##name; \
178 } \
179 ctf_user_integer_type(uint8_t, \
180 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
181 } \
182 } \
183 skip_##name: ; \
184 ) \
185 )
186
187#define LTTNG_SYSCALL_SELECT_fds_field_BE(name, input) \
188 ctf_custom_field( \
189 ctf_custom_type( \
190 .atype = atype_sequence, \
191 .u.sequence.length_type = __type_integer( \
192 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
193 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
194 __BYTE_ORDER, 16, none), \
195 ), \
196 name, \
197 ctf_custom_code( \
198 unsigned int src, nr_bytes_out = 0; \
199 \
200 if (input) { \
201 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
202 ctf_align(uint8_t) \
203 } else { \
204 ctf_integer_type(uint8_t, 0) \
205 ctf_align(uint8_t) \
206 goto skip_##name; \
207 } \
208 \
209 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
210 int dst; \
211 for (dst = sizeof(long); dst >= 0; dst--) { \
212 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
213 goto skip_##name; \
214 } \
215 ctf_user_integer_type(uint8_t, \
216 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
217 } \
218 } \
219 skip_##name: ; \
220 ) \
221 )
222
223#define LTTNG_SYSCALL_SELECT_code_post \
224 kfree(tp_locvar->fds_in); \
225 kfree(tp_locvar->fds_out); \
226 kfree(tp_locvar->fds_ex);
227
228#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
229#define OVERRIDE_32_select
230#define OVERRIDE_64_select
231SC_LTTNG_TRACEPOINT_EVENT_CODE(select,
232 TP_PROTO(sc_exit(long ret,) int n, fd_set __user *inp, fd_set __user *outp,
233 fd_set __user *exp, struct timeval *tvp),
234 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp),
235 TP_locvar(
236 LTTNG_SYSCALL_SELECT_locvar
237 ),
238 TP_code_pre(
239 LTTNG_SYSCALL_SELECT_code_pre
240 ),
241 TP_FIELDS(
242 sc_exit(ctf_integer(long, ret, ret))
243 sc_in(ctf_integer(int, n, n))
244 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
245 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
246
247 sc_inout(
248#if (__BYTE_ORDER == __LITTLE_ENDIAN)
249 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
250 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
251 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
252#else
253 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
254 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
255 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
256#endif
257 )
258 ),
259 TP_code_post(
260 LTTNG_SYSCALL_SELECT_code_post
261 )
262)
263#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) */
264
265#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
266#define OVERRIDE_32_pselect6
267#define OVERRIDE_64_pselect6
268SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6,
269 TP_PROTO(sc_exit(long ret,) int n, fd_set __user * inp, fd_set __user * outp,
270 fd_set __user * exp, struct timeval __user * tvp, void __user * sig),
271 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp, sig),
272 TP_locvar(
273 LTTNG_SYSCALL_SELECT_locvar
274 ),
275 TP_code_pre(
276 LTTNG_SYSCALL_SELECT_code_pre
277 ),
278 TP_FIELDS(
279 sc_exit(ctf_integer(long, ret, ret))
280 sc_in(ctf_integer(int, n, n))
281 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
282 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
283 sc_in(ctf_integer_hex(void *, sig, sig))
284
285 sc_inout(
286#if (__BYTE_ORDER == __LITTLE_ENDIAN)
287 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
288 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
289 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
290#else
291 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
292 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
293 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
294#endif
295 )
296 ),
297 TP_code_post(
298 LTTNG_SYSCALL_SELECT_code_post
299 )
300)
301#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
302
e42e81fd 303#endif /* CREATE_SYSCALL_TABLE */
This page took 0.040228 seconds and 4 git commands to generate.