Generate bytecodes related to the trigger on reception
[lttng-tools.git] / src / common / event-rule / kprobe.c
CommitLineData
077192fd
JR
1/*
2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <assert.h>
58daac01 9#include <common/credentials.h>
077192fd
JR
10#include <common/error.h>
11#include <common/macros.h>
12#include <common/payload.h>
13#include <common/payload-view.h>
14#include <common/runas.h>
15#include <ctype.h>
16#include <lttng/constant.h>
17#include <lttng/event-rule/event-rule-internal.h>
18#include <lttng/event-rule/kprobe-internal.h>
19#include <lttng/kernel-probe.h>
20#include <lttng/kernel-probe-internal.h>
21#include <stdio.h>
22
23#define IS_KPROBE_EVENT_RULE(rule) \
24 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KPROBE)
25
26#if (LTTNG_SYMBOL_NAME_LEN == 256)
27#define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
28#endif
29
30static void lttng_event_rule_kprobe_destroy(struct lttng_event_rule *rule)
31{
32 struct lttng_event_rule_kprobe *kprobe;
33
34 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
35
36 lttng_kernel_probe_location_destroy(kprobe->location);
37 free(kprobe->name);
38 free(kprobe);
39}
40
41static bool lttng_event_rule_kprobe_validate(
42 const struct lttng_event_rule *rule)
43{
44 bool valid = false;
45 struct lttng_event_rule_kprobe *kprobe;
46
47 if (!rule) {
48 goto end;
49 }
50
51 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
52
53 /* Required field. */
54 if (!kprobe->name) {
55 ERR("Invalid name event rule: a name must be set.");
56 goto end;
57 }
58
59 /* Required field. */
60 if(!kprobe->location) {
61 ERR("Invalid name event rule: a location must be set.");
62 goto end;
63 }
64
65 valid = true;
66end:
67 return valid;
68}
69
70static int lttng_event_rule_kprobe_serialize(
71 const struct lttng_event_rule *rule,
72 struct lttng_payload *payload)
73{
74 int ret;
75 size_t name_len, header_offset, size_before_location;
76 struct lttng_event_rule_kprobe *kprobe;
77 struct lttng_event_rule_kprobe_comm kprobe_comm;
78 struct lttng_event_rule_kprobe_comm *header;
79
80 if (!rule || !IS_KPROBE_EVENT_RULE(rule)) {
81 ret = -1;
82 goto end;
83 }
84
85 header_offset = payload->buffer.size;
86
87 DBG("Serializing kprobe event rule.");
88 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
89
90 name_len = strlen(kprobe->name) + 1;
91 kprobe_comm.name_len = name_len;
92
93 ret = lttng_dynamic_buffer_append(
94 &payload->buffer, &kprobe_comm, sizeof(kprobe_comm));
95 if (ret) {
96 goto end;
97 }
98
99 ret = lttng_dynamic_buffer_append(&payload->buffer, kprobe->name, name_len);
100 if (ret) {
101 goto end;
102 }
103
104 size_before_location = payload->buffer.size;
105
106 ret = lttng_kernel_probe_location_serialize(kprobe->location, payload);
107 if (ret < 0) {
108 goto end;
109 }
110
111 /* Update the header regarding the probe size. */
112 header = (struct lttng_event_rule_kprobe_comm*) (
113 (char *) payload->buffer.data + header_offset);
114 header->location_len = payload->buffer.size - size_before_location;
115
116 ret = 0;
117
118end:
119 return ret;
120}
121
122static bool lttng_event_rule_kprobe_is_equal(const struct lttng_event_rule *_a,
123 const struct lttng_event_rule *_b)
124{
125 bool is_equal = false;
126 struct lttng_event_rule_kprobe *a, *b;
127
128 a = container_of(_a, struct lttng_event_rule_kprobe, parent);
129 b = container_of(_b, struct lttng_event_rule_kprobe, parent);
130
131 /* Quick checks */
132 if (!!a->name != !!b->name) {
133 goto end;
134 }
135
136 /* Long check */
137 assert(a->name);
138 assert(b->name);
139 if (strcmp(a->name, b->name)) {
140 goto end;
141 }
142
143 is_equal = lttng_kernel_probe_location_is_equal(
144 a->location, b->location);
145end:
146 return is_equal;
147}
148
149static enum lttng_error_code lttng_event_rule_kprobe_generate_filter_bytecode(
58daac01
JR
150 struct lttng_event_rule *rule,
151 const struct lttng_credentials *creds)
077192fd
JR
152{
153 /* Nothing to do. */
154 return LTTNG_OK;
155}
156
157static const char *lttng_event_rule_kprobe_get_filter(
158 const struct lttng_event_rule *rule)
159{
160 /* Not supported. */
161 return NULL;
162}
163
164static const struct lttng_filter_bytecode *
165lttng_event_rule_kprobe_get_filter_bytecode(const struct lttng_event_rule *rule)
166{
167 /* Not supported. */
168 return NULL;
169}
170
171static struct lttng_event_exclusion *
172lttng_event_rule_kprobe_generate_exclusions(const struct lttng_event_rule *rule)
173{
174 /* Not supported. */
175 return NULL;
176}
177
178struct lttng_event_rule *lttng_event_rule_kprobe_create()
179{
180 struct lttng_event_rule *rule = NULL;
181 struct lttng_event_rule_kprobe *krule;
182
183 krule = zmalloc(sizeof(struct lttng_event_rule_kprobe));
184 if (!krule) {
185 goto end;
186 }
187
188 rule = &krule->parent;
189 lttng_event_rule_init(&krule->parent, LTTNG_EVENT_RULE_TYPE_KPROBE);
190 krule->parent.validate = lttng_event_rule_kprobe_validate;
191 krule->parent.serialize = lttng_event_rule_kprobe_serialize;
192 krule->parent.equal = lttng_event_rule_kprobe_is_equal;
193 krule->parent.destroy = lttng_event_rule_kprobe_destroy;
194 krule->parent.generate_filter_bytecode =
195 lttng_event_rule_kprobe_generate_filter_bytecode;
196 krule->parent.get_filter = lttng_event_rule_kprobe_get_filter;
197 krule->parent.get_filter_bytecode =
198 lttng_event_rule_kprobe_get_filter_bytecode;
199 krule->parent.generate_exclusions =
200 lttng_event_rule_kprobe_generate_exclusions;
201end:
202 return rule;
203}
204
205LTTNG_HIDDEN
206ssize_t lttng_event_rule_kprobe_create_from_payload(
207 struct lttng_payload_view *view,
208 struct lttng_event_rule **_event_rule)
209{
210 ssize_t ret, offset = 0;
211 enum lttng_event_rule_status status;
212 const struct lttng_event_rule_kprobe_comm *kprobe_comm;
213 const char *name;
214 struct lttng_buffer_view current_buffer_view;
215 struct lttng_event_rule *rule = NULL;
216 struct lttng_event_rule_kprobe *kprobe = NULL;
217 struct lttng_kernel_probe_location *location;
218
219 if (!_event_rule) {
220 ret = -1;
221 goto end;
222 }
223
3e6e0df2
JG
224 current_buffer_view = lttng_buffer_view_from_view(
225 &view->buffer, offset, sizeof(*kprobe_comm));
226 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
077192fd
JR
227 ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header.");
228 ret = -1;
229 goto end;
230 }
231
077192fd 232 kprobe_comm = (typeof(kprobe_comm)) current_buffer_view.data;
077192fd
JR
233
234 rule = lttng_event_rule_kprobe_create();
235 if (!rule) {
236 ERR("Failed to create event rule kprobe.");
237 ret = -1;
238 goto end;
239 }
240
241 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
242
243 /* Skip to payload */
244 offset += current_buffer_view.size;
245
246 {
247 /* Map the name. */
248 struct lttng_payload_view current_payload_view =
249 lttng_payload_view_from_view(view, offset,
250 kprobe_comm->name_len);
251
3e6e0df2 252 if (!lttng_payload_view_is_valid(&current_payload_view)) {
077192fd
JR
253 ret = -1;
254 goto end;
255 }
256
3e6e0df2 257 name = current_payload_view.buffer.data;
077192fd
JR
258 if (!lttng_buffer_view_contains_string(
259 &current_payload_view.buffer, name,
260 kprobe_comm->name_len)) {
261 ret = -1;
262 goto end;
263 }
264 }
265
266 /* Skip after the name. */
267 offset += kprobe_comm->name_len;
268
269 /* Map the kernel probe location. */
270 {
271 struct lttng_payload_view current_payload_view =
272 lttng_payload_view_from_view(view, offset,
273 kprobe_comm->location_len);
274
3e6e0df2
JG
275 if (!lttng_payload_view_is_valid(&current_payload_view)) {
276 ret = -1;
277 goto end;
278 }
279
077192fd
JR
280 ret = lttng_kernel_probe_location_create_from_payload(
281 &current_payload_view, &location);
282 if (ret < 0) {
283 ret = -1;
284 goto end;
285 }
286 }
287
288 if (ret != kprobe_comm->location_len) {
289 ret = -1;
290 goto end;
291 }
292
293 kprobe->location = location;
294
295 /* Skip after the location */
296 offset += kprobe_comm->location_len;
297
298 status = lttng_event_rule_kprobe_set_name(rule, name);
299 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
300 ERR("Failed to set event rule kprobe name.");
301 ret = -1;
302 goto end;
303 }
304
305 *_event_rule = rule;
306 rule = NULL;
307 ret = offset;
308end:
309 lttng_event_rule_destroy(rule);
310 return ret;
311}
312
313enum lttng_event_rule_status lttng_event_rule_kprobe_set_location(
314 struct lttng_event_rule *rule,
315 const struct lttng_kernel_probe_location *location)
316{
317 struct lttng_kernel_probe_location *location_copy = NULL;
318 struct lttng_event_rule_kprobe *kprobe;
319 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
320
321 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !location) {
322 status = LTTNG_EVENT_RULE_STATUS_INVALID;
323 goto end;
324 }
325
326 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
327 location_copy = lttng_kernel_probe_location_copy(location);
328 if (!location_copy) {
329 status = LTTNG_EVENT_RULE_STATUS_ERROR;
330 goto end;
331 }
332
333 if (kprobe->location) {
334 lttng_kernel_probe_location_destroy(kprobe->location);
335 }
336
337 kprobe->location = location_copy;
338 location_copy = NULL;
339end:
340 lttng_kernel_probe_location_destroy(location_copy);
341 return status;
342}
343
344enum lttng_event_rule_status lttng_event_rule_kprobe_get_location(
345 const struct lttng_event_rule *rule,
346 const struct lttng_kernel_probe_location **location)
347{
348 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
349 struct lttng_event_rule_kprobe *kprobe;
350
351 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !location) {
352 status = LTTNG_EVENT_RULE_STATUS_INVALID;
353 goto end;
354 }
355
356 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
357 *location = kprobe->location;
358
359 if (!*location) {
360 status = LTTNG_EVENT_RULE_STATUS_UNSET;
361 goto end;
362 }
363
364end:
365 return status;
366}
367
368enum lttng_event_rule_status lttng_event_rule_kprobe_set_name(
369 struct lttng_event_rule *rule, const char *name)
370{
371 char *name_copy = NULL;
372 struct lttng_event_rule_kprobe *kprobe;
373 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
374
375 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name ||
376 strlen(name) == 0) {
377 status = LTTNG_EVENT_RULE_STATUS_INVALID;
378 goto end;
379 }
380
381 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
382 name_copy = strdup(name);
383 if (!name_copy) {
384 status = LTTNG_EVENT_RULE_STATUS_ERROR;
385 goto end;
386 }
387
388 free(kprobe->name);
389
390 kprobe->name = name_copy;
391 name_copy = NULL;
392end:
393 return status;
394}
395
396enum lttng_event_rule_status lttng_event_rule_kprobe_get_name(
397 const struct lttng_event_rule *rule, const char **name)
398{
399 struct lttng_event_rule_kprobe *kprobe;
400 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
401
402 if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name) {
403 status = LTTNG_EVENT_RULE_STATUS_INVALID;
404 goto end;
405 }
406
407 kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent);
408 if (!kprobe->name) {
409 status = LTTNG_EVENT_RULE_STATUS_UNSET;
410 goto end;
411 }
412
413 *name = kprobe->name;
414end:
415 return status;
416}
This page took 0.056571 seconds and 4 git commands to generate.