Add underscore prefix before event names
[lttng-modules.git] / lttng-syscalls.c
CommitLineData
259b6cb3
MD
1/*
2 * lttng-syscalls.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng sched probes.
7 *
8 * Dual LGPL v2.1/GPL v2 license.
9 */
10
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <asm/ptrace.h>
14#include <asm/syscall.h>
15
16#include "ltt-events.h"
17
18static void syscall_entry_probe(void *__data, struct pt_regs *regs, long id);
19
f7bdf4db
MD
20/*
21 * Take care of NOARGS not supported by mainline.
22 */
23#define DECLARE_EVENT_CLASS_NOARGS(name, tstruct, assign, print)
24#define DEFINE_EVENT_NOARGS(template, name)
25#define TRACE_EVENT_NOARGS(name, struct, assign, print)
26
259b6cb3
MD
27/*
28 * Create LTTng tracepoint probes.
29 */
30#define LTTNG_PACKAGE_BUILD
31#define CREATE_TRACE_POINTS
32
33/* Hijack probe callback for system calls */
34#define TP_PROBE_CB(_template) &syscall_entry_probe
35#define TP_MODULE_OVERRIDE
36
37#define TRACE_INCLUDE_PATH ../instrumentation/syscalls/headers
177b3692
MD
38#include "instrumentation/syscalls/headers/syscalls_integers.h"
39#include "instrumentation/syscalls/headers/syscalls_pointers.h"
259b6cb3
MD
40
41#undef TP_MODULE_OVERRIDE
42#undef TP_PROBE_CB
43#undef LTTNG_PACKAGE_BUILD
44#undef CREATE_TRACE_POINTS
45
46struct trace_syscall_entry {
47 void *func;
f7bdf4db 48 const struct lttng_event_desc *desc;
259b6cb3
MD
49 const struct lttng_event_field *fields;
50 unsigned int nrargs;
51};
52
259b6cb3
MD
53#define CREATE_SYSCALL_TABLE
54
55#undef TRACE_SYSCALL_TABLE
f7bdf4db 56#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
259b6cb3 57 [ _nr ] = { \
f7bdf4db 58 .func = __event_probe__##_template, \
259b6cb3 59 .nrargs = (_nrargs), \
f7bdf4db
MD
60 .fields = __event_fields___##_template, \
61 .desc = &__event_desc___##_name, \
259b6cb3
MD
62 },
63
64static struct trace_syscall_entry sc_table[] = {
177b3692
MD
65#include "instrumentation/syscalls/headers/syscalls_integers.h"
66#include "instrumentation/syscalls/headers/syscalls_pointers.h"
259b6cb3
MD
67};
68
69#undef CREATE_SYSCALL_TABLE
70
71static void syscall_entry_probe(void *__data, struct pt_regs *regs, long id)
72{
73 struct trace_syscall_entry *entry;
74 struct ltt_channel *chan = __data;
75 struct ltt_event *event;
76
77 if (unlikely(id >= ARRAY_SIZE(sc_table)))
78 return;
79 entry = &sc_table[id];
80 if (unlikely(!entry->func))
81 return;
82 event = chan->sc_table[id];
83 WARN_ON_ONCE(!event);
84
85 switch (entry->nrargs) {
86 case 0:
87 {
88 void (*fptr)(void *__data) = entry->func;
89
90 fptr(event);
91 break;
92 }
93 case 1:
94 {
95 void (*fptr)(void *__data, unsigned long arg0) = entry->func;
96 unsigned long args[1];
97
98 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
99 fptr(event, args[0]);
100 break;
101 }
102 case 2:
103 {
104 void (*fptr)(void *__data,
105 unsigned long arg0,
106 unsigned long arg1) = entry->func;
107 unsigned long args[2];
108
109 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
110 fptr(event, args[0], args[1]);
111 break;
112 }
113 case 3:
114 {
115 void (*fptr)(void *__data,
116 unsigned long arg0,
117 unsigned long arg1,
118 unsigned long arg2) = entry->func;
119 unsigned long args[3];
120
121 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
122 fptr(event, args[0], args[1], args[2]);
123 break;
124 }
125 case 4:
126 {
127 void (*fptr)(void *__data,
128 unsigned long arg0,
129 unsigned long arg1,
130 unsigned long arg2,
131 unsigned long arg3) = entry->func;
132 unsigned long args[4];
133
134 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
135 fptr(event, args[0], args[1], args[2], args[3]);
136 break;
137 }
138 case 5:
139 {
140 void (*fptr)(void *__data,
141 unsigned long arg0,
142 unsigned long arg1,
143 unsigned long arg2,
144 unsigned long arg3,
145 unsigned long arg4) = entry->func;
146 unsigned long args[5];
147
148 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
149 fptr(event, args[0], args[1], args[2], args[3], args[4]);
150 break;
151 }
152 case 6:
153 {
154 void (*fptr)(void *__data,
155 unsigned long arg0,
156 unsigned long arg1,
157 unsigned long arg2,
158 unsigned long arg3,
159 unsigned long arg4,
160 unsigned long arg5) = entry->func;
161 unsigned long args[6];
162
163 syscall_get_arguments(current, regs, 0, entry->nrargs, args);
164 fptr(event, args[0], args[1], args[2],
165 args[3], args[4], args[5]);
166 break;
167 }
168 default:
169 break;
170 }
171}
172
259b6cb3
MD
173int lttng_syscalls_register(struct ltt_channel *chan, void *filter)
174{
175 unsigned int i;
176 int ret;
177
178 wrapper_vmalloc_sync_all();
259b6cb3
MD
179
180 if (!chan->sc_table) {
181 /* create syscall table mapping syscall to events */
182 chan->sc_table = kzalloc(sizeof(struct ltt_event *)
183 * ARRAY_SIZE(sc_table), GFP_KERNEL);
184 if (!chan->sc_table)
185 return -ENOMEM;
186 }
187
188 /* Allocate events for each syscall, insert into table */
189 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
190 struct lttng_kernel_event ev;
191 const struct lttng_event_desc *desc = sc_table[i].desc;
192
193 if (!desc)
194 continue;
195 /*
196 * Skip those already populated by previous failed
197 * register for this channel.
198 */
199 if (chan->sc_table[i])
200 continue;
201 memset(&ev, 0, sizeof(ev));
202 strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
203 ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
204 ev.instrumentation = LTTNG_KERNEL_NOOP;
205 chan->sc_table[i] = ltt_event_create(chan, &ev, filter,
206 desc);
207 if (!chan->sc_table[i]) {
208 /*
209 * If something goes wrong in event registration
210 * after the first one, we have no choice but to
211 * leave the previous events in there, until
212 * deleted by session teardown.
213 */
214 return -EINVAL;
215 }
216 }
217 ret = tracepoint_probe_register("sys_enter",
218 (void *) syscall_entry_probe, chan);
219 return ret;
220}
221
222/*
223 * Only called at session destruction.
224 */
225int lttng_syscalls_unregister(struct ltt_channel *chan)
226{
227 int ret;
228
229 if (!chan->sc_table)
230 return 0;
231 ret = tracepoint_probe_unregister("sys_enter",
232 (void *) syscall_entry_probe, chan);
233 if (ret)
234 return ret;
235 /* ltt_event destroy will be performed by ltt_session_destroy() */
236 kfree(chan->sc_table);
237 return 0;
238}
This page took 0.031245 seconds and 4 git commands to generate.