Fix: kernels 3.0.x do not implement IS_ENABLED macro
[lttng-modules.git] / src / lttng-syscalls.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
259b6cb3
MD
3 * lttng-syscalls.c
4 *
2faf7d1b 5 * LTTng syscall probes.
259b6cb3 6 *
886d51a3 7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
259b6cb3
MD
8 */
9
10#include <linux/module.h>
11#include <linux/slab.h>
6333ace3 12#include <linux/compat.h>
abc0446a 13#include <linux/err.h>
80f87dd2 14#include <linux/bitmap.h>
7ca580f8
MD
15#include <linux/in.h>
16#include <linux/in6.h>
2d2464bd 17#include <linux/seq_file.h>
d4291869 18#include <linux/stringify.h>
082d4946
MD
19#include <linux/file.h>
20#include <linux/anon_inodes.h>
c8dfb724 21#include <linux/fcntl.h>
3cf55950 22#include <linux/mman.h>
259b6cb3
MD
23#include <asm/ptrace.h>
24#include <asm/syscall.h>
25
a071f25d 26#include <lttng/bitfield.h>
241ae9a8
MD
27#include <wrapper/tracepoint.h>
28#include <wrapper/file.h>
29#include <wrapper/rcu.h>
1b7b9c65 30#include <wrapper/syscall.h>
2df37e95 31#include <lttng/events.h>
6f156b09 32#include <lttng/events-internal.h>
8a8ac9a8 33#include <lttng/utils.h>
259b6cb3 34
ebcc64cd
FD
35#include "lttng-syscalls.h"
36
6333ace3 37#ifndef CONFIG_COMPAT
bfa949bf
MD
38# ifndef is_compat_task
39# define is_compat_task() (0)
40# endif
6333ace3
MD
41#endif
42
1aa3298b
MD
43/* in_compat_syscall appears in kernel 4.6. */
44#ifndef in_compat_syscall
45 #define in_compat_syscall() is_compat_task()
46#endif
47
5b7ac358
MD
48enum sc_type {
49 SC_TYPE_ENTRY,
50 SC_TYPE_EXIT,
51 SC_TYPE_COMPAT_ENTRY,
52 SC_TYPE_COMPAT_EXIT,
53};
54
d4291869
MD
55#define SYSCALL_ENTRY_TOK syscall_entry_
56#define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
57#define SYSCALL_EXIT_TOK syscall_exit_
58#define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
59
60#define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
61#define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
62#define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
63#define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
5b7ac358 64
2d6d88c6 65void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
2d6d88c6 66void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
259b6cb3 67
3a523f5b
MD
68/*
69 * Forward declarations for old kernels.
70 */
71struct mmsghdr;
72struct rlimit64;
73struct oldold_utsname;
74struct old_utsname;
75struct sel_arg_struct;
76struct mmap_arg_struct;
c0b71117 77struct file_handle;
a292e6f1 78struct user_msghdr;
3a523f5b 79
9eb15e8b
MJ
80/*
81 * Forward declaration for kernels >= 5.6
82 */
83struct timex;
edfdcb68
MJ
84struct timeval;
85struct itimerval;
86struct itimerspec;
87
5f4c791e 88#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
edfdcb68
MJ
89typedef __kernel_old_time_t time_t;
90#endif
9eb15e8b 91
80f87dd2
MD
92#ifdef IA32_NR_syscalls
93#define NR_compat_syscalls IA32_NR_syscalls
94#else
95#define NR_compat_syscalls NR_syscalls
96#endif
97
259b6cb3
MD
98/*
99 * Create LTTng tracepoint probes.
100 */
101#define LTTNG_PACKAGE_BUILD
102#define CREATE_TRACE_POINTS
2655f9ad 103#define TP_MODULE_NOINIT
c075712b 104#define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
259b6cb3 105
a93244f8
MD
106#define PARAMS(args...) args
107
5b7ac358 108/* Handle unknown syscalls */
72a52753 109#undef TRACE_SYSTEM
5b7ac358 110#define TRACE_SYSTEM syscalls_unknown
241ae9a8 111#include <instrumentation/syscalls/headers/syscalls_unknown.h>
5b7ac358
MD
112#undef TRACE_SYSTEM
113
5b7ac358 114#undef TP_PROBE_CB
fc4f7161 115
e42c4f49
FD
116extern const struct trace_syscall_table sc_table;
117extern const struct trace_syscall_table compat_sc_table;
5b7ac358 118
2d6d88c6 119/* Event syscall exit table */
e42c4f49
FD
120extern const struct trace_syscall_table sc_exit_table;
121extern const struct trace_syscall_table compat_sc_exit_table;
ebcc64cd
FD
122
123
fc4f7161
MD
124#undef SC_EXIT
125
a93244f8 126#undef CREATE_SYSCALL_TABLE
2faf7d1b 127
80f87dd2 128struct lttng_syscall_filter {
badfe9f5
MD
129 DECLARE_BITMAP(sc_entry, NR_syscalls);
130 DECLARE_BITMAP(sc_exit, NR_syscalls);
131 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
132 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
80f87dd2
MD
133};
134
3b82c4e1 135static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 136 struct pt_regs *regs, long id)
f405cfce 137{
1b7b9c65 138 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 139 struct lttng_kernel_event_common_private *event_priv;
f405cfce 140
1b7b9c65 141 lttng_syscall_get_arguments(current, regs, args);
a67ba386 142 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
8a8ac9a8 143 if (unlikely(in_compat_syscall()))
e2d5dbc7 144 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8 145 else
e2d5dbc7 146 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8
FD
147 }
148}
149
63aa9160 150static __always_inline
e2d5dbc7 151void syscall_entry_event_call_func(struct hlist_head *action_list,
3b82c4e1 152 void *func, unsigned int nrargs,
63aa9160 153 struct pt_regs *regs)
259b6cb3 154{
a67ba386 155 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 156
63aa9160 157 switch (nrargs) {
259b6cb3
MD
158 case 0:
159 {
63aa9160 160 void (*fptr)(void *__data) = func;
259b6cb3 161
e2d5dbc7
MD
162 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
163 fptr(event_priv->pub);
259b6cb3
MD
164 break;
165 }
166 case 1:
167 {
63aa9160 168 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 169 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 170
1b7b9c65 171 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
172 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
173 fptr(event_priv->pub, args[0]);
259b6cb3
MD
174 break;
175 }
176 case 2:
177 {
178 void (*fptr)(void *__data,
179 unsigned long arg0,
63aa9160 180 unsigned long arg1) = func;
1b7b9c65 181 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 182
1b7b9c65 183 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
184 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
185 fptr(event_priv->pub, args[0], args[1]);
259b6cb3
MD
186 break;
187 }
188 case 3:
189 {
190 void (*fptr)(void *__data,
191 unsigned long arg0,
192 unsigned long arg1,
63aa9160 193 unsigned long arg2) = func;
1b7b9c65 194 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 195
1b7b9c65 196 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
197 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
198 fptr(event_priv->pub, args[0], args[1], args[2]);
259b6cb3
MD
199 break;
200 }
201 case 4:
202 {
203 void (*fptr)(void *__data,
204 unsigned long arg0,
205 unsigned long arg1,
206 unsigned long arg2,
63aa9160 207 unsigned long arg3) = func;
1b7b9c65 208 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 209
1b7b9c65 210 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
211 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
212 fptr(event_priv->pub, args[0], args[1], args[2], args[3]);
259b6cb3
MD
213 break;
214 }
215 case 5:
216 {
217 void (*fptr)(void *__data,
218 unsigned long arg0,
219 unsigned long arg1,
220 unsigned long arg2,
221 unsigned long arg3,
63aa9160 222 unsigned long arg4) = func;
1b7b9c65 223 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 224
1b7b9c65 225 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
226 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
227 fptr(event_priv->pub, args[0], args[1], args[2], args[3], args[4]);
259b6cb3
MD
228 break;
229 }
230 case 6:
231 {
232 void (*fptr)(void *__data,
233 unsigned long arg0,
234 unsigned long arg1,
235 unsigned long arg2,
236 unsigned long arg3,
237 unsigned long arg4,
63aa9160 238 unsigned long arg5) = func;
1b7b9c65 239 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 240
1b7b9c65 241 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
242 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
243 fptr(event_priv->pub, args[0], args[1], args[2],
3b82c4e1 244 args[3], args[4], args[5]);
8a8ac9a8
FD
245 break;
246 }
247 default:
248 break;
249 }
250}
251
63aa9160
FD
252void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
253{
0bb716a8 254 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1 255 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
256 const struct trace_syscall_entry *table, *entry;
257 size_t table_len;
258
259 if (unlikely(in_compat_syscall())) {
0bb716a8 260 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
261
262 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 263 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
264 /* System call filtered out. */
265 return;
266 }
ebcc64cd
FD
267 table = compat_sc_table.table;
268 table_len = compat_sc_table.len;
0bb716a8 269 unknown_action_list = &syscall_table->compat_unknown_syscall_dispatch;
63aa9160 270 } else {
0bb716a8 271 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
272
273 if (id < 0 || id >= NR_syscalls
0bb716a8 274 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
275 /* System call filtered out. */
276 return;
277 }
ebcc64cd
FD
278 table = sc_table.table;
279 table_len = sc_table.len;
0bb716a8 280 unknown_action_list = &syscall_table->unknown_syscall_dispatch;
63aa9160
FD
281 }
282 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 283 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
284 return;
285 }
3b82c4e1
MD
286
287 entry = &table[id];
288 if (!entry->event_func) {
289 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
290 return;
291 }
3b82c4e1
MD
292
293 if (unlikely(in_compat_syscall())) {
0bb716a8 294 action_list = &syscall_table->compat_syscall_dispatch[id];
3b82c4e1 295 } else {
0bb716a8 296 action_list = &syscall_table->syscall_dispatch[id];
3b82c4e1
MD
297 }
298 if (unlikely(hlist_empty(action_list)))
299 return;
300
e2d5dbc7 301 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
302}
303
3b82c4e1 304static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 305 struct pt_regs *regs, long id, long ret)
5b7ac358 306{
1b7b9c65 307 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 308 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 309
1b7b9c65 310 lttng_syscall_get_arguments(current, regs, args);
a67ba386 311 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
3b82c4e1 312 if (unlikely(in_compat_syscall()))
e2d5dbc7 313 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
3b82c4e1
MD
314 args);
315 else
e2d5dbc7 316 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
3b82c4e1 317 }
5b7ac358
MD
318}
319
3b82c4e1 320static __always_inline
e2d5dbc7 321void syscall_exit_event_call_func(struct hlist_head *action_list,
3b82c4e1
MD
322 void *func, unsigned int nrargs,
323 struct pt_regs *regs, long ret)
5b7ac358 324{
a67ba386 325 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 326
3b82c4e1 327 switch (nrargs) {
5b7ac358
MD
328 case 0:
329 {
3b82c4e1 330 void (*fptr)(void *__data, long ret) = func;
5b7ac358 331
e2d5dbc7
MD
332 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
333 fptr(event_priv->pub, ret);
5b7ac358
MD
334 break;
335 }
336 case 1:
337 {
338 void (*fptr)(void *__data,
fc4f7161 339 long ret,
3b82c4e1 340 unsigned long arg0) = func;
1b7b9c65 341 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 342
1b7b9c65 343 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
344 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
345 fptr(event_priv->pub, ret, args[0]);
5b7ac358
MD
346 break;
347 }
348 case 2:
349 {
350 void (*fptr)(void *__data,
fc4f7161 351 long ret,
5b7ac358 352 unsigned long arg0,
3b82c4e1 353 unsigned long arg1) = func;
1b7b9c65 354 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 355
1b7b9c65 356 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
357 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
358 fptr(event_priv->pub, ret, args[0], args[1]);
5b7ac358
MD
359 break;
360 }
361 case 3:
362 {
363 void (*fptr)(void *__data,
fc4f7161 364 long ret,
5b7ac358
MD
365 unsigned long arg0,
366 unsigned long arg1,
3b82c4e1 367 unsigned long arg2) = func;
1b7b9c65 368 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 369
1b7b9c65 370 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
371 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
372 fptr(event_priv->pub, ret, args[0], args[1], args[2]);
5b7ac358
MD
373 break;
374 }
375 case 4:
376 {
377 void (*fptr)(void *__data,
fc4f7161 378 long ret,
5b7ac358
MD
379 unsigned long arg0,
380 unsigned long arg1,
381 unsigned long arg2,
3b82c4e1 382 unsigned long arg3) = func;
1b7b9c65 383 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 384
1b7b9c65 385 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
386 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
387 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3]);
5b7ac358
MD
388 break;
389 }
390 case 5:
391 {
392 void (*fptr)(void *__data,
fc4f7161 393 long ret,
5b7ac358
MD
394 unsigned long arg0,
395 unsigned long arg1,
396 unsigned long arg2,
397 unsigned long arg3,
3b82c4e1 398 unsigned long arg4) = func;
1b7b9c65 399 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 400
1b7b9c65 401 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
402 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
403 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3], args[4]);
5b7ac358
MD
404 break;
405 }
406 case 6:
407 {
408 void (*fptr)(void *__data,
fc4f7161 409 long ret,
5b7ac358
MD
410 unsigned long arg0,
411 unsigned long arg1,
412 unsigned long arg2,
413 unsigned long arg3,
414 unsigned long arg4,
3b82c4e1 415 unsigned long arg5) = func;
1b7b9c65 416 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 417
1b7b9c65 418 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
419 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
420 fptr(event_priv->pub, ret, args[0], args[1], args[2],
3b82c4e1 421 args[3], args[4], args[5]);
5b7ac358
MD
422 break;
423 }
424 default:
425 break;
426 }
427}
428
3b82c4e1
MD
429void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
430{
0bb716a8 431 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1
MD
432 struct hlist_head *action_list, *unknown_action_list;
433 const struct trace_syscall_entry *table, *entry;
434 size_t table_len;
435 long id;
436
437 id = syscall_get_nr(current, regs);
438
439 if (unlikely(in_compat_syscall())) {
0bb716a8 440 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
441
442 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 443 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
3b82c4e1
MD
444 /* System call filtered out. */
445 return;
446 }
ebcc64cd
FD
447 table = compat_sc_exit_table.table;
448 table_len = compat_sc_exit_table.len;
0bb716a8 449 unknown_action_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
3b82c4e1 450 } else {
0bb716a8 451 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
452
453 if (id < 0 || id >= NR_syscalls
0bb716a8 454 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
3b82c4e1
MD
455 /* System call filtered out. */
456 return;
457 }
ebcc64cd
FD
458 table = sc_exit_table.table;
459 table_len = sc_exit_table.len;
0bb716a8 460 unknown_action_list = &syscall_table->unknown_syscall_exit_dispatch;
3b82c4e1
MD
461 }
462 if (unlikely(id < 0 || id >= table_len)) {
463 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
464 return;
465 }
466
467 entry = &table[id];
468 if (!entry->event_func) {
469 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
470 return;
471 }
472
473 if (unlikely(in_compat_syscall())) {
0bb716a8 474 action_list = &syscall_table->compat_syscall_exit_dispatch[id];
3b82c4e1 475 } else {
0bb716a8 476 action_list = &syscall_table->syscall_exit_dispatch[id];
3b82c4e1
MD
477 }
478 if (unlikely(hlist_empty(action_list)))
479 return;
480
e2d5dbc7 481 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
3b82c4e1
MD
482 regs, ret);
483}
484
0bb716a8
MD
485static
486struct lttng_kernel_syscall_table *get_syscall_table_from_enabler(struct lttng_event_enabler_common *event_enabler)
8a8ac9a8 487{
0bb716a8
MD
488 switch (event_enabler->enabler_type) {
489 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
490 {
1ae083ba
MD
491 struct lttng_event_recorder_enabler *event_recorder_enabler =
492 container_of(event_enabler, struct lttng_event_recorder_enabler, parent);
0bb716a8 493 return &event_recorder_enabler->chan->priv->parent.syscall_table;
8a8ac9a8 494 }
0bb716a8
MD
495 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
496 {
497 struct lttng_event_notifier_enabler *event_notifier_enabler =
498 container_of(event_enabler, struct lttng_event_notifier_enabler, parent);
499 return &event_notifier_enabler->group->syscall_table;
8a8ac9a8 500 }
0bb716a8
MD
501 default:
502 return NULL;
8a8ac9a8 503 }
0bb716a8 504}
8a8ac9a8 505
0bb716a8
MD
506static
507struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_kernel_event_common *event)
508{
509 switch (event->type) {
510 case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
511 {
512 struct lttng_kernel_event_recorder *event_recorder =
513 container_of(event, struct lttng_kernel_event_recorder, parent);
514 return &event_recorder->chan->priv->parent.syscall_table;
515 }
516 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
517 {
518 struct lttng_kernel_event_notifier *event_notifier =
519 container_of(event, struct lttng_kernel_event_notifier, parent);
520 return &event_notifier->priv->group->syscall_table;
521 }
522 default:
523 return NULL;
8a8ac9a8 524 }
8a8ac9a8 525}
0bb716a8 526
5408b6d6
MD
527static
528void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common *syscall_event_enabler,
529 const struct lttng_kernel_event_desc *desc, struct hlist_head *dispatch_table,
530 enum sc_type type, unsigned int syscall_nr)
531{
532 struct lttng_kernel_event_common *event;
533
534 switch (syscall_event_enabler->enabler_type) {
535 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
536 {
537 struct lttng_event_recorder_enabler *syscall_event_recorder_enabler =
538 container_of(syscall_event_enabler, struct lttng_event_recorder_enabler, parent);
539 struct lttng_event_recorder_enabler *event_recorder_enabler;
540 struct lttng_kernel_abi_event ev;
541
542 /* We need to create an event for this syscall/enabler. */
543 memset(&ev, 0, sizeof(ev));
544 switch (type) {
545 case SC_TYPE_ENTRY:
546 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
547 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
548 break;
549 case SC_TYPE_EXIT:
550 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
551 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
552 break;
553 case SC_TYPE_COMPAT_ENTRY:
554 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
555 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
556 break;
557 case SC_TYPE_COMPAT_EXIT:
558 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
559 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
560 break;
561 }
562 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
563 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
564 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
565 event_recorder_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev,
566 syscall_event_recorder_enabler->chan);
567 WARN_ON_ONCE(!event_recorder_enabler);
568 if (!event_recorder_enabler)
569 return;
570 event = _lttng_kernel_event_create(&event_recorder_enabler->parent, desc);
c3fb484e 571 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 572 lttng_event_enabler_destroy(&event_recorder_enabler->parent);
c3fb484e 573 if (IS_ERR(event)) {
5408b6d6
MD
574 printk(KERN_INFO "Unable to create event recorder %s\n", desc->event_name);
575 return;
576 }
9cd106a6 577 event->priv->u.syscall.syscall_id = syscall_nr;
fd70f5a5 578 if (dispatch_table)
9cd106a6 579 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_table);
5408b6d6
MD
580 break;
581 }
582 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
583 {
584 struct lttng_event_notifier_enabler *syscall_event_notifier_enabler =
585 container_of(syscall_event_enabler, struct lttng_event_notifier_enabler, parent);
586 struct lttng_event_notifier_enabler *event_notifier_enabler;
587 struct lttng_kernel_abi_event_notifier event_notifier_param;
588 uint64_t user_token = syscall_event_enabler->user_token;
589 uint64_t error_counter_index = syscall_event_notifier_enabler->error_counter_index;
590
591 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
592 switch (type) {
593 case SC_TYPE_ENTRY:
594 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
595 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
596 break;
597 case SC_TYPE_EXIT:
598 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
599 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
600 break;
601 case SC_TYPE_COMPAT_ENTRY:
602 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
603 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
604 break;
605 case SC_TYPE_COMPAT_EXIT:
606 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
607 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
608 break;
609 }
610 strncat(event_notifier_param.event.name, desc->event_name,
611 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
612 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
613 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
614 event_notifier_param.event.token = user_token;
615 event_notifier_param.error_counter_index = error_counter_index;
616
617 event_notifier_enabler = lttng_event_notifier_enabler_create(LTTNG_ENABLER_FORMAT_NAME,
618 &event_notifier_param, syscall_event_notifier_enabler->group);
619 WARN_ON_ONCE(!event_notifier_enabler);
620 event = _lttng_kernel_event_create(&event_notifier_enabler->parent, desc);
c3fb484e 621 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 622 lttng_event_enabler_destroy(&event_notifier_enabler->parent);
c3fb484e 623 if (IS_ERR(event)) {
5408b6d6
MD
624 printk(KERN_INFO "Unable to create event notifier %s\n", desc->event_name);
625 return;
626 }
627 event->priv->u.syscall.syscall_id = syscall_nr;
ac07db60
MD
628 if (dispatch_table)
629 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_table);
5408b6d6
MD
630 break;
631 }
632 default:
633 break;
634 }
635}
636
49c50022 637static
67233a18
MD
638void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct lttng_event_enabler_common *syscall_event_enabler_common,
639 const struct trace_syscall_entry *table, size_t table_len, enum sc_type type)
259b6cb3 640{
063f0825
MD
641 struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(syscall_event_enabler_common);
642 const struct lttng_kernel_event_desc *desc;
259b6cb3 643 unsigned int i;
49c50022 644
1d303f69
MD
645#ifndef CONFIG_COMPAT
646 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 647 return;
1d303f69 648#endif
67233a18 649 /* iterate over all syscall and create event that match */
49c50022 650 for (i = 0; i < table_len; i++) {
19bef247 651 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 652 struct hlist_head *head;
6768203a 653 bool found = false;
49c50022 654
063f0825 655 desc = table[i].desc;
49c50022
MD
656 if (!desc) {
657 /* Unknown syscall */
658 continue;
659 }
063f0825
MD
660
661 if (!lttng_desc_match_enabler(desc, syscall_event_enabler_common))
3b82c4e1 662 continue;
063f0825 663
49c50022 664 /*
3b82c4e1 665 * Check if already created.
49c50022 666 */
0def9170 667 head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
19bef247 668 lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
6768203a
MD
669 if (lttng_event_enabler_desc_match_event(syscall_event_enabler_common, desc, event_priv->pub)) {
670 found = true;
671 break;
672 }
3b82c4e1
MD
673 }
674 if (found)
49c50022 675 continue;
3b82c4e1 676
ecdbbfd8 677 lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, NULL, type, i);
49c50022 678 }
49c50022
MD
679}
680
552f7c79
MD
681static
682bool lttng_syscall_event_enabler_is_wildcard_all(struct lttng_event_enabler_common *event_enabler)
683{
684 if (event_enabler->event_param.instrumentation != LTTNG_KERNEL_ABI_SYSCALL)
685 return false;
686 if (event_enabler->event_param.u.syscall.abi != LTTNG_KERNEL_ABI_SYSCALL_ABI_ALL)
687 return false;
688 if (event_enabler->event_param.u.syscall.match != LTTNG_KERNEL_ABI_SYSCALL_MATCH_NAME)
689 return false;
690 if (strcmp(event_enabler->event_param.name, "*"))
691 return false;
692 return true;
693}
694
9f6f4507
MD
695static
696void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type)
697{
698 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(event_enabler);
699 struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(event_enabler);
700 struct lttng_kernel_event_common_private *event_priv;
701 const struct lttng_kernel_event_desc *desc;
702 struct hlist_head *unknown_dispatch_list;
703 bool found = false;
704 struct hlist_head *head;
705
1d303f69
MD
706#ifndef CONFIG_COMPAT
707 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 708 return;
1d303f69 709#endif
552f7c79
MD
710 /*
711 * Considering that currently system calls can only be enabled on a per
712 * name basis (or wildcard based on a name), unknown syscall events are
713 * only used when matching *all* system calls, because this is the only
714 * case which can be associated with an unknown system call.
715 *
716 * When enabling system call on a per system call number basis will be
717 * supported, this will need to be revisited.
718 */
719 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
720 return;
721
9f6f4507
MD
722 switch (type) {
723 case SC_TYPE_ENTRY:
724 desc = &__event_desc___syscall_entry_unknown;
725 unknown_dispatch_list = &syscall_table->unknown_syscall_dispatch;
726 break;
727 case SC_TYPE_EXIT:
728 desc = &__event_desc___syscall_exit_unknown;
729 unknown_dispatch_list = &syscall_table->unknown_syscall_exit_dispatch;
730 break;
731 case SC_TYPE_COMPAT_ENTRY:
732 desc = &__event_desc___compat_syscall_entry_unknown;
733 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_dispatch;
734 break;
735 case SC_TYPE_COMPAT_EXIT:
736 desc = &__event_desc___compat_syscall_exit_unknown;
737 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
738 break;
739 default:
740 WARN_ON_ONCE(1);
741 }
742
743 /*
744 * Check if already created.
745 */
746 head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
747 lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
6768203a 748 if (lttng_event_enabler_desc_match_event(event_enabler, desc, event_priv->pub)) {
9f6f4507 749 found = true;
6768203a
MD
750 break;
751 }
9f6f4507
MD
752 }
753 if (!found)
754 lttng_syscall_event_enabler_create_event(event_enabler, desc, unknown_dispatch_list, type, -1U);
755}
756
d26015f6 757static
15a00134 758void lttng_syscall_event_enabler_create_matching_events(struct lttng_event_enabler_common *event_enabler)
49c50022 759{
15a00134 760 enum lttng_kernel_abi_syscall_entryexit entryexit = event_enabler->event_param.u.syscall.entryexit;
5b7ac358 761
15a00134
MD
762 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
763 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
764 sc_table.table, sc_table.len, SC_TYPE_ENTRY);
765 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
766 compat_sc_table.table, compat_sc_table.len, SC_TYPE_COMPAT_ENTRY);
767 create_unknown_syscall_event(event_enabler, SC_TYPE_ENTRY);
768 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_ENTRY);
769 }
1ab4126a 770
15a00134
MD
771 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
772 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
773 sc_exit_table.table, sc_exit_table.len, SC_TYPE_EXIT);
774 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
775 compat_sc_exit_table.table, compat_sc_exit_table.len, SC_TYPE_COMPAT_EXIT);
776 create_unknown_syscall_event(event_enabler, SC_TYPE_EXIT);
777 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_EXIT);
778 }
259b6cb3
MD
779}
780
781/*
8a8ac9a8
FD
782 * Should be called with sessions lock held.
783 */
b2f63bde 784int lttng_event_enabler_create_syscall_events_if_missing(struct lttng_event_enabler_common *syscall_event_enabler)
8a8ac9a8 785{
d26015f6
MD
786 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(syscall_event_enabler);
787 int ret;
8a8ac9a8 788
0bb716a8 789 if (!syscall_table->syscall_dispatch) {
d26015f6 790 /* create syscall table mapping syscall to events */
0bb716a8
MD
791 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
792 if (!syscall_table->syscall_dispatch)
8a8ac9a8 793 return -ENOMEM;
8a8ac9a8 794 }
0bb716a8 795 if (!syscall_table->syscall_exit_dispatch) {
d26015f6
MD
796 /* create syscall table mapping syscall to events */
797 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_exit_table.len, GFP_KERNEL);
0bb716a8 798 if (!syscall_table->syscall_exit_dispatch)
8a8ac9a8 799 return -ENOMEM;
8a8ac9a8
FD
800 }
801
802#ifdef CONFIG_COMPAT
0bb716a8 803 if (!syscall_table->compat_syscall_dispatch) {
d26015f6 804 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
805 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
806 if (!syscall_table->compat_syscall_dispatch)
8a8ac9a8 807 return -ENOMEM;
8a8ac9a8
FD
808 }
809
0bb716a8 810 if (!syscall_table->compat_syscall_exit_dispatch) {
d26015f6
MD
811 /* create syscall table mapping compat syscall to events */
812 syscall_table->compat_syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len, GFP_KERNEL);
0bb716a8 813 if (!syscall_table->compat_syscall_exit_dispatch)
8a8ac9a8 814 return -ENOMEM;
8a8ac9a8
FD
815 }
816#endif
0bb716a8
MD
817 if (!syscall_table->sc_filter) {
818 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
8a8ac9a8 819 GFP_KERNEL);
0bb716a8 820 if (!syscall_table->sc_filter)
8a8ac9a8
FD
821 return -ENOMEM;
822 }
823
0bb716a8 824 if (!syscall_table->sys_enter_registered) {
8a8ac9a8 825 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
0bb716a8 826 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
827 if (ret)
828 return ret;
0bb716a8 829 syscall_table->sys_enter_registered = 1;
8a8ac9a8 830 }
0bb716a8 831 if (!syscall_table->sys_exit_registered) {
8a8ac9a8 832 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
0bb716a8 833 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8
FD
834 if (ret) {
835 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 836 (void *) syscall_entry_event_probe, syscall_table));
8a8ac9a8
FD
837 return ret;
838 }
0bb716a8 839 syscall_table->sys_exit_registered = 1;
8a8ac9a8 840 }
0fab709d 841
86e12a51
MD
842 lttng_syscall_event_enabler_create_matching_events(syscall_event_enabler);
843
8a8ac9a8
FD
844 return ret;
845}
846
6053e75e 847int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
259b6cb3
MD
848{
849 int ret;
850
0bb716a8 851 if (!syscall_table->syscall_dispatch)
259b6cb3 852 return 0;
0bb716a8 853 if (syscall_table->sys_enter_registered) {
2d9cd7f3 854 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 855 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
856 if (ret)
857 return ret;
0bb716a8 858 syscall_table->sys_enter_registered = 0;
80f87dd2 859 }
0bb716a8 860 if (syscall_table->sys_exit_registered) {
2d9cd7f3 861 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 862 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
863 if (ret)
864 return ret;
0bb716a8 865 syscall_table->sys_exit_registered = 0;
80f87dd2 866 }
badfe9f5
MD
867 return 0;
868}
869
6053e75e 870int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
badfe9f5 871{
0bb716a8
MD
872 kfree(syscall_table->syscall_dispatch);
873 kfree(syscall_table->syscall_exit_dispatch);
49c50022 874#ifdef CONFIG_COMPAT
0bb716a8
MD
875 kfree(syscall_table->compat_syscall_dispatch);
876 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 877#endif
0bb716a8 878 kfree(syscall_table->sc_filter);
80f87dd2
MD
879 return 0;
880}
881
882static
883int get_syscall_nr(const char *syscall_name)
884{
885 int syscall_nr = -1;
886 int i;
887
ebcc64cd 888 for (i = 0; i < sc_table.len; i++) {
80f87dd2 889 const struct trace_syscall_entry *entry;
5b7ac358 890 const char *it_name;
80f87dd2 891
ebcc64cd 892 entry = &sc_table.table[i];
80f87dd2
MD
893 if (!entry->desc)
894 continue;
437d5aa5 895 it_name = entry->desc->event_name;
5b7ac358
MD
896 it_name += strlen(SYSCALL_ENTRY_STR);
897 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
898 syscall_nr = i;
899 break;
900 }
901 }
902 return syscall_nr;
903}
904
905static
906int get_compat_syscall_nr(const char *syscall_name)
907{
908 int syscall_nr = -1;
909 int i;
910
ebcc64cd 911 for (i = 0; i < compat_sc_table.len; i++) {
80f87dd2 912 const struct trace_syscall_entry *entry;
5b7ac358 913 const char *it_name;
80f87dd2 914
ebcc64cd 915 entry = &compat_sc_table.table[i];
80f87dd2
MD
916 if (!entry->desc)
917 continue;
437d5aa5 918 it_name = entry->desc->event_name;
5b7ac358
MD
919 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
920 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
921 syscall_nr = i;
922 break;
923 }
924 }
925 return syscall_nr;
926}
927
12e579db
MD
928static
929uint32_t get_sc_tables_len(void)
930{
ebcc64cd 931 return sc_table.len + compat_sc_table.len;
12e579db
MD
932}
933
badfe9f5 934static
ade8a729
FD
935const char *get_syscall_name(const char *desc_name,
936 enum lttng_syscall_abi abi,
937 enum lttng_syscall_entryexit entryexit)
80f87dd2 938{
badfe9f5 939 size_t prefix_len = 0;
80f87dd2 940
80f87dd2 941
ade8a729 942 switch (entryexit) {
badfe9f5 943 case LTTNG_SYSCALL_ENTRY:
ade8a729 944 switch (abi) {
badfe9f5
MD
945 case LTTNG_SYSCALL_ABI_NATIVE:
946 prefix_len = strlen(SYSCALL_ENTRY_STR);
947 break;
948 case LTTNG_SYSCALL_ABI_COMPAT:
949 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
950 break;
80f87dd2 951 }
badfe9f5
MD
952 break;
953 case LTTNG_SYSCALL_EXIT:
ade8a729 954 switch (abi) {
badfe9f5
MD
955 case LTTNG_SYSCALL_ABI_NATIVE:
956 prefix_len = strlen(SYSCALL_EXIT_STR);
957 break;
958 case LTTNG_SYSCALL_ABI_COMPAT:
959 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
960 break;
80f87dd2 961 }
badfe9f5 962 break;
80f87dd2 963 }
badfe9f5 964 WARN_ON_ONCE(prefix_len == 0);
ade8a729 965 return desc_name + prefix_len;
badfe9f5
MD
966}
967
ade8a729
FD
968static
969int lttng_syscall_filter_enable(
970 struct lttng_syscall_filter *filter,
971 const char *desc_name, enum lttng_syscall_abi abi,
972 enum lttng_syscall_entryexit entryexit)
badfe9f5 973{
badfe9f5
MD
974 const char *syscall_name;
975 unsigned long *bitmap;
976 int syscall_nr;
977
ade8a729 978 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 979
ade8a729 980 switch (abi) {
badfe9f5
MD
981 case LTTNG_SYSCALL_ABI_NATIVE:
982 syscall_nr = get_syscall_nr(syscall_name);
983 break;
984 case LTTNG_SYSCALL_ABI_COMPAT:
985 syscall_nr = get_compat_syscall_nr(syscall_name);
986 break;
987 default:
988 return -EINVAL;
80f87dd2 989 }
badfe9f5
MD
990 if (syscall_nr < 0)
991 return -ENOENT;
992
ade8a729 993 switch (entryexit) {
badfe9f5 994 case LTTNG_SYSCALL_ENTRY:
ade8a729 995 switch (abi) {
badfe9f5
MD
996 case LTTNG_SYSCALL_ABI_NATIVE:
997 bitmap = filter->sc_entry;
998 break;
999 case LTTNG_SYSCALL_ABI_COMPAT:
1000 bitmap = filter->sc_compat_entry;
1001 break;
6d9694d8
MD
1002 default:
1003 return -EINVAL;
80f87dd2 1004 }
badfe9f5
MD
1005 break;
1006 case LTTNG_SYSCALL_EXIT:
ade8a729 1007 switch (abi) {
badfe9f5
MD
1008 case LTTNG_SYSCALL_ABI_NATIVE:
1009 bitmap = filter->sc_exit;
1010 break;
1011 case LTTNG_SYSCALL_ABI_COMPAT:
1012 bitmap = filter->sc_compat_exit;
1013 break;
6d9694d8
MD
1014 default:
1015 return -EINVAL;
80f87dd2 1016 }
badfe9f5
MD
1017 break;
1018 default:
1019 return -EINVAL;
80f87dd2 1020 }
badfe9f5
MD
1021 if (test_bit(syscall_nr, bitmap))
1022 return -EEXIST;
1023 bitmap_set(bitmap, syscall_nr, 1);
80f87dd2 1024 return 0;
80f87dd2
MD
1025}
1026
9b2f1c54 1027int lttng_syscall_filter_enable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1028{
9b2f1c54 1029 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
9cd106a6
MD
1030 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
1031 struct hlist_head *dispatch_list;
9b2f1c54 1032 int ret;
8a8ac9a8 1033
9b2f1c54 1034 WARN_ON_ONCE(event->priv->instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1035
0bb716a8 1036 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
9b2f1c54
MD
1037 event->priv->desc->event_name, event->priv->u.syscall.abi,
1038 event->priv->u.syscall.entryexit);
1039 if (ret)
1040 return ret;
8a8ac9a8 1041
9cd106a6
MD
1042 switch (event->priv->u.syscall.entryexit) {
1043 case LTTNG_SYSCALL_ENTRY:
1044 switch (event->priv->u.syscall.abi) {
1045 case LTTNG_SYSCALL_ABI_NATIVE:
1046 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
1047 break;
1048 case LTTNG_SYSCALL_ABI_COMPAT:
1049 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
1050 break;
1051 default:
1052 ret = -EINVAL;
1053 goto end;
1054 }
8a8ac9a8 1055 break;
9cd106a6
MD
1056 case LTTNG_SYSCALL_EXIT:
1057 switch (event->priv->u.syscall.abi) {
1058 case LTTNG_SYSCALL_ABI_NATIVE:
1059 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
8a8ac9a8 1060 break;
9cd106a6
MD
1061 case LTTNG_SYSCALL_ABI_COMPAT:
1062 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
8a8ac9a8 1063 break;
6866b1c7
MJ
1064 default:
1065 ret = -EINVAL;
1066 goto end;
8a8ac9a8
FD
1067 }
1068 break;
6866b1c7 1069 default:
9cd106a6
MD
1070 ret = -EINVAL;
1071 goto end;
8a8ac9a8 1072 }
9cd106a6
MD
1073
1074 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_list);
8a8ac9a8 1075end:
9b2f1c54 1076 return ret;
ade8a729
FD
1077}
1078
1079static
f2db8be3 1080int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729
FD
1081 const char *desc_name, enum lttng_syscall_abi abi,
1082 enum lttng_syscall_entryexit entryexit)
1083{
badfe9f5
MD
1084 const char *syscall_name;
1085 unsigned long *bitmap;
1086 int syscall_nr;
80f87dd2 1087
ade8a729 1088 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1089
ade8a729 1090 switch (abi) {
badfe9f5
MD
1091 case LTTNG_SYSCALL_ABI_NATIVE:
1092 syscall_nr = get_syscall_nr(syscall_name);
1093 break;
1094 case LTTNG_SYSCALL_ABI_COMPAT:
1095 syscall_nr = get_compat_syscall_nr(syscall_name);
1096 break;
1097 default:
1098 return -EINVAL;
80f87dd2 1099 }
badfe9f5
MD
1100 if (syscall_nr < 0)
1101 return -ENOENT;
80f87dd2 1102
ade8a729 1103 switch (entryexit) {
badfe9f5 1104 case LTTNG_SYSCALL_ENTRY:
ade8a729 1105 switch (abi) {
badfe9f5
MD
1106 case LTTNG_SYSCALL_ABI_NATIVE:
1107 bitmap = filter->sc_entry;
1108 break;
1109 case LTTNG_SYSCALL_ABI_COMPAT:
1110 bitmap = filter->sc_compat_entry;
1111 break;
6d9694d8
MD
1112 default:
1113 return -EINVAL;
80f87dd2 1114 }
badfe9f5
MD
1115 break;
1116 case LTTNG_SYSCALL_EXIT:
ade8a729 1117 switch (abi) {
badfe9f5
MD
1118 case LTTNG_SYSCALL_ABI_NATIVE:
1119 bitmap = filter->sc_exit;
1120 break;
1121 case LTTNG_SYSCALL_ABI_COMPAT:
1122 bitmap = filter->sc_compat_exit;
1123 break;
6d9694d8
MD
1124 default:
1125 return -EINVAL;
80f87dd2 1126 }
badfe9f5
MD
1127 break;
1128 default:
1129 return -EINVAL;
80f87dd2 1130 }
badfe9f5
MD
1131 if (!test_bit(syscall_nr, bitmap))
1132 return -EEXIST;
1133 bitmap_clear(bitmap, syscall_nr, 1);
80f87dd2 1134
badfe9f5 1135 return 0;
259b6cb3 1136}
2d2464bd 1137
9b2f1c54 1138int lttng_syscall_filter_disable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1139{
9b2f1c54 1140 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
8a8ac9a8
FD
1141 int ret;
1142
0bb716a8 1143 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
9b2f1c54
MD
1144 event->priv->desc->event_name, event->priv->u.syscall.abi,
1145 event->priv->u.syscall.entryexit);
1146 if (ret)
1147 return ret;
9cd106a6 1148 hlist_del_rcu(&event->priv->u.syscall.node);
8a8ac9a8
FD
1149 return 0;
1150}
1151
9cb5be7e
MD
1152void lttng_syscall_table_set_wildcard_all(struct lttng_event_enabler_common *event_enabler)
1153{
1154 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(event_enabler);
1155 enum lttng_kernel_abi_syscall_entryexit entryexit;
1156 int enabled = event_enabler->enabled;
1157
552f7c79 1158 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
9cb5be7e 1159 return;
9cb5be7e
MD
1160 entryexit = event_enabler->event_param.u.syscall.entryexit;
1161 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1162 WRITE_ONCE(syscall_table->syscall_all_entry, enabled);
1163
1164 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1165 WRITE_ONCE(syscall_table->syscall_all_exit, enabled);
1166}
1167
2d2464bd
MD
1168static
1169const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1170{
1171 const struct trace_syscall_entry *entry;
1172 int iter = 0;
1173
ebcc64cd
FD
1174 for (entry = sc_table.table;
1175 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1176 entry++) {
1177 if (iter++ >= *pos)
1178 return entry;
1179 }
ebcc64cd
FD
1180 for (entry = compat_sc_table.table;
1181 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1182 entry++) {
1183 if (iter++ >= *pos)
1184 return entry;
1185 }
1186 /* End of list */
1187 return NULL;
1188}
1189
1190static
1191void *syscall_list_start(struct seq_file *m, loff_t *pos)
1192{
1193 return (void *) syscall_list_get_entry(pos);
1194}
1195
1196static
1197void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1198{
1199 (*ppos)++;
1200 return (void *) syscall_list_get_entry(ppos);
1201}
1202
1203static
1204void syscall_list_stop(struct seq_file *m, void *p)
1205{
1206}
1207
12e579db
MD
1208static
1209int get_sc_table(const struct trace_syscall_entry *entry,
1210 const struct trace_syscall_entry **table,
1211 unsigned int *bitness)
1212{
ebcc64cd 1213 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1214 if (bitness)
1215 *bitness = BITS_PER_LONG;
1216 if (table)
ebcc64cd 1217 *table = sc_table.table;
12e579db
MD
1218 return 0;
1219 }
ebcc64cd
FD
1220 if (!(entry >= compat_sc_table.table
1221 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1222 return -EINVAL;
1223 }
1224 if (bitness)
1225 *bitness = 32;
1226 if (table)
ebcc64cd 1227 *table = compat_sc_table.table;
12e579db
MD
1228 return 0;
1229}
1230
2d2464bd
MD
1231static
1232int syscall_list_show(struct seq_file *m, void *p)
1233{
1234 const struct trace_syscall_entry *table, *entry = p;
1235 unsigned int bitness;
d4291869 1236 unsigned long index;
12e579db 1237 int ret;
d4291869 1238 const char *name;
2d2464bd 1239
12e579db
MD
1240 ret = get_sc_table(entry, &table, &bitness);
1241 if (ret)
1242 return ret;
f4855b46
MD
1243 if (!entry->desc)
1244 return 0;
ebcc64cd 1245 if (table == sc_table.table) {
d4291869 1246 index = entry - table;
437d5aa5 1247 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1248 } else {
ebcc64cd 1249 index = (entry - table) + sc_table.len;
437d5aa5 1250 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1251 }
12e579db 1252 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1253 index, name, bitness);
2d2464bd
MD
1254 return 0;
1255}
1256
1257static
1258const struct seq_operations lttng_syscall_list_seq_ops = {
1259 .start = syscall_list_start,
1260 .next = syscall_list_next,
1261 .stop = syscall_list_stop,
1262 .show = syscall_list_show,
1263};
1264
1265static
1266int lttng_syscall_list_open(struct inode *inode, struct file *file)
1267{
1268 return seq_open(file, &lttng_syscall_list_seq_ops);
1269}
1270
1271const struct file_operations lttng_syscall_list_fops = {
1272 .owner = THIS_MODULE,
1273 .open = lttng_syscall_list_open,
1274 .read = seq_read,
1275 .llseek = seq_lseek,
1276 .release = seq_release,
1277};
12e579db 1278
badfe9f5
MD
1279/*
1280 * A syscall is enabled if it is traced for either entry or exit.
1281 */
c970b655 1282long lttng_syscall_table_get_active_mask(struct lttng_kernel_syscall_table *syscall_table,
606828e4 1283 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
1284{
1285 uint32_t len, sc_tables_len, bitmask_len;
1286 int ret = 0, bit;
1287 char *tmp_mask;
1288 struct lttng_syscall_filter *filter;
1289
1290 ret = get_user(len, &usyscall_mask->len);
1291 if (ret)
1292 return ret;
1293 sc_tables_len = get_sc_tables_len();
1294 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1295 if (len < sc_tables_len) {
1296 return put_user(sc_tables_len, &usyscall_mask->len);
1297 }
1298 /* Array is large enough, we can copy array to user-space. */
1299 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1300 if (!tmp_mask)
1301 return -ENOMEM;
0bb716a8 1302 filter = syscall_table->sc_filter;
12e579db 1303
ebcc64cd 1304 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1305 char state;
2f25059d 1306
0bb716a8
MD
1307 if (syscall_table->syscall_dispatch) {
1308 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1309 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1310 state = test_bit(bit, filter->sc_entry)
1311 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1312 else
1313 state = 1;
1314 } else {
1315 state = 0;
1316 }
1317 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1318 }
1319 for (; bit < sc_tables_len; bit++) {
e2129868 1320 char state;
2f25059d 1321
0bb716a8
MD
1322 if (syscall_table->compat_syscall_dispatch) {
1323 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1324 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
ebcc64cd 1325 state = test_bit(bit - sc_table.len,
badfe9f5 1326 filter->sc_compat_entry)
ebcc64cd 1327 || test_bit(bit - sc_table.len,
badfe9f5 1328 filter->sc_compat_exit);
2f25059d
MD
1329 else
1330 state = 1;
1331 } else {
1332 state = 0;
1333 }
1334 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1335 }
1336 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1337 ret = -EFAULT;
1338 kfree(tmp_mask);
1339 return ret;
1340}
082d4946
MD
1341
1342int lttng_abi_syscall_list(void)
1343{
1344 struct file *syscall_list_file;
1345 int file_fd, ret;
1346
4ac10b76 1347 file_fd = lttng_get_unused_fd();
082d4946
MD
1348 if (file_fd < 0) {
1349 ret = file_fd;
1350 goto fd_error;
1351 }
1352
1353 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1354 &lttng_syscall_list_fops,
1355 NULL, O_RDWR);
1356 if (IS_ERR(syscall_list_file)) {
1357 ret = PTR_ERR(syscall_list_file);
1358 goto file_error;
1359 }
1360 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1361 if (ret < 0)
1362 goto open_error;
1363 fd_install(file_fd, syscall_list_file);
082d4946
MD
1364 return file_fd;
1365
1366open_error:
1367 fput(syscall_list_file);
1368file_error:
1369 put_unused_fd(file_fd);
1370fd_error:
1371 return ret;
1372}
This page took 0.131671 seconds and 4 git commands to generate.