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