Refactoring: type description structures
[lttng-modules.git] / src / lttng-bytecode-interpreter.c
CommitLineData
9f36eaed
MJ
1/* SPDX-License-Identifier: MIT
2 *
80c2a69a 3 * lttng-bytecode-interpreter.c
07dfc1d0 4 *
80c2a69a 5 * LTTng modules bytecode interpreter.
07dfc1d0 6 *
bbf3aef5 7 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
07dfc1d0
MD
8 */
9
80bb2600 10#include <wrapper/uaccess.h>
d9053936 11#include <wrapper/objtool.h>
cbc19040 12#include <wrapper/types.h>
3834b99f 13#include <linux/swab.h>
f127e61e 14
80c2a69a 15#include <lttng/lttng-bytecode.h>
2df37e95 16#include <lttng/string-utils.h>
437d5aa5 17#include <lttng/events-internal.h>
07dfc1d0 18
f127e61e
MD
19/*
20 * get_char should be called with page fault handler disabled if it is expected
21 * to handle user-space read.
22 */
23static
acbe9250 24char get_char(const struct estack_entry *reg, size_t offset)
f127e61e
MD
25{
26 if (unlikely(offset >= reg->u.s.seq_len))
27 return '\0';
28 if (reg->u.s.user) {
29 char c;
30
31 /* Handle invalid access as end of string. */
80bb2600 32 if (unlikely(!lttng_access_ok(VERIFY_READ,
f127e61e
MD
33 reg->u.s.user_str + offset,
34 sizeof(c))))
35 return '\0';
36 /* Handle fault (nonzero return value) as end of string. */
37 if (unlikely(__copy_from_user_inatomic(&c,
38 reg->u.s.user_str + offset,
39 sizeof(c))))
40 return '\0';
41 return c;
42 } else {
43 return reg->u.s.str[offset];
44 }
45}
46
07dfc1d0
MD
47/*
48 * -1: wildcard found.
49 * -2: unknown escape char.
50 * 0: normal char.
51 */
07dfc1d0 52static
f127e61e 53int parse_char(struct estack_entry *reg, char *c, size_t *offset)
07dfc1d0 54{
f127e61e 55 switch (*c) {
07dfc1d0 56 case '\\':
f127e61e
MD
57 (*offset)++;
58 *c = get_char(reg, *offset);
59 switch (*c) {
07dfc1d0
MD
60 case '\\':
61 case '*':
62 return 0;
63 default:
64 return -2;
65 }
66 case '*':
67 return -1;
68 default:
69 return 0;
70 }
71}
72
02aca193
PP
73static
74char get_char_at_cb(size_t at, void *data)
75{
76 return get_char(data, at);
77}
78
79static
80int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
81{
82 bool has_user = false;
02aca193
PP
83 int result;
84 struct estack_entry *pattern_reg;
85 struct estack_entry *candidate_reg;
86
6f192a16 87 /* Disable the page fault handler when reading from userspace. */
02aca193
PP
88 if (estack_bx(stack, top)->u.s.user
89 || estack_ax(stack, top)->u.s.user) {
90 has_user = true;
02aca193
PP
91 pagefault_disable();
92 }
93
94 /* Find out which side is the pattern vs. the candidate. */
95 if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) {
96 pattern_reg = estack_ax(stack, top);
97 candidate_reg = estack_bx(stack, top);
98 } else {
99 pattern_reg = estack_bx(stack, top);
100 candidate_reg = estack_ax(stack, top);
101 }
102
103 /* Perform the match operation. */
104 result = !strutils_star_glob_match_char_cb(get_char_at_cb,
105 pattern_reg, get_char_at_cb, candidate_reg);
6f192a16 106 if (has_user)
02aca193 107 pagefault_enable();
02aca193
PP
108
109 return result;
110}
111
07dfc1d0
MD
112static
113int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
114{
f127e61e
MD
115 size_t offset_bx = 0, offset_ax = 0;
116 int diff, has_user = 0;
f127e61e
MD
117
118 if (estack_bx(stack, top)->u.s.user
119 || estack_ax(stack, top)->u.s.user) {
120 has_user = 1;
f127e61e
MD
121 pagefault_disable();
122 }
07dfc1d0
MD
123
124 for (;;) {
f127e61e 125 int ret;
07dfc1d0 126 int escaped_r0 = 0;
f127e61e 127 char char_bx, char_ax;
07dfc1d0 128
f127e61e
MD
129 char_bx = get_char(estack_bx(stack, top), offset_bx);
130 char_ax = get_char(estack_ax(stack, top), offset_ax);
131
132 if (unlikely(char_bx == '\0')) {
133 if (char_ax == '\0') {
134 diff = 0;
135 break;
07dfc1d0 136 } else {
02aca193
PP
137 if (estack_ax(stack, top)->u.s.literal_type ==
138 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
f127e61e
MD
139 ret = parse_char(estack_ax(stack, top),
140 &char_ax, &offset_ax);
141 if (ret == -1) {
142 diff = 0;
143 break;
144 }
07dfc1d0 145 }
f127e61e
MD
146 diff = -1;
147 break;
07dfc1d0
MD
148 }
149 }
f127e61e 150 if (unlikely(char_ax == '\0')) {
02aca193
PP
151 if (estack_bx(stack, top)->u.s.literal_type ==
152 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
abfd272b
MD
153 ret = parse_char(estack_bx(stack, top),
154 &char_bx, &offset_bx);
155 if (ret == -1) {
156 diff = 0;
157 break;
07dfc1d0 158 }
07dfc1d0 159 }
abfd272b
MD
160 diff = 1;
161 break;
07dfc1d0 162 }
02aca193
PP
163 if (estack_bx(stack, top)->u.s.literal_type ==
164 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
f127e61e
MD
165 ret = parse_char(estack_bx(stack, top),
166 &char_bx, &offset_bx);
07dfc1d0 167 if (ret == -1) {
f127e61e
MD
168 diff = 0;
169 break;
07dfc1d0
MD
170 } else if (ret == -2) {
171 escaped_r0 = 1;
172 }
173 /* else compare both char */
174 }
02aca193
PP
175 if (estack_ax(stack, top)->u.s.literal_type ==
176 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
f127e61e
MD
177 ret = parse_char(estack_ax(stack, top),
178 &char_ax, &offset_ax);
07dfc1d0 179 if (ret == -1) {
f127e61e
MD
180 diff = 0;
181 break;
07dfc1d0 182 } else if (ret == -2) {
f127e61e
MD
183 if (!escaped_r0) {
184 diff = -1;
185 break;
186 }
07dfc1d0 187 } else {
f127e61e
MD
188 if (escaped_r0) {
189 diff = 1;
190 break;
191 }
07dfc1d0
MD
192 }
193 } else {
f127e61e
MD
194 if (escaped_r0) {
195 diff = 1;
196 break;
197 }
07dfc1d0 198 }
f127e61e 199 diff = char_bx - char_ax;
07dfc1d0
MD
200 if (diff != 0)
201 break;
f127e61e
MD
202 offset_bx++;
203 offset_ax++;
204 }
6f192a16 205 if (has_user)
f127e61e 206 pagefault_enable();
6f192a16 207
07dfc1d0
MD
208 return diff;
209}
210
80c2a69a 211uint64_t lttng_bytecode_filter_interpret_false(void *filter_data,
79150a49 212 struct lttng_probe_ctx *lttng_probe_ctx,
07dfc1d0
MD
213 const char *filter_stack_data)
214{
80c2a69a 215 return LTTNG_INTERPRETER_DISCARD;
07dfc1d0
MD
216}
217
99d223ad
FD
218uint64_t lttng_bytecode_capture_interpret_false(void *filter_data,
219 struct lttng_probe_ctx *lttng_probe_ctx,
220 const char *capture_stack_data,
221 struct lttng_interpreter_output *output)
222{
223 return LTTNG_INTERPRETER_DISCARD;
224}
225
07dfc1d0
MD
226#ifdef INTERPRETER_USE_SWITCH
227
228/*
229 * Fallback for compilers that do not support taking address of labels.
230 */
231
232#define START_OP \
233 start_pc = &bytecode->data[0]; \
234 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
235 pc = next_pc) { \
5a15f70c 236 dbg_printk("LTTng: Executing op %s (%u)\n", \
80c2a69a
FD
237 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc), \
238 (unsigned int) *(bytecode_opcode_t *) pc); \
239 switch (*(bytecode_opcode_t *) pc) {
07dfc1d0
MD
240
241#define OP(name) case name
242
243#define PO break
244
245#define END_OP } \
246 }
247
248#else
249
250/*
251 * Dispatch-table based interpreter.
252 */
253
254#define START_OP \
3834b99f 255 start_pc = &bytecode->code[0]; \
07dfc1d0
MD
256 pc = next_pc = start_pc; \
257 if (unlikely(pc - start_pc >= bytecode->len)) \
258 goto end; \
80c2a69a 259 goto *dispatch[*(bytecode_opcode_t *) pc];
07dfc1d0
MD
260
261#define OP(name) \
262LABEL_##name
263
264#define PO \
265 pc = next_pc; \
80c2a69a 266 goto *dispatch[*(bytecode_opcode_t *) pc];
07dfc1d0
MD
267
268#define END_OP
269
270#endif
271
1242217a
FD
272#define IS_INTEGER_REGISTER(reg_type) \
273 (reg_type == REG_S64 || reg_type == REG_U64)
d644d1df 274
3834b99f
MD
275static int context_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
276 struct load_ptr *ptr,
277 uint32_t idx)
278{
279
437d5aa5
MD
280 struct lttng_kernel_ctx_field *ctx_field;
281 const struct lttng_kernel_event_field *field;
3834b99f
MD
282 union lttng_ctx_value v;
283
284 ctx_field = &lttng_static_ctx->fields[idx];
437d5aa5 285 field = ctx_field->event_field;
3834b99f
MD
286 ptr->type = LOAD_OBJECT;
287 /* field is only used for types nested within variants. */
288 ptr->field = NULL;
289
437d5aa5 290 switch (field->type->type) {
12bb2edb 291 case lttng_kernel_type_integer:
3834b99f 292 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
437d5aa5 293 if (lttng_kernel_get_type_integer(field->type)->signedness) {
3834b99f
MD
294 ptr->object_type = OBJECT_TYPE_S64;
295 ptr->u.s64 = v.s64;
296 ptr->ptr = &ptr->u.s64;
297 } else {
298 ptr->object_type = OBJECT_TYPE_U64;
299 ptr->u.u64 = v.s64; /* Cast. */
300 ptr->ptr = &ptr->u.u64;
301 }
302 break;
437d5aa5 303 case lttng_kernel_type_enum:
3834b99f 304 {
437d5aa5
MD
305 const struct lttng_kernel_type_enum *enum_type = lttng_kernel_get_type_enum(field->type);
306 const struct lttng_kernel_type_integer *integer_type = lttng_kernel_get_type_integer(enum_type->container_type);
3834b99f
MD
307
308 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
437d5aa5 309 if (integer_type->signedness) {
29a574c3 310 ptr->object_type = OBJECT_TYPE_SIGNED_ENUM;
3834b99f
MD
311 ptr->u.s64 = v.s64;
312 ptr->ptr = &ptr->u.s64;
313 } else {
29a574c3 314 ptr->object_type = OBJECT_TYPE_UNSIGNED_ENUM;
3834b99f
MD
315 ptr->u.u64 = v.s64; /* Cast. */
316 ptr->ptr = &ptr->u.u64;
317 }
318 break;
319 }
437d5aa5
MD
320 case lttng_kernel_type_array:
321 {
322 const struct lttng_kernel_type_array *array_type = lttng_kernel_get_type_array(field->type);
323
324 if (!lttng_kernel_type_is_bytewise_integer(array_type->elem_type)) {
80c2a69a 325 printk(KERN_WARNING "LTTng: bytecode: Array nesting only supports integer types.\n");
3834b99f
MD
326 return -EINVAL;
327 }
437d5aa5 328 if (array_type->encoding == lttng_kernel_string_encoding_none) {
80c2a69a 329 printk(KERN_WARNING "LTTng: bytecode: Only string arrays are supported for contexts.\n");
3834b99f
MD
330 return -EINVAL;
331 }
332 ptr->object_type = OBJECT_TYPE_STRING;
333 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
334 ptr->ptr = v.str;
335 break;
437d5aa5
MD
336 }
337 case lttng_kernel_type_sequence:
338 {
339 const struct lttng_kernel_type_sequence *sequence_type = lttng_kernel_get_type_sequence(field->type);
340
341 if (!lttng_kernel_type_is_bytewise_integer(sequence_type->elem_type)) {
80c2a69a 342 printk(KERN_WARNING "LTTng: bytecode: Sequence nesting only supports integer types.\n");
3834b99f
MD
343 return -EINVAL;
344 }
437d5aa5 345 if (sequence_type->encoding == lttng_kernel_string_encoding_none) {
80c2a69a 346 printk(KERN_WARNING "LTTng: bytecode: Only string sequences are supported for contexts.\n");
3834b99f
MD
347 return -EINVAL;
348 }
349 ptr->object_type = OBJECT_TYPE_STRING;
350 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
351 ptr->ptr = v.str;
352 break;
437d5aa5 353 }
12bb2edb 354 case lttng_kernel_type_string:
3834b99f
MD
355 ptr->object_type = OBJECT_TYPE_STRING;
356 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
357 ptr->ptr = v.str;
358 break;
437d5aa5 359 case lttng_kernel_type_struct:
80c2a69a 360 printk(KERN_WARNING "LTTng: bytecode: Structure type cannot be loaded.\n");
3834b99f 361 return -EINVAL;
437d5aa5 362 case lttng_kernel_type_variant:
80c2a69a 363 printk(KERN_WARNING "LTTng: bytecode: Variant type cannot be loaded.\n");
ceabb767 364 return -EINVAL;
3834b99f 365 default:
437d5aa5 366 printk(KERN_WARNING "LTTng: bytecode: Unknown type: %d", (int) field->type->type);
3834b99f
MD
367 return -EINVAL;
368 }
369 return 0;
370}
371
372static int dynamic_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
373 struct bytecode_runtime *runtime,
374 uint64_t index, struct estack_entry *stack_top)
375{
376 int ret;
80c2a69a 377 const struct bytecode_get_index_data *gid;
3834b99f 378
80c2a69a 379 gid = (const struct bytecode_get_index_data *) &runtime->data[index];
3834b99f
MD
380 switch (stack_top->u.ptr.type) {
381 case LOAD_OBJECT:
382 switch (stack_top->u.ptr.object_type) {
383 case OBJECT_TYPE_ARRAY:
384 {
385 const char *ptr;
386
387 WARN_ON_ONCE(gid->offset >= gid->array_len);
388 /* Skip count (unsigned long) */
389 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
390 ptr = ptr + gid->offset;
391 stack_top->u.ptr.ptr = ptr;
392 stack_top->u.ptr.object_type = gid->elem.type;
393 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
437d5aa5 394 BUG_ON(stack_top->u.ptr.field->type->type != lttng_kernel_type_array);
3834b99f
MD
395 stack_top->u.ptr.field = NULL;
396 break;
397 }
398 case OBJECT_TYPE_SEQUENCE:
399 {
400 const char *ptr;
401 size_t ptr_seq_len;
402
403 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
404 ptr_seq_len = *(unsigned long *) stack_top->u.ptr.ptr;
405 if (gid->offset >= gid->elem.len * ptr_seq_len) {
406 ret = -EINVAL;
407 goto end;
408 }
409 ptr = ptr + gid->offset;
410 stack_top->u.ptr.ptr = ptr;
411 stack_top->u.ptr.object_type = gid->elem.type;
412 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
437d5aa5 413 BUG_ON(stack_top->u.ptr.field->type->type != lttng_kernel_type_sequence);
3834b99f
MD
414 stack_top->u.ptr.field = NULL;
415 break;
416 }
417 case OBJECT_TYPE_STRUCT:
80c2a69a 418 printk(KERN_WARNING "LTTng: bytecode: Nested structures are not supported yet.\n");
3834b99f
MD
419 ret = -EINVAL;
420 goto end;
421 case OBJECT_TYPE_VARIANT:
422 default:
80c2a69a 423 printk(KERN_WARNING "LTTng: bytecode: Unexpected get index type %d",
3834b99f
MD
424 (int) stack_top->u.ptr.object_type);
425 ret = -EINVAL;
426 goto end;
427 }
428 break;
429 case LOAD_ROOT_CONTEXT:
430 case LOAD_ROOT_APP_CONTEXT: /* Fall-through */
431 {
432 ret = context_get_index(lttng_probe_ctx,
433 &stack_top->u.ptr,
434 gid->ctx_index);
435 if (ret) {
436 goto end;
437 }
438 break;
439 }
440 case LOAD_ROOT_PAYLOAD:
441 stack_top->u.ptr.ptr += gid->offset;
442 if (gid->elem.type == OBJECT_TYPE_STRING)
443 stack_top->u.ptr.ptr = *(const char * const *) stack_top->u.ptr.ptr;
444 stack_top->u.ptr.object_type = gid->elem.type;
445 stack_top->u.ptr.type = LOAD_OBJECT;
03cb0cdd 446 stack_top->u.ptr.field = gid->field;
60e8b0d6 447 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
3834b99f
MD
448 break;
449 }
196e531f
FD
450
451 stack_top->type = REG_PTR;
452
3834b99f
MD
453 return 0;
454
455end:
456 return ret;
457}
458
459static int dynamic_load_field(struct estack_entry *stack_top)
460{
461 int ret;
462
463 switch (stack_top->u.ptr.type) {
464 case LOAD_OBJECT:
465 break;
466 case LOAD_ROOT_CONTEXT:
467 case LOAD_ROOT_APP_CONTEXT:
468 case LOAD_ROOT_PAYLOAD:
469 default:
80c2a69a 470 dbg_printk("Bytecode warning: cannot load root, missing field name.\n");
3834b99f
MD
471 ret = -EINVAL;
472 goto end;
473 }
474 switch (stack_top->u.ptr.object_type) {
475 case OBJECT_TYPE_S8:
476 dbg_printk("op load field s8\n");
477 stack_top->u.v = *(int8_t *) stack_top->u.ptr.ptr;
d644d1df 478 stack_top->type = REG_S64;
3834b99f
MD
479 break;
480 case OBJECT_TYPE_S16:
481 {
482 int16_t tmp;
483
484 dbg_printk("op load field s16\n");
485 tmp = *(int16_t *) stack_top->u.ptr.ptr;
486 if (stack_top->u.ptr.rev_bo)
487 __swab16s(&tmp);
488 stack_top->u.v = tmp;
d644d1df 489 stack_top->type = REG_S64;
3834b99f
MD
490 break;
491 }
492 case OBJECT_TYPE_S32:
493 {
494 int32_t tmp;
495
496 dbg_printk("op load field s32\n");
497 tmp = *(int32_t *) stack_top->u.ptr.ptr;
498 if (stack_top->u.ptr.rev_bo)
499 __swab32s(&tmp);
500 stack_top->u.v = tmp;
d644d1df 501 stack_top->type = REG_S64;
3834b99f
MD
502 break;
503 }
504 case OBJECT_TYPE_S64:
505 {
506 int64_t tmp;
507
508 dbg_printk("op load field s64\n");
509 tmp = *(int64_t *) stack_top->u.ptr.ptr;
510 if (stack_top->u.ptr.rev_bo)
511 __swab64s(&tmp);
512 stack_top->u.v = tmp;
d644d1df 513 stack_top->type = REG_S64;
3834b99f
MD
514 break;
515 }
29a574c3
FD
516 case OBJECT_TYPE_SIGNED_ENUM:
517 {
518 int64_t tmp;
519
520 dbg_printk("op load field signed enumeration\n");
521 tmp = *(int64_t *) stack_top->u.ptr.ptr;
522 if (stack_top->u.ptr.rev_bo)
523 __swab64s(&tmp);
524 stack_top->u.v = tmp;
525 stack_top->type = REG_S64;
526 break;
527 }
3834b99f
MD
528 case OBJECT_TYPE_U8:
529 dbg_printk("op load field u8\n");
530 stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
1242217a 531 stack_top->type = REG_U64;
3834b99f
MD
532 break;
533 case OBJECT_TYPE_U16:
534 {
535 uint16_t tmp;
536
5fae98f7 537 dbg_printk("op load field u16\n");
3834b99f
MD
538 tmp = *(uint16_t *) stack_top->u.ptr.ptr;
539 if (stack_top->u.ptr.rev_bo)
540 __swab16s(&tmp);
541 stack_top->u.v = tmp;
1242217a 542 stack_top->type = REG_U64;
3834b99f
MD
543 break;
544 }
545 case OBJECT_TYPE_U32:
546 {
547 uint32_t tmp;
548
549 dbg_printk("op load field u32\n");
550 tmp = *(uint32_t *) stack_top->u.ptr.ptr;
551 if (stack_top->u.ptr.rev_bo)
552 __swab32s(&tmp);
553 stack_top->u.v = tmp;
1242217a 554 stack_top->type = REG_U64;
3834b99f
MD
555 break;
556 }
557 case OBJECT_TYPE_U64:
558 {
559 uint64_t tmp;
560
561 dbg_printk("op load field u64\n");
562 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
563 if (stack_top->u.ptr.rev_bo)
564 __swab64s(&tmp);
565 stack_top->u.v = tmp;
1242217a 566 stack_top->type = REG_U64;
3834b99f
MD
567 break;
568 }
29a574c3
FD
569 case OBJECT_TYPE_UNSIGNED_ENUM:
570 {
571 uint64_t tmp;
572
573 dbg_printk("op load field unsigned enumeration\n");
574 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
575 if (stack_top->u.ptr.rev_bo)
576 __swab64s(&tmp);
577 stack_top->u.v = tmp;
578 stack_top->type = REG_U64;
579 break;
580 }
3834b99f
MD
581 case OBJECT_TYPE_STRING:
582 {
583 const char *str;
584
585 dbg_printk("op load field string\n");
586 str = (const char *) stack_top->u.ptr.ptr;
587 stack_top->u.s.str = str;
588 if (unlikely(!stack_top->u.s.str)) {
80c2a69a 589 dbg_printk("Bytecode warning: loading a NULL string.\n");
3834b99f
MD
590 ret = -EINVAL;
591 goto end;
592 }
4efe037b 593 stack_top->u.s.seq_len = LTTNG_SIZE_MAX;
3834b99f
MD
594 stack_top->u.s.literal_type =
595 ESTACK_STRING_LITERAL_TYPE_NONE;
d644d1df 596 stack_top->type = REG_STRING;
3834b99f
MD
597 break;
598 }
599 case OBJECT_TYPE_STRING_SEQUENCE:
600 {
601 const char *ptr;
602
603 dbg_printk("op load field string sequence\n");
604 ptr = stack_top->u.ptr.ptr;
605 stack_top->u.s.seq_len = *(unsigned long *) ptr;
606 stack_top->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
607 if (unlikely(!stack_top->u.s.str)) {
80c2a69a 608 dbg_printk("Bytecode warning: loading a NULL sequence.\n");
3834b99f
MD
609 ret = -EINVAL;
610 goto end;
611 }
612 stack_top->u.s.literal_type =
613 ESTACK_STRING_LITERAL_TYPE_NONE;
d644d1df 614 stack_top->type = REG_STRING;
3834b99f
MD
615 break;
616 }
617 case OBJECT_TYPE_DYNAMIC:
618 /*
619 * Dynamic types in context are looked up
620 * by context get index.
621 */
622 ret = -EINVAL;
623 goto end;
624 case OBJECT_TYPE_DOUBLE:
625 ret = -EINVAL;
626 goto end;
627 case OBJECT_TYPE_SEQUENCE:
628 case OBJECT_TYPE_ARRAY:
629 case OBJECT_TYPE_STRUCT:
630 case OBJECT_TYPE_VARIANT:
80c2a69a 631 printk(KERN_WARNING "LTTng: bytecode: Sequences, arrays, struct and variant cannot be loaded (nested types).\n");
3834b99f
MD
632 ret = -EINVAL;
633 goto end;
634 }
635 return 0;
636
637end:
638 return ret;
639}
640
03cb0cdd
FD
641static
642int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
643 struct lttng_interpreter_output *output)
644{
645 int ret;
646
647again:
648 switch (ax->type) {
649 case REG_S64:
650 output->type = LTTNG_INTERPRETER_TYPE_S64;
651 output->u.s = ax->u.v;
652 break;
653 case REG_U64:
654 output->type = LTTNG_INTERPRETER_TYPE_U64;
655 output->u.u = (uint64_t) ax->u.v;
656 break;
657 case REG_STRING:
658 output->type = LTTNG_INTERPRETER_TYPE_STRING;
659 output->u.str.str = ax->u.s.str;
660 output->u.str.len = ax->u.s.seq_len;
661 break;
662 case REG_PTR:
663 switch (ax->u.ptr.object_type) {
664 case OBJECT_TYPE_S8:
665 case OBJECT_TYPE_S16:
666 case OBJECT_TYPE_S32:
667 case OBJECT_TYPE_S64:
668 case OBJECT_TYPE_U8:
669 case OBJECT_TYPE_U16:
670 case OBJECT_TYPE_U32:
671 case OBJECT_TYPE_U64:
672 case OBJECT_TYPE_DOUBLE:
673 case OBJECT_TYPE_STRING:
674 case OBJECT_TYPE_STRING_SEQUENCE:
675 ret = dynamic_load_field(ax);
676 if (ret)
677 return ret;
678 /* Retry after loading ptr into stack top. */
679 goto again;
680 case OBJECT_TYPE_SEQUENCE:
681 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
682 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
683 output->u.sequence.nr_elem = *(unsigned long *) ax->u.ptr.ptr;
437d5aa5 684 output->u.sequence.nested_type = lttng_kernel_get_type_sequence(ax->u.ptr.field->type)->elem_type;
03cb0cdd
FD
685 break;
686 case OBJECT_TYPE_ARRAY:
687 /* Skip count (unsigned long) */
688 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
689 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
437d5aa5
MD
690 output->u.sequence.nr_elem = lttng_kernel_get_type_array(ax->u.ptr.field->type)->length;
691 output->u.sequence.nested_type = lttng_kernel_get_type_array(ax->u.ptr.field->type)->elem_type;
03cb0cdd 692 break;
29a574c3
FD
693 case OBJECT_TYPE_SIGNED_ENUM:
694 ret = dynamic_load_field(ax);
695 if (ret)
696 return ret;
697 output->type = LTTNG_INTERPRETER_TYPE_SIGNED_ENUM;
698 output->u.s = ax->u.v;
699 break;
700 case OBJECT_TYPE_UNSIGNED_ENUM:
701 ret = dynamic_load_field(ax);
702 if (ret)
703 return ret;
704 output->type = LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM;
705 output->u.u = ax->u.v;
706 break;
03cb0cdd
FD
707 case OBJECT_TYPE_STRUCT:
708 case OBJECT_TYPE_VARIANT:
709 default:
710 return -EINVAL;
711 }
712
713 break;
714 case REG_STAR_GLOB_STRING:
715 case REG_TYPE_UNKNOWN:
716 default:
717 return -EINVAL;
718 }
719
80c2a69a 720 return LTTNG_INTERPRETER_RECORD_FLAG;
03cb0cdd
FD
721}
722
acbe9250
JG
723#ifdef DEBUG
724
725#define DBG_USER_STR_CUTOFF 32
726
727/*
728 * In debug mode, print user string (truncated, if necessary).
729 */
730static inline
731void dbg_load_ref_user_str_printk(const struct estack_entry *user_str_reg)
732{
733 size_t pos = 0;
734 char last_char;
735 char user_str[DBG_USER_STR_CUTOFF];
736
737 pagefault_disable();
738 do {
739 last_char = get_char(user_str_reg, pos);
740 user_str[pos] = last_char;
741 pos++;
742 } while (last_char != '\0' && pos < sizeof(user_str));
743 pagefault_enable();
744
745 user_str[sizeof(user_str) - 1] = '\0';
746 dbg_printk("load field ref user string: '%s%s'\n", user_str,
747 last_char != '\0' ? "[...]" : "");
748}
749#else
750static inline
751void dbg_load_ref_user_str_printk(const struct estack_entry *user_str_reg)
752{
753}
754#endif
755
07dfc1d0
MD
756/*
757 * Return 0 (discard), or raise the 0x1 flag (log event).
758 * Currently, other flags are kept for future extensions and have no
759 * effect.
760 */
03cb0cdd
FD
761static
762uint64_t bytecode_interpret(void *interpreter_data,
79150a49 763 struct lttng_probe_ctx *lttng_probe_ctx,
03cb0cdd
FD
764 const char *interpreter_stack_data,
765 struct lttng_interpreter_output *output)
07dfc1d0 766{
03cb0cdd 767 struct bytecode_runtime *bytecode = interpreter_data;
07dfc1d0
MD
768 void *pc, *next_pc, *start_pc;
769 int ret = -EINVAL;
770 uint64_t retval = 0;
771 struct estack _stack;
772 struct estack *stack = &_stack;
773 register int64_t ax = 0, bx = 0;
d644d1df 774 register enum entry_type ax_t = REG_TYPE_UNKNOWN, bx_t = REG_TYPE_UNKNOWN;
80c2a69a 775 register int top = INTERPRETER_STACK_EMPTY;
07dfc1d0 776#ifndef INTERPRETER_USE_SWITCH
80c2a69a
FD
777 static void *dispatch[NR_BYTECODE_OPS] = {
778 [ BYTECODE_OP_UNKNOWN ] = &&LABEL_BYTECODE_OP_UNKNOWN,
07dfc1d0 779
80c2a69a 780 [ BYTECODE_OP_RETURN ] = &&LABEL_BYTECODE_OP_RETURN,
07dfc1d0
MD
781
782 /* binary */
80c2a69a
FD
783 [ BYTECODE_OP_MUL ] = &&LABEL_BYTECODE_OP_MUL,
784 [ BYTECODE_OP_DIV ] = &&LABEL_BYTECODE_OP_DIV,
785 [ BYTECODE_OP_MOD ] = &&LABEL_BYTECODE_OP_MOD,
786 [ BYTECODE_OP_PLUS ] = &&LABEL_BYTECODE_OP_PLUS,
787 [ BYTECODE_OP_MINUS ] = &&LABEL_BYTECODE_OP_MINUS,
788 [ BYTECODE_OP_BIT_RSHIFT ] = &&LABEL_BYTECODE_OP_BIT_RSHIFT,
789 [ BYTECODE_OP_BIT_LSHIFT ] = &&LABEL_BYTECODE_OP_BIT_LSHIFT,
790 [ BYTECODE_OP_BIT_AND ] = &&LABEL_BYTECODE_OP_BIT_AND,
791 [ BYTECODE_OP_BIT_OR ] = &&LABEL_BYTECODE_OP_BIT_OR,
792 [ BYTECODE_OP_BIT_XOR ] = &&LABEL_BYTECODE_OP_BIT_XOR,
07dfc1d0
MD
793
794 /* binary comparators */
80c2a69a
FD
795 [ BYTECODE_OP_EQ ] = &&LABEL_BYTECODE_OP_EQ,
796 [ BYTECODE_OP_NE ] = &&LABEL_BYTECODE_OP_NE,
797 [ BYTECODE_OP_GT ] = &&LABEL_BYTECODE_OP_GT,
798 [ BYTECODE_OP_LT ] = &&LABEL_BYTECODE_OP_LT,
799 [ BYTECODE_OP_GE ] = &&LABEL_BYTECODE_OP_GE,
800 [ BYTECODE_OP_LE ] = &&LABEL_BYTECODE_OP_LE,
07dfc1d0
MD
801
802 /* string binary comparator */
80c2a69a
FD
803 [ BYTECODE_OP_EQ_STRING ] = &&LABEL_BYTECODE_OP_EQ_STRING,
804 [ BYTECODE_OP_NE_STRING ] = &&LABEL_BYTECODE_OP_NE_STRING,
805 [ BYTECODE_OP_GT_STRING ] = &&LABEL_BYTECODE_OP_GT_STRING,
806 [ BYTECODE_OP_LT_STRING ] = &&LABEL_BYTECODE_OP_LT_STRING,
807 [ BYTECODE_OP_GE_STRING ] = &&LABEL_BYTECODE_OP_GE_STRING,
808 [ BYTECODE_OP_LE_STRING ] = &&LABEL_BYTECODE_OP_LE_STRING,
07dfc1d0 809
02aca193 810 /* globbing pattern binary comparator */
80c2a69a
FD
811 [ BYTECODE_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_EQ_STAR_GLOB_STRING,
812 [ BYTECODE_OP_NE_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_NE_STAR_GLOB_STRING,
02aca193 813
07dfc1d0 814 /* s64 binary comparator */
80c2a69a
FD
815 [ BYTECODE_OP_EQ_S64 ] = &&LABEL_BYTECODE_OP_EQ_S64,
816 [ BYTECODE_OP_NE_S64 ] = &&LABEL_BYTECODE_OP_NE_S64,
817 [ BYTECODE_OP_GT_S64 ] = &&LABEL_BYTECODE_OP_GT_S64,
818 [ BYTECODE_OP_LT_S64 ] = &&LABEL_BYTECODE_OP_LT_S64,
819 [ BYTECODE_OP_GE_S64 ] = &&LABEL_BYTECODE_OP_GE_S64,
820 [ BYTECODE_OP_LE_S64 ] = &&LABEL_BYTECODE_OP_LE_S64,
07dfc1d0
MD
821
822 /* double binary comparator */
80c2a69a
FD
823 [ BYTECODE_OP_EQ_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE,
824 [ BYTECODE_OP_NE_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_DOUBLE,
825 [ BYTECODE_OP_GT_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_DOUBLE,
826 [ BYTECODE_OP_LT_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_DOUBLE,
827 [ BYTECODE_OP_GE_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_DOUBLE,
828 [ BYTECODE_OP_LE_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_DOUBLE,
07dfc1d0
MD
829
830 /* Mixed S64-double binary comparators */
80c2a69a
FD
831 [ BYTECODE_OP_EQ_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE_S64,
832 [ BYTECODE_OP_NE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_NE_DOUBLE_S64,
833 [ BYTECODE_OP_GT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GT_DOUBLE_S64,
834 [ BYTECODE_OP_LT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LT_DOUBLE_S64,
835 [ BYTECODE_OP_GE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GE_DOUBLE_S64,
836 [ BYTECODE_OP_LE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LE_DOUBLE_S64,
837
838 [ BYTECODE_OP_EQ_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_S64_DOUBLE,
839 [ BYTECODE_OP_NE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_S64_DOUBLE,
840 [ BYTECODE_OP_GT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_S64_DOUBLE,
841 [ BYTECODE_OP_LT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_S64_DOUBLE,
842 [ BYTECODE_OP_GE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_S64_DOUBLE,
843 [ BYTECODE_OP_LE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_S64_DOUBLE,
07dfc1d0
MD
844
845 /* unary */
80c2a69a
FD
846 [ BYTECODE_OP_UNARY_PLUS ] = &&LABEL_BYTECODE_OP_UNARY_PLUS,
847 [ BYTECODE_OP_UNARY_MINUS ] = &&LABEL_BYTECODE_OP_UNARY_MINUS,
848 [ BYTECODE_OP_UNARY_NOT ] = &&LABEL_BYTECODE_OP_UNARY_NOT,
849 [ BYTECODE_OP_UNARY_PLUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_S64,
850 [ BYTECODE_OP_UNARY_MINUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_S64,
851 [ BYTECODE_OP_UNARY_NOT_S64 ] = &&LABEL_BYTECODE_OP_UNARY_NOT_S64,
852 [ BYTECODE_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_DOUBLE,
853 [ BYTECODE_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_DOUBLE,
854 [ BYTECODE_OP_UNARY_NOT_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_NOT_DOUBLE,
07dfc1d0
MD
855
856 /* logical */
80c2a69a
FD
857 [ BYTECODE_OP_AND ] = &&LABEL_BYTECODE_OP_AND,
858 [ BYTECODE_OP_OR ] = &&LABEL_BYTECODE_OP_OR,
07dfc1d0
MD
859
860 /* load field ref */
80c2a69a
FD
861 [ BYTECODE_OP_LOAD_FIELD_REF ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF,
862 [ BYTECODE_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_STRING,
863 [ BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE,
864 [ BYTECODE_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_S64,
865 [ BYTECODE_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_DOUBLE,
07dfc1d0
MD
866
867 /* load from immediate operand */
80c2a69a
FD
868 [ BYTECODE_OP_LOAD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STRING,
869 [ BYTECODE_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STAR_GLOB_STRING,
870 [ BYTECODE_OP_LOAD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_S64,
871 [ BYTECODE_OP_LOAD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_DOUBLE,
07dfc1d0
MD
872
873 /* cast */
80c2a69a
FD
874 [ BYTECODE_OP_CAST_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_TO_S64,
875 [ BYTECODE_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_DOUBLE_TO_S64,
876 [ BYTECODE_OP_CAST_NOP ] = &&LABEL_BYTECODE_OP_CAST_NOP,
07dfc1d0
MD
877
878 /* get context ref */
80c2a69a
FD
879 [ BYTECODE_OP_GET_CONTEXT_REF ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF,
880 [ BYTECODE_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_STRING,
881 [ BYTECODE_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_S64,
882 [ BYTECODE_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_DOUBLE,
f127e61e
MD
883
884 /* load userspace field ref */
80c2a69a
FD
885 [ BYTECODE_OP_LOAD_FIELD_REF_USER_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_USER_STRING,
886 [ BYTECODE_OP_LOAD_FIELD_REF_USER_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_USER_SEQUENCE,
3834b99f
MD
887
888 /* Instructions for recursive traversal through composed types. */
80c2a69a
FD
889 [ BYTECODE_OP_GET_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_ROOT,
890 [ BYTECODE_OP_GET_APP_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_APP_CONTEXT_ROOT,
891 [ BYTECODE_OP_GET_PAYLOAD_ROOT ] = &&LABEL_BYTECODE_OP_GET_PAYLOAD_ROOT,
892
893 [ BYTECODE_OP_GET_SYMBOL ] = &&LABEL_BYTECODE_OP_GET_SYMBOL,
894 [ BYTECODE_OP_GET_SYMBOL_FIELD ] = &&LABEL_BYTECODE_OP_GET_SYMBOL_FIELD,
895 [ BYTECODE_OP_GET_INDEX_U16 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U16,
896 [ BYTECODE_OP_GET_INDEX_U64 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U64,
897
898 [ BYTECODE_OP_LOAD_FIELD ] = &&LABEL_BYTECODE_OP_LOAD_FIELD,
899 [ BYTECODE_OP_LOAD_FIELD_S8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S8,
900 [ BYTECODE_OP_LOAD_FIELD_S16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S16,
901 [ BYTECODE_OP_LOAD_FIELD_S32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S32,
902 [ BYTECODE_OP_LOAD_FIELD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S64,
903 [ BYTECODE_OP_LOAD_FIELD_U8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U8,
904 [ BYTECODE_OP_LOAD_FIELD_U16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U16,
905 [ BYTECODE_OP_LOAD_FIELD_U32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U32,
906 [ BYTECODE_OP_LOAD_FIELD_U64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U64,
907 [ BYTECODE_OP_LOAD_FIELD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_STRING,
908 [ BYTECODE_OP_LOAD_FIELD_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_SEQUENCE,
909 [ BYTECODE_OP_LOAD_FIELD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_DOUBLE,
910
911 [ BYTECODE_OP_UNARY_BIT_NOT ] = &&LABEL_BYTECODE_OP_UNARY_BIT_NOT,
912
913 [ BYTECODE_OP_RETURN_S64 ] = &&LABEL_BYTECODE_OP_RETURN_S64,
07dfc1d0
MD
914 };
915#endif /* #ifndef INTERPRETER_USE_SWITCH */
916
917 START_OP
918
80c2a69a
FD
919 OP(BYTECODE_OP_UNKNOWN):
920 OP(BYTECODE_OP_LOAD_FIELD_REF):
921 OP(BYTECODE_OP_GET_CONTEXT_REF):
07dfc1d0
MD
922#ifdef INTERPRETER_USE_SWITCH
923 default:
924#endif /* INTERPRETER_USE_SWITCH */
80c2a69a
FD
925 printk(KERN_WARNING "LTTng: bytecode: unknown bytecode op %u\n",
926 (unsigned int) *(bytecode_opcode_t *) pc);
07dfc1d0
MD
927 ret = -EINVAL;
928 goto end;
929
80c2a69a
FD
930 OP(BYTECODE_OP_RETURN):
931 OP(BYTECODE_OP_RETURN_S64):
932 /* LTTNG_INTERPRETER_DISCARD or LTTNG_INTERPRETER_RECORD_FLAG */
d644d1df
FD
933 switch (estack_ax_t) {
934 case REG_S64:
1242217a 935 case REG_U64:
d644d1df
FD
936 retval = !!estack_ax_v;
937 break;
938 case REG_DOUBLE:
939 case REG_STRING:
940 case REG_PTR:
03cb0cdd
FD
941 if (!output) {
942 ret = -EINVAL;
943 goto end;
944 }
945 retval = 0;
946 break;
d644d1df
FD
947 case REG_STAR_GLOB_STRING:
948 case REG_TYPE_UNKNOWN:
949 ret = -EINVAL;
950 goto end;
951 }
07dfc1d0
MD
952 ret = 0;
953 goto end;
954
955 /* binary */
80c2a69a
FD
956 OP(BYTECODE_OP_MUL):
957 OP(BYTECODE_OP_DIV):
958 OP(BYTECODE_OP_MOD):
959 OP(BYTECODE_OP_PLUS):
960 OP(BYTECODE_OP_MINUS):
961 printk(KERN_WARNING "LTTng: bytecode: unsupported bytecode op %u\n",
962 (unsigned int) *(bytecode_opcode_t *) pc);
07dfc1d0
MD
963 ret = -EINVAL;
964 goto end;
965
80c2a69a
FD
966 OP(BYTECODE_OP_EQ):
967 OP(BYTECODE_OP_NE):
968 OP(BYTECODE_OP_GT):
969 OP(BYTECODE_OP_LT):
970 OP(BYTECODE_OP_GE):
971 OP(BYTECODE_OP_LE):
972 printk(KERN_WARNING "LTTng: bytecode: unsupported non-specialized bytecode op %u\n",
973 (unsigned int) *(bytecode_opcode_t *) pc);
07dfc1d0
MD
974 ret = -EINVAL;
975 goto end;
976
80c2a69a 977 OP(BYTECODE_OP_EQ_STRING):
07dfc1d0
MD
978 {
979 int res;
980
981 res = (stack_strcmp(stack, top, "==") == 0);
d644d1df 982 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 983 estack_ax_v = res;
d644d1df 984 estack_ax_t = REG_S64;
07dfc1d0
MD
985 next_pc += sizeof(struct binary_op);
986 PO;
987 }
80c2a69a 988 OP(BYTECODE_OP_NE_STRING):
07dfc1d0
MD
989 {
990 int res;
991
992 res = (stack_strcmp(stack, top, "!=") != 0);
d644d1df 993 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 994 estack_ax_v = res;
d644d1df 995 estack_ax_t = REG_S64;
07dfc1d0
MD
996 next_pc += sizeof(struct binary_op);
997 PO;
998 }
80c2a69a 999 OP(BYTECODE_OP_GT_STRING):
07dfc1d0
MD
1000 {
1001 int res;
1002
1003 res = (stack_strcmp(stack, top, ">") > 0);
d644d1df 1004 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1005 estack_ax_v = res;
d644d1df 1006 estack_ax_t = REG_S64;
07dfc1d0
MD
1007 next_pc += sizeof(struct binary_op);
1008 PO;
1009 }
80c2a69a 1010 OP(BYTECODE_OP_LT_STRING):
07dfc1d0
MD
1011 {
1012 int res;
1013
1014 res = (stack_strcmp(stack, top, "<") < 0);
d644d1df 1015 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1016 estack_ax_v = res;
d644d1df 1017 estack_ax_t = REG_S64;
07dfc1d0
MD
1018 next_pc += sizeof(struct binary_op);
1019 PO;
1020 }
80c2a69a 1021 OP(BYTECODE_OP_GE_STRING):
07dfc1d0
MD
1022 {
1023 int res;
1024
1025 res = (stack_strcmp(stack, top, ">=") >= 0);
d644d1df 1026 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1027 estack_ax_v = res;
d644d1df 1028 estack_ax_t = REG_S64;
07dfc1d0
MD
1029 next_pc += sizeof(struct binary_op);
1030 PO;
1031 }
80c2a69a 1032 OP(BYTECODE_OP_LE_STRING):
07dfc1d0
MD
1033 {
1034 int res;
1035
1036 res = (stack_strcmp(stack, top, "<=") <= 0);
d644d1df 1037 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1038 estack_ax_v = res;
d644d1df 1039 estack_ax_t = REG_S64;
07dfc1d0
MD
1040 next_pc += sizeof(struct binary_op);
1041 PO;
1042 }
1043
80c2a69a 1044 OP(BYTECODE_OP_EQ_STAR_GLOB_STRING):
02aca193
PP
1045 {
1046 int res;
1047
1048 res = (stack_star_glob_match(stack, top, "==") == 0);
d644d1df 1049 estack_pop(stack, top, ax, bx, ax_t, bx_t);
02aca193 1050 estack_ax_v = res;
d644d1df 1051 estack_ax_t = REG_S64;
02aca193
PP
1052 next_pc += sizeof(struct binary_op);
1053 PO;
1054 }
80c2a69a 1055 OP(BYTECODE_OP_NE_STAR_GLOB_STRING):
02aca193
PP
1056 {
1057 int res;
1058
1059 res = (stack_star_glob_match(stack, top, "!=") != 0);
d644d1df 1060 estack_pop(stack, top, ax, bx, ax_t, bx_t);
02aca193 1061 estack_ax_v = res;
d644d1df 1062 estack_ax_t = REG_S64;
02aca193
PP
1063 next_pc += sizeof(struct binary_op);
1064 PO;
1065 }
1066
80c2a69a 1067 OP(BYTECODE_OP_EQ_S64):
07dfc1d0
MD
1068 {
1069 int res;
1070
1071 res = (estack_bx_v == estack_ax_v);
d644d1df 1072 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1073 estack_ax_v = res;
d644d1df 1074 estack_ax_t = REG_S64;
07dfc1d0
MD
1075 next_pc += sizeof(struct binary_op);
1076 PO;
1077 }
80c2a69a 1078 OP(BYTECODE_OP_NE_S64):
07dfc1d0
MD
1079 {
1080 int res;
1081
1082 res = (estack_bx_v != estack_ax_v);
d644d1df 1083 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1084 estack_ax_v = res;
d644d1df 1085 estack_ax_t = REG_S64;
07dfc1d0
MD
1086 next_pc += sizeof(struct binary_op);
1087 PO;
1088 }
80c2a69a 1089 OP(BYTECODE_OP_GT_S64):
07dfc1d0
MD
1090 {
1091 int res;
1092
1093 res = (estack_bx_v > estack_ax_v);
d644d1df 1094 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1095 estack_ax_v = res;
d644d1df 1096 estack_ax_t = REG_S64;
07dfc1d0
MD
1097 next_pc += sizeof(struct binary_op);
1098 PO;
1099 }
80c2a69a 1100 OP(BYTECODE_OP_LT_S64):
07dfc1d0
MD
1101 {
1102 int res;
1103
1104 res = (estack_bx_v < estack_ax_v);
d644d1df 1105 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1106 estack_ax_v = res;
d644d1df 1107 estack_ax_t = REG_S64;
07dfc1d0
MD
1108 next_pc += sizeof(struct binary_op);
1109 PO;
1110 }
80c2a69a 1111 OP(BYTECODE_OP_GE_S64):
07dfc1d0
MD
1112 {
1113 int res;
1114
1115 res = (estack_bx_v >= estack_ax_v);
d644d1df 1116 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1117 estack_ax_v = res;
d644d1df 1118 estack_ax_t = REG_S64;
07dfc1d0
MD
1119 next_pc += sizeof(struct binary_op);
1120 PO;
1121 }
80c2a69a 1122 OP(BYTECODE_OP_LE_S64):
07dfc1d0
MD
1123 {
1124 int res;
1125
1126 res = (estack_bx_v <= estack_ax_v);
d644d1df 1127 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1128 estack_ax_v = res;
d644d1df 1129 estack_ax_t = REG_S64;
07dfc1d0
MD
1130 next_pc += sizeof(struct binary_op);
1131 PO;
1132 }
1133
80c2a69a
FD
1134 OP(BYTECODE_OP_EQ_DOUBLE):
1135 OP(BYTECODE_OP_NE_DOUBLE):
1136 OP(BYTECODE_OP_GT_DOUBLE):
1137 OP(BYTECODE_OP_LT_DOUBLE):
1138 OP(BYTECODE_OP_GE_DOUBLE):
1139 OP(BYTECODE_OP_LE_DOUBLE):
07dfc1d0
MD
1140 {
1141 BUG_ON(1);
1142 PO;
1143 }
1144
1145 /* Mixed S64-double binary comparators */
80c2a69a
FD
1146 OP(BYTECODE_OP_EQ_DOUBLE_S64):
1147 OP(BYTECODE_OP_NE_DOUBLE_S64):
1148 OP(BYTECODE_OP_GT_DOUBLE_S64):
1149 OP(BYTECODE_OP_LT_DOUBLE_S64):
1150 OP(BYTECODE_OP_GE_DOUBLE_S64):
1151 OP(BYTECODE_OP_LE_DOUBLE_S64):
1152 OP(BYTECODE_OP_EQ_S64_DOUBLE):
1153 OP(BYTECODE_OP_NE_S64_DOUBLE):
1154 OP(BYTECODE_OP_GT_S64_DOUBLE):
1155 OP(BYTECODE_OP_LT_S64_DOUBLE):
1156 OP(BYTECODE_OP_GE_S64_DOUBLE):
1157 OP(BYTECODE_OP_LE_S64_DOUBLE):
07dfc1d0
MD
1158 {
1159 BUG_ON(1);
1160 PO;
1161 }
80c2a69a 1162 OP(BYTECODE_OP_BIT_RSHIFT):
e16c054b
MD
1163 {
1164 int64_t res;
1165
d644d1df
FD
1166 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1167 ret = -EINVAL;
1168 goto end;
1169 }
1170
ea13ec96
MD
1171 /* Catch undefined behavior. */
1172 if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1173 ret = -EINVAL;
1174 goto end;
1175 }
f8d42740 1176 res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
d644d1df 1177 estack_pop(stack, top, ax, bx, ax_t, bx_t);
e16c054b 1178 estack_ax_v = res;
1242217a 1179 estack_ax_t = REG_U64;
e16c054b
MD
1180 next_pc += sizeof(struct binary_op);
1181 PO;
1182 }
80c2a69a 1183 OP(BYTECODE_OP_BIT_LSHIFT):
e16c054b
MD
1184 {
1185 int64_t res;
1186
d644d1df
FD
1187 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1188 ret = -EINVAL;
1189 goto end;
1190 }
1191
ea13ec96
MD
1192 /* Catch undefined behavior. */
1193 if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1194 ret = -EINVAL;
1195 goto end;
1196 }
f8d42740 1197 res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
d644d1df 1198 estack_pop(stack, top, ax, bx, ax_t, bx_t);
e16c054b 1199 estack_ax_v = res;
1242217a 1200 estack_ax_t = REG_U64;
e16c054b
MD
1201 next_pc += sizeof(struct binary_op);
1202 PO;
1203 }
80c2a69a 1204 OP(BYTECODE_OP_BIT_AND):
3834b99f
MD
1205 {
1206 int64_t res;
1207
d644d1df
FD
1208 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1209 ret = -EINVAL;
1210 goto end;
1211 }
1212
f8d42740 1213 res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
d644d1df 1214 estack_pop(stack, top, ax, bx, ax_t, bx_t);
3834b99f 1215 estack_ax_v = res;
1242217a 1216 estack_ax_t = REG_U64;
3834b99f
MD
1217 next_pc += sizeof(struct binary_op);
1218 PO;
1219 }
80c2a69a 1220 OP(BYTECODE_OP_BIT_OR):
3834b99f
MD
1221 {
1222 int64_t res;
1223
d644d1df
FD
1224 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1225 ret = -EINVAL;
1226 goto end;
1227 }
1228
f8d42740 1229 res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
d644d1df 1230 estack_pop(stack, top, ax, bx, ax_t, bx_t);
3834b99f 1231 estack_ax_v = res;
1242217a 1232 estack_ax_t = REG_U64;
3834b99f
MD
1233 next_pc += sizeof(struct binary_op);
1234 PO;
1235 }
80c2a69a 1236 OP(BYTECODE_OP_BIT_XOR):
3834b99f
MD
1237 {
1238 int64_t res;
1239
d644d1df
FD
1240 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1241 ret = -EINVAL;
1242 goto end;
1243 }
1244
f8d42740 1245 res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
d644d1df 1246 estack_pop(stack, top, ax, bx, ax_t, bx_t);
3834b99f 1247 estack_ax_v = res;
1242217a 1248 estack_ax_t = REG_U64;
3834b99f
MD
1249 next_pc += sizeof(struct binary_op);
1250 PO;
1251 }
07dfc1d0
MD
1252
1253 /* unary */
80c2a69a
FD
1254 OP(BYTECODE_OP_UNARY_PLUS):
1255 OP(BYTECODE_OP_UNARY_MINUS):
1256 OP(BYTECODE_OP_UNARY_NOT):
1257 printk(KERN_WARNING "LTTng: bytecode: unsupported non-specialized bytecode op %u\n",
1258 (unsigned int) *(bytecode_opcode_t *) pc);
07dfc1d0
MD
1259 ret = -EINVAL;
1260 goto end;
1261
1262
80c2a69a 1263 OP(BYTECODE_OP_UNARY_BIT_NOT):
e16c054b 1264 {
f8d42740 1265 estack_ax_v = ~(uint64_t) estack_ax_v;
d644d1df 1266 estack_ax_t = REG_S64;
e16c054b
MD
1267 next_pc += sizeof(struct unary_op);
1268 PO;
1269 }
1270
80c2a69a 1271 OP(BYTECODE_OP_UNARY_PLUS_S64):
07dfc1d0
MD
1272 {
1273 next_pc += sizeof(struct unary_op);
1274 PO;
1275 }
80c2a69a 1276 OP(BYTECODE_OP_UNARY_MINUS_S64):
07dfc1d0
MD
1277 {
1278 estack_ax_v = -estack_ax_v;
d644d1df 1279 estack_ax_t = REG_S64;
07dfc1d0
MD
1280 next_pc += sizeof(struct unary_op);
1281 PO;
1282 }
80c2a69a
FD
1283 OP(BYTECODE_OP_UNARY_PLUS_DOUBLE):
1284 OP(BYTECODE_OP_UNARY_MINUS_DOUBLE):
07dfc1d0
MD
1285 {
1286 BUG_ON(1);
1287 PO;
1288 }
80c2a69a 1289 OP(BYTECODE_OP_UNARY_NOT_S64):
07dfc1d0
MD
1290 {
1291 estack_ax_v = !estack_ax_v;
d644d1df 1292 estack_ax_t = REG_S64;
07dfc1d0
MD
1293 next_pc += sizeof(struct unary_op);
1294 PO;
1295 }
80c2a69a 1296 OP(BYTECODE_OP_UNARY_NOT_DOUBLE):
07dfc1d0
MD
1297 {
1298 BUG_ON(1);
1299 PO;
1300 }
1301
1302 /* logical */
80c2a69a 1303 OP(BYTECODE_OP_AND):
07dfc1d0
MD
1304 {
1305 struct logical_op *insn = (struct logical_op *) pc;
1306
1307 /* If AX is 0, skip and evaluate to 0 */
1308 if (unlikely(estack_ax_v == 0)) {
1309 dbg_printk("Jumping to bytecode offset %u\n",
1310 (unsigned int) insn->skip_offset);
1311 next_pc = start_pc + insn->skip_offset;
1312 } else {
1313 /* Pop 1 when jump not taken */
d644d1df 1314 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0
MD
1315 next_pc += sizeof(struct logical_op);
1316 }
1317 PO;
1318 }
80c2a69a 1319 OP(BYTECODE_OP_OR):
07dfc1d0
MD
1320 {
1321 struct logical_op *insn = (struct logical_op *) pc;
1322
1323 /* If AX is nonzero, skip and evaluate to 1 */
1324
1325 if (unlikely(estack_ax_v != 0)) {
1326 estack_ax_v = 1;
1327 dbg_printk("Jumping to bytecode offset %u\n",
1328 (unsigned int) insn->skip_offset);
1329 next_pc = start_pc + insn->skip_offset;
1330 } else {
1331 /* Pop 1 when jump not taken */
d644d1df 1332 estack_pop(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0
MD
1333 next_pc += sizeof(struct logical_op);
1334 }
1335 PO;
1336 }
1337
1338
1339 /* load field ref */
80c2a69a 1340 OP(BYTECODE_OP_LOAD_FIELD_REF_STRING):
07dfc1d0
MD
1341 {
1342 struct load_op *insn = (struct load_op *) pc;
1343 struct field_ref *ref = (struct field_ref *) insn->data;
1344
1345 dbg_printk("load field ref offset %u type string\n",
1346 ref->offset);
d644d1df 1347 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1348 estack_ax(stack, top)->u.s.str =
03cb0cdd 1349 *(const char * const *) &interpreter_stack_data[ref->offset];
07dfc1d0 1350 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
80c2a69a 1351 dbg_printk("Bytecode warning: loading a NULL string.\n");
07dfc1d0
MD
1352 ret = -EINVAL;
1353 goto end;
1354 }
cbc19040 1355 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
02aca193
PP
1356 estack_ax(stack, top)->u.s.literal_type =
1357 ESTACK_STRING_LITERAL_TYPE_NONE;
f127e61e 1358 estack_ax(stack, top)->u.s.user = 0;
d644d1df 1359 estack_ax(stack, top)->type = REG_STRING;
07dfc1d0
MD
1360 dbg_printk("ref load string %s\n", estack_ax(stack, top)->u.s.str);
1361 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1362 PO;
1363 }
1364
80c2a69a 1365 OP(BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE):
07dfc1d0
MD
1366 {
1367 struct load_op *insn = (struct load_op *) pc;
1368 struct field_ref *ref = (struct field_ref *) insn->data;
1369
1370 dbg_printk("load field ref offset %u type sequence\n",
1371 ref->offset);
d644d1df 1372 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1373 estack_ax(stack, top)->u.s.seq_len =
03cb0cdd 1374 *(unsigned long *) &interpreter_stack_data[ref->offset];
07dfc1d0 1375 estack_ax(stack, top)->u.s.str =
03cb0cdd 1376 *(const char **) (&interpreter_stack_data[ref->offset
07dfc1d0
MD
1377 + sizeof(unsigned long)]);
1378 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
80c2a69a 1379 dbg_printk("Bytecode warning: loading a NULL sequence.\n");
07dfc1d0
MD
1380 ret = -EINVAL;
1381 goto end;
1382 }
02aca193
PP
1383 estack_ax(stack, top)->u.s.literal_type =
1384 ESTACK_STRING_LITERAL_TYPE_NONE;
f127e61e 1385 estack_ax(stack, top)->u.s.user = 0;
07dfc1d0
MD
1386 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1387 PO;
1388 }
1389
80c2a69a 1390 OP(BYTECODE_OP_LOAD_FIELD_REF_S64):
07dfc1d0
MD
1391 {
1392 struct load_op *insn = (struct load_op *) pc;
1393 struct field_ref *ref = (struct field_ref *) insn->data;
1394
1395 dbg_printk("load field ref offset %u type s64\n",
1396 ref->offset);
d644d1df 1397 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1398 estack_ax_v =
03cb0cdd 1399 ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
d644d1df 1400 estack_ax_t = REG_S64;
07dfc1d0
MD
1401 dbg_printk("ref load s64 %lld\n",
1402 (long long) estack_ax_v);
1403 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1404 PO;
1405 }
1406
80c2a69a 1407 OP(BYTECODE_OP_LOAD_FIELD_REF_DOUBLE):
07dfc1d0
MD
1408 {
1409 BUG_ON(1);
1410 PO;
1411 }
1412
1413 /* load from immediate operand */
80c2a69a 1414 OP(BYTECODE_OP_LOAD_STRING):
07dfc1d0
MD
1415 {
1416 struct load_op *insn = (struct load_op *) pc;
1417
1418 dbg_printk("load string %s\n", insn->data);
d644d1df 1419 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1420 estack_ax(stack, top)->u.s.str = insn->data;
cbc19040 1421 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
02aca193
PP
1422 estack_ax(stack, top)->u.s.literal_type =
1423 ESTACK_STRING_LITERAL_TYPE_PLAIN;
1424 estack_ax(stack, top)->u.s.user = 0;
1425 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1426 PO;
1427 }
1428
80c2a69a 1429 OP(BYTECODE_OP_LOAD_STAR_GLOB_STRING):
02aca193
PP
1430 {
1431 struct load_op *insn = (struct load_op *) pc;
1432
1433 dbg_printk("load globbing pattern %s\n", insn->data);
d644d1df 1434 estack_push(stack, top, ax, bx, ax_t, bx_t);
02aca193 1435 estack_ax(stack, top)->u.s.str = insn->data;
cbc19040 1436 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
02aca193
PP
1437 estack_ax(stack, top)->u.s.literal_type =
1438 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB;
f127e61e 1439 estack_ax(stack, top)->u.s.user = 0;
07dfc1d0
MD
1440 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1441 PO;
1442 }
1443
80c2a69a 1444 OP(BYTECODE_OP_LOAD_S64):
07dfc1d0
MD
1445 {
1446 struct load_op *insn = (struct load_op *) pc;
1447
d644d1df 1448 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1449 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
d644d1df 1450 estack_ax_t = REG_S64;
07dfc1d0
MD
1451 dbg_printk("load s64 %lld\n",
1452 (long long) estack_ax_v);
1453 next_pc += sizeof(struct load_op)
1454 + sizeof(struct literal_numeric);
1455 PO;
1456 }
1457
80c2a69a 1458 OP(BYTECODE_OP_LOAD_DOUBLE):
07dfc1d0
MD
1459 {
1460 BUG_ON(1);
1461 PO;
1462 }
1463
1464 /* cast */
80c2a69a
FD
1465 OP(BYTECODE_OP_CAST_TO_S64):
1466 printk(KERN_WARNING "LTTng: bytecode: unsupported non-specialized bytecode op %u\n",
1467 (unsigned int) *(bytecode_opcode_t *) pc);
07dfc1d0
MD
1468 ret = -EINVAL;
1469 goto end;
1470
80c2a69a 1471 OP(BYTECODE_OP_CAST_DOUBLE_TO_S64):
07dfc1d0
MD
1472 {
1473 BUG_ON(1);
1474 PO;
1475 }
1476
80c2a69a 1477 OP(BYTECODE_OP_CAST_NOP):
07dfc1d0
MD
1478 {
1479 next_pc += sizeof(struct cast_op);
1480 PO;
1481 }
1482
1483 /* get context ref */
80c2a69a 1484 OP(BYTECODE_OP_GET_CONTEXT_REF_STRING):
07dfc1d0
MD
1485 {
1486 struct load_op *insn = (struct load_op *) pc;
1487 struct field_ref *ref = (struct field_ref *) insn->data;
437d5aa5 1488 struct lttng_kernel_ctx_field *ctx_field;
07dfc1d0
MD
1489 union lttng_ctx_value v;
1490
1491 dbg_printk("get context ref offset %u type string\n",
1492 ref->offset);
1493 ctx_field = &lttng_static_ctx->fields[ref->offset];
79150a49 1494 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
d644d1df 1495 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0
MD
1496 estack_ax(stack, top)->u.s.str = v.str;
1497 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
80c2a69a 1498 dbg_printk("Bytecode warning: loading a NULL string.\n");
07dfc1d0
MD
1499 ret = -EINVAL;
1500 goto end;
1501 }
cbc19040 1502 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
02aca193
PP
1503 estack_ax(stack, top)->u.s.literal_type =
1504 ESTACK_STRING_LITERAL_TYPE_NONE;
f127e61e 1505 estack_ax(stack, top)->u.s.user = 0;
d644d1df 1506 estack_ax(stack, top)->type = REG_STRING;
07dfc1d0
MD
1507 dbg_printk("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
1508 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1509 PO;
1510 }
1511
80c2a69a 1512 OP(BYTECODE_OP_GET_CONTEXT_REF_S64):
07dfc1d0
MD
1513 {
1514 struct load_op *insn = (struct load_op *) pc;
1515 struct field_ref *ref = (struct field_ref *) insn->data;
437d5aa5 1516 struct lttng_kernel_ctx_field *ctx_field;
07dfc1d0
MD
1517 union lttng_ctx_value v;
1518
1519 dbg_printk("get context ref offset %u type s64\n",
1520 ref->offset);
1521 ctx_field = &lttng_static_ctx->fields[ref->offset];
79150a49 1522 ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
d644d1df 1523 estack_push(stack, top, ax, bx, ax_t, bx_t);
07dfc1d0 1524 estack_ax_v = v.s64;
d644d1df 1525 estack_ax_t = REG_S64;
07dfc1d0
MD
1526 dbg_printk("ref get context s64 %lld\n",
1527 (long long) estack_ax_v);
1528 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1529 PO;
1530 }
1531
80c2a69a 1532 OP(BYTECODE_OP_GET_CONTEXT_REF_DOUBLE):
07dfc1d0
MD
1533 {
1534 BUG_ON(1);
1535 PO;
1536 }
1537
f127e61e 1538 /* load userspace field ref */
80c2a69a 1539 OP(BYTECODE_OP_LOAD_FIELD_REF_USER_STRING):
f127e61e
MD
1540 {
1541 struct load_op *insn = (struct load_op *) pc;
1542 struct field_ref *ref = (struct field_ref *) insn->data;
1543
1544 dbg_printk("load field ref offset %u type user string\n",
1545 ref->offset);
d644d1df 1546 estack_push(stack, top, ax, bx, ax_t, bx_t);
5b4ad89f 1547 estack_ax(stack, top)->u.s.user_str =
03cb0cdd 1548 *(const char * const *) &interpreter_stack_data[ref->offset];
acbe9250 1549 if (unlikely(!estack_ax(stack, top)->u.s.user_str)) {
80c2a69a 1550 dbg_printk("Bytecode warning: loading a NULL string.\n");
f127e61e
MD
1551 ret = -EINVAL;
1552 goto end;
1553 }
cbc19040 1554 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
02aca193
PP
1555 estack_ax(stack, top)->u.s.literal_type =
1556 ESTACK_STRING_LITERAL_TYPE_NONE;
f127e61e 1557 estack_ax(stack, top)->u.s.user = 1;
d644d1df 1558 estack_ax(stack, top)->type = REG_STRING;
acbe9250 1559 dbg_load_ref_user_str_printk(estack_ax(stack, top));
f127e61e
MD
1560 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1561 PO;
1562 }
1563
80c2a69a 1564 OP(BYTECODE_OP_LOAD_FIELD_REF_USER_SEQUENCE):
f127e61e
MD
1565 {
1566 struct load_op *insn = (struct load_op *) pc;
1567 struct field_ref *ref = (struct field_ref *) insn->data;
1568
1569 dbg_printk("load field ref offset %u type user sequence\n",
1570 ref->offset);
d644d1df 1571 estack_push(stack, top, ax, bx, ax_t, bx_t);
f127e61e 1572 estack_ax(stack, top)->u.s.seq_len =
03cb0cdd 1573 *(unsigned long *) &interpreter_stack_data[ref->offset];
5b4ad89f 1574 estack_ax(stack, top)->u.s.user_str =
03cb0cdd 1575 *(const char **) (&interpreter_stack_data[ref->offset
f127e61e 1576 + sizeof(unsigned long)]);
acbe9250 1577 if (unlikely(!estack_ax(stack, top)->u.s.user_str)) {
80c2a69a 1578 dbg_printk("Bytecode warning: loading a NULL sequence.\n");
f127e61e
MD
1579 ret = -EINVAL;
1580 goto end;
1581 }
02aca193
PP
1582 estack_ax(stack, top)->u.s.literal_type =
1583 ESTACK_STRING_LITERAL_TYPE_NONE;
f127e61e
MD
1584 estack_ax(stack, top)->u.s.user = 1;
1585 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1586 PO;
1587 }
1588
80c2a69a 1589 OP(BYTECODE_OP_GET_CONTEXT_ROOT):
3834b99f
MD
1590 {
1591 dbg_printk("op get context root\n");
d644d1df 1592 estack_push(stack, top, ax, bx, ax_t, bx_t);
3834b99f
MD
1593 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_CONTEXT;
1594 /* "field" only needed for variants. */
1595 estack_ax(stack, top)->u.ptr.field = NULL;
d644d1df 1596 estack_ax(stack, top)->type = REG_PTR;
3834b99f
MD
1597 next_pc += sizeof(struct load_op);
1598 PO;
1599 }
1600
80c2a69a 1601 OP(BYTECODE_OP_GET_APP_CONTEXT_ROOT):
3834b99f
MD
1602 {
1603 BUG_ON(1);
1604 PO;
1605 }
1606
80c2a69a 1607 OP(BYTECODE_OP_GET_PAYLOAD_ROOT):
3834b99f
MD
1608 {
1609 dbg_printk("op get app payload root\n");
d644d1df 1610 estack_push(stack, top, ax, bx, ax_t, bx_t);
3834b99f 1611 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_PAYLOAD;
03cb0cdd 1612 estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
3834b99f
MD
1613 /* "field" only needed for variants. */
1614 estack_ax(stack, top)->u.ptr.field = NULL;
d644d1df 1615 estack_ax(stack, top)->type = REG_PTR;
3834b99f
MD
1616 next_pc += sizeof(struct load_op);
1617 PO;
1618 }
1619
80c2a69a 1620 OP(BYTECODE_OP_GET_SYMBOL):
3834b99f
MD
1621 {
1622 dbg_printk("op get symbol\n");
1623 switch (estack_ax(stack, top)->u.ptr.type) {
1624 case LOAD_OBJECT:
80c2a69a 1625 printk(KERN_WARNING "LTTng: bytecode: Nested fields not implemented yet.\n");
3834b99f
MD
1626 ret = -EINVAL;
1627 goto end;
1628 case LOAD_ROOT_CONTEXT:
1629 case LOAD_ROOT_APP_CONTEXT:
1630 case LOAD_ROOT_PAYLOAD:
1631 /*
1632 * symbol lookup is performed by
1633 * specialization.
1634 */
1635 ret = -EINVAL;
1636 goto end;
1637 }
1638 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1639 PO;
1640 }
1641
80c2a69a 1642 OP(BYTECODE_OP_GET_SYMBOL_FIELD):
3834b99f
MD
1643 {
1644 /*
1645 * Used for first variant encountered in a
1646 * traversal. Variants are not implemented yet.
1647 */
1648 ret = -EINVAL;
1649 goto end;
1650 }
1651
80c2a69a 1652 OP(BYTECODE_OP_GET_INDEX_U16):
3834b99f
MD
1653 {
1654 struct load_op *insn = (struct load_op *) pc;
1655 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1656
1657 dbg_printk("op get index u16\n");
1658 ret = dynamic_get_index(lttng_probe_ctx, bytecode, index->index, estack_ax(stack, top));
1659 if (ret)
1660 goto end;
1661 estack_ax_v = estack_ax(stack, top)->u.v;
d644d1df 1662 estack_ax_t = estack_ax(stack, top)->type;
3834b99f
MD
1663 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1664 PO;
1665 }
1666
80c2a69a 1667 OP(BYTECODE_OP_GET_INDEX_U64):
3834b99f
MD
1668 {
1669 struct load_op *insn = (struct load_op *) pc;
1670 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1671
1672 dbg_printk("op get index u64\n");
1673 ret = dynamic_get_index(lttng_probe_ctx, bytecode, index->index, estack_ax(stack, top));
1674 if (ret)
1675 goto end;
1676 estack_ax_v = estack_ax(stack, top)->u.v;
d644d1df 1677 estack_ax_t = estack_ax(stack, top)->type;
3834b99f
MD
1678 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1679 PO;
1680 }
1681
80c2a69a 1682 OP(BYTECODE_OP_LOAD_FIELD):
3834b99f
MD
1683 {
1684 dbg_printk("op load field\n");
1685 ret = dynamic_load_field(estack_ax(stack, top));
1686 if (ret)
1687 goto end;
1688 estack_ax_v = estack_ax(stack, top)->u.v;
d644d1df 1689 estack_ax_t = estack_ax(stack, top)->type;
3834b99f
MD
1690 next_pc += sizeof(struct load_op);
1691 PO;
1692 }
1693
80c2a69a 1694 OP(BYTECODE_OP_LOAD_FIELD_S8):
3834b99f
MD
1695 {
1696 dbg_printk("op load field s8\n");
1697
1698 estack_ax_v = *(int8_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1699 estack_ax_t = REG_S64;
3834b99f
MD
1700 next_pc += sizeof(struct load_op);
1701 PO;
1702 }
80c2a69a 1703 OP(BYTECODE_OP_LOAD_FIELD_S16):
3834b99f
MD
1704 {
1705 dbg_printk("op load field s16\n");
1706
1707 estack_ax_v = *(int16_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1708 estack_ax_t = REG_S64;
3834b99f
MD
1709 next_pc += sizeof(struct load_op);
1710 PO;
1711 }
80c2a69a 1712 OP(BYTECODE_OP_LOAD_FIELD_S32):
3834b99f
MD
1713 {
1714 dbg_printk("op load field s32\n");
1715
1716 estack_ax_v = *(int32_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1717 estack_ax_t = REG_S64;
3834b99f
MD
1718 next_pc += sizeof(struct load_op);
1719 PO;
1720 }
80c2a69a 1721 OP(BYTECODE_OP_LOAD_FIELD_S64):
3834b99f
MD
1722 {
1723 dbg_printk("op load field s64\n");
1724
1725 estack_ax_v = *(int64_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1726 estack_ax_t = REG_S64;
3834b99f
MD
1727 next_pc += sizeof(struct load_op);
1728 PO;
1729 }
80c2a69a 1730 OP(BYTECODE_OP_LOAD_FIELD_U8):
3834b99f
MD
1731 {
1732 dbg_printk("op load field u8\n");
1733
1734 estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1735 estack_ax_t = REG_S64;
3834b99f
MD
1736 next_pc += sizeof(struct load_op);
1737 PO;
1738 }
80c2a69a 1739 OP(BYTECODE_OP_LOAD_FIELD_U16):
3834b99f
MD
1740 {
1741 dbg_printk("op load field u16\n");
1742
1743 estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1744 estack_ax_t = REG_S64;
3834b99f
MD
1745 next_pc += sizeof(struct load_op);
1746 PO;
1747 }
80c2a69a 1748 OP(BYTECODE_OP_LOAD_FIELD_U32):
3834b99f
MD
1749 {
1750 dbg_printk("op load field u32\n");
1751
1752 estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1753 estack_ax_t = REG_S64;
3834b99f
MD
1754 next_pc += sizeof(struct load_op);
1755 PO;
1756 }
80c2a69a 1757 OP(BYTECODE_OP_LOAD_FIELD_U64):
3834b99f
MD
1758 {
1759 dbg_printk("op load field u64\n");
1760
1761 estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
d644d1df 1762 estack_ax_t = REG_S64;
3834b99f
MD
1763 next_pc += sizeof(struct load_op);
1764 PO;
1765 }
80c2a69a 1766 OP(BYTECODE_OP_LOAD_FIELD_DOUBLE):
3834b99f
MD
1767 {
1768 ret = -EINVAL;
1769 goto end;
1770 }
1771
80c2a69a 1772 OP(BYTECODE_OP_LOAD_FIELD_STRING):
3834b99f
MD
1773 {
1774 const char *str;
1775
1776 dbg_printk("op load field string\n");
1777 str = (const char *) estack_ax(stack, top)->u.ptr.ptr;
1778 estack_ax(stack, top)->u.s.str = str;
1779 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
80c2a69a 1780 dbg_printk("Bytecode warning: loading a NULL string.\n");
3834b99f
MD
1781 ret = -EINVAL;
1782 goto end;
1783 }
4efe037b 1784 estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
3834b99f
MD
1785 estack_ax(stack, top)->u.s.literal_type =
1786 ESTACK_STRING_LITERAL_TYPE_NONE;
d644d1df 1787 estack_ax(stack, top)->type = REG_STRING;
3834b99f
MD
1788 next_pc += sizeof(struct load_op);
1789 PO;
1790 }
1791
80c2a69a 1792 OP(BYTECODE_OP_LOAD_FIELD_SEQUENCE):
3834b99f
MD
1793 {
1794 const char *ptr;
1795
1796 dbg_printk("op load field string sequence\n");
1797 ptr = estack_ax(stack, top)->u.ptr.ptr;
1798 estack_ax(stack, top)->u.s.seq_len = *(unsigned long *) ptr;
1799 estack_ax(stack, top)->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
1800 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
80c2a69a 1801 dbg_printk("Bytecode warning: loading a NULL sequence.\n");
3834b99f
MD
1802 ret = -EINVAL;
1803 goto end;
1804 }
1805 estack_ax(stack, top)->u.s.literal_type =
1806 ESTACK_STRING_LITERAL_TYPE_NONE;
d644d1df 1807 estack_ax(stack, top)->type = REG_STRING;
3834b99f
MD
1808 next_pc += sizeof(struct load_op);
1809 PO;
1810 }
1811
07dfc1d0
MD
1812 END_OP
1813end:
a93d4e71 1814 /* Return _DISCARD on error. */
07dfc1d0 1815 if (ret)
80c2a69a 1816 return LTTNG_INTERPRETER_DISCARD;
03cb0cdd
FD
1817
1818 if (output) {
1819 return lttng_bytecode_interpret_format_output(
1820 estack_ax(stack, top), output);
1821 }
1822
07dfc1d0
MD
1823 return retval;
1824}
03cb0cdd
FD
1825LTTNG_STACK_FRAME_NON_STANDARD(bytecode_interpret);
1826
80c2a69a 1827uint64_t lttng_bytecode_filter_interpret(void *filter_data,
03cb0cdd
FD
1828 struct lttng_probe_ctx *lttng_probe_ctx,
1829 const char *filter_stack_data)
1830{
1831 return bytecode_interpret(filter_data, lttng_probe_ctx,
1832 filter_stack_data, NULL);
1833}
07dfc1d0 1834
99d223ad
FD
1835uint64_t lttng_bytecode_capture_interpret(void *capture_data,
1836 struct lttng_probe_ctx *lttng_probe_ctx,
1837 const char *capture_stack_data,
1838 struct lttng_interpreter_output *output)
1839{
1840 return bytecode_interpret(capture_data, lttng_probe_ctx,
1841 capture_stack_data, output);
1842}
1843
07dfc1d0
MD
1844#undef START_OP
1845#undef OP
1846#undef PO
1847#undef END_OP
This page took 0.133131 seconds and 4 git commands to generate.