Fix: remove dead code from filter interpreter
[lttng-ust.git] / liblttng-ust / lttng-filter-interpreter.c
CommitLineData
97b58163
MD
1/*
2 * lttng-filter-interpreter.c
3 *
4 * LTTng UST filter interpreter.
5 *
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "lttng-filter.h"
24
25/*
26 * -1: wildcard found.
27 * -2: unknown escape char.
28 * 0: normal char.
29 */
30
31static
32int parse_char(const char **p)
33{
34 switch (**p) {
35 case '\\':
36 (*p)++;
37 switch (**p) {
38 case '\\':
39 case '*':
40 return 0;
41 default:
42 return -2;
43 }
44 case '*':
45 return -1;
46 default:
47 return 0;
48 }
49}
50
51static
9b33aac4 52int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
97b58163 53{
9b33aac4 54 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
97b58163
MD
55 int ret;
56 int diff;
57
58 for (;;) {
59 int escaped_r0 = 0;
60
332335cd
MD
61 if (unlikely(p - estack_bx(stack, top)->u.s.str >= estack_bx(stack, top)->u.s.seq_len || *p == '\0')) {
62 if (q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0') {
5cf8141d 63 return 0;
a0928c1e 64 } else {
5cf8141d
MD
65 if (estack_ax(stack, top)->u.s.literal) {
66 ret = parse_char(&q);
67 if (ret == -1)
68 return 0;
69 }
70 return -1;
a0928c1e 71 }
97b58163 72 }
332335cd 73 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
867df2ba
MD
74 if (estack_bx(stack, top)->u.s.literal) {
75 ret = parse_char(&p);
76 if (ret == -1)
77 return 0;
a0928c1e 78 }
867df2ba 79 return 1;
97b58163 80 }
9b33aac4 81 if (estack_bx(stack, top)->u.s.literal) {
97b58163
MD
82 ret = parse_char(&p);
83 if (ret == -1) {
84 return 0;
85 } else if (ret == -2) {
86 escaped_r0 = 1;
87 }
88 /* else compare both char */
89 }
9b33aac4 90 if (estack_ax(stack, top)->u.s.literal) {
97b58163
MD
91 ret = parse_char(&q);
92 if (ret == -1) {
93 return 0;
94 } else if (ret == -2) {
95 if (!escaped_r0)
96 return -1;
97 } else {
98 if (escaped_r0)
99 return 1;
100 }
101 } else {
102 if (escaped_r0)
103 return 1;
104 }
105 diff = *p - *q;
106 if (diff != 0)
107 break;
108 p++;
109 q++;
110 }
111 return diff;
112}
113
8a92ed2a 114uint64_t lttng_filter_false(void *filter_data,
97b58163
MD
115 const char *filter_stack_data)
116{
117 return 0;
118}
119
120#ifdef INTERPRETER_USE_SWITCH
121
122/*
123 * Fallback for compilers that do not support taking address of labels.
124 */
125
126#define START_OP \
127 start_pc = &bytecode->data[0]; \
128 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
129 pc = next_pc) { \
130 dbg_printf("Executing op %s (%u)\n", \
131 print_op((unsigned int) *(filter_opcode_t *) pc), \
132 (unsigned int) *(filter_opcode_t *) pc); \
133 switch (*(filter_opcode_t *) pc) {
134
135#define OP(name) case name
136
137#define PO break
138
139#define END_OP } \
140 }
141
142#else
143
144/*
145 * Dispatch-table based interpreter.
146 */
147
148#define START_OP \
149 start_pc = &bytecode->data[0]; \
150 pc = next_pc = start_pc; \
151 if (unlikely(pc - start_pc >= bytecode->len)) \
152 goto end; \
153 goto *dispatch[*(filter_opcode_t *) pc];
154
155#define OP(name) \
156LABEL_##name
157
158#define PO \
159 pc = next_pc; \
160 goto *dispatch[*(filter_opcode_t *) pc];
161
162#define END_OP
163
164#endif
165
8a92ed2a
MD
166/*
167 * Return 0 (discard), or raise the 0x1 flag (log event).
168 * Currently, other flags are kept for future extensions and have no
169 * effect.
170 */
171uint64_t lttng_filter_interpret_bytecode(void *filter_data,
97b58163
MD
172 const char *filter_stack_data)
173{
174 struct bytecode_runtime *bytecode = filter_data;
175 void *pc, *next_pc, *start_pc;
176 int ret = -EINVAL;
8b82df15 177 uint64_t retval = 0;
0305960f
MD
178 struct estack _stack;
179 struct estack *stack = &_stack;
9b33aac4
MD
180 register int64_t ax = 0, bx = 0;
181 register int top = FILTER_STACK_EMPTY;
97b58163
MD
182#ifndef INTERPRETER_USE_SWITCH
183 static void *dispatch[NR_FILTER_OPS] = {
184 [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN,
185
186 [ FILTER_OP_RETURN ] = &&LABEL_FILTER_OP_RETURN,
187
188 /* binary */
189 [ FILTER_OP_MUL ] = &&LABEL_FILTER_OP_MUL,
190 [ FILTER_OP_DIV ] = &&LABEL_FILTER_OP_DIV,
191 [ FILTER_OP_MOD ] = &&LABEL_FILTER_OP_MOD,
192 [ FILTER_OP_PLUS ] = &&LABEL_FILTER_OP_PLUS,
193 [ FILTER_OP_MINUS ] = &&LABEL_FILTER_OP_MINUS,
194 [ FILTER_OP_RSHIFT ] = &&LABEL_FILTER_OP_RSHIFT,
195 [ FILTER_OP_LSHIFT ] = &&LABEL_FILTER_OP_LSHIFT,
196 [ FILTER_OP_BIN_AND ] = &&LABEL_FILTER_OP_BIN_AND,
197 [ FILTER_OP_BIN_OR ] = &&LABEL_FILTER_OP_BIN_OR,
198 [ FILTER_OP_BIN_XOR ] = &&LABEL_FILTER_OP_BIN_XOR,
199
200 /* binary comparators */
201 [ FILTER_OP_EQ ] = &&LABEL_FILTER_OP_EQ,
202 [ FILTER_OP_NE ] = &&LABEL_FILTER_OP_NE,
203 [ FILTER_OP_GT ] = &&LABEL_FILTER_OP_GT,
204 [ FILTER_OP_LT ] = &&LABEL_FILTER_OP_LT,
205 [ FILTER_OP_GE ] = &&LABEL_FILTER_OP_GE,
206 [ FILTER_OP_LE ] = &&LABEL_FILTER_OP_LE,
207
208 /* string binary comparator */
209 [ FILTER_OP_EQ_STRING ] = &&LABEL_FILTER_OP_EQ_STRING,
210 [ FILTER_OP_NE_STRING ] = &&LABEL_FILTER_OP_NE_STRING,
211 [ FILTER_OP_GT_STRING ] = &&LABEL_FILTER_OP_GT_STRING,
212 [ FILTER_OP_LT_STRING ] = &&LABEL_FILTER_OP_LT_STRING,
213 [ FILTER_OP_GE_STRING ] = &&LABEL_FILTER_OP_GE_STRING,
214 [ FILTER_OP_LE_STRING ] = &&LABEL_FILTER_OP_LE_STRING,
215
216 /* s64 binary comparator */
217 [ FILTER_OP_EQ_S64 ] = &&LABEL_FILTER_OP_EQ_S64,
218 [ FILTER_OP_NE_S64 ] = &&LABEL_FILTER_OP_NE_S64,
219 [ FILTER_OP_GT_S64 ] = &&LABEL_FILTER_OP_GT_S64,
220 [ FILTER_OP_LT_S64 ] = &&LABEL_FILTER_OP_LT_S64,
221 [ FILTER_OP_GE_S64 ] = &&LABEL_FILTER_OP_GE_S64,
222 [ FILTER_OP_LE_S64 ] = &&LABEL_FILTER_OP_LE_S64,
223
224 /* double binary comparator */
225 [ FILTER_OP_EQ_DOUBLE ] = &&LABEL_FILTER_OP_EQ_DOUBLE,
226 [ FILTER_OP_NE_DOUBLE ] = &&LABEL_FILTER_OP_NE_DOUBLE,
227 [ FILTER_OP_GT_DOUBLE ] = &&LABEL_FILTER_OP_GT_DOUBLE,
228 [ FILTER_OP_LT_DOUBLE ] = &&LABEL_FILTER_OP_LT_DOUBLE,
229 [ FILTER_OP_GE_DOUBLE ] = &&LABEL_FILTER_OP_GE_DOUBLE,
230 [ FILTER_OP_LE_DOUBLE ] = &&LABEL_FILTER_OP_LE_DOUBLE,
231
dbea82ec
MD
232 /* Mixed S64-double binary comparators */
233 [ FILTER_OP_EQ_DOUBLE_S64 ] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64,
234 [ FILTER_OP_NE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_NE_DOUBLE_S64,
235 [ FILTER_OP_GT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GT_DOUBLE_S64,
236 [ FILTER_OP_LT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LT_DOUBLE_S64,
237 [ FILTER_OP_GE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GE_DOUBLE_S64,
238 [ FILTER_OP_LE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LE_DOUBLE_S64,
239
240 [ FILTER_OP_EQ_S64_DOUBLE ] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE,
241 [ FILTER_OP_NE_S64_DOUBLE ] = &&LABEL_FILTER_OP_NE_S64_DOUBLE,
242 [ FILTER_OP_GT_S64_DOUBLE ] = &&LABEL_FILTER_OP_GT_S64_DOUBLE,
243 [ FILTER_OP_LT_S64_DOUBLE ] = &&LABEL_FILTER_OP_LT_S64_DOUBLE,
244 [ FILTER_OP_GE_S64_DOUBLE ] = &&LABEL_FILTER_OP_GE_S64_DOUBLE,
245 [ FILTER_OP_LE_S64_DOUBLE ] = &&LABEL_FILTER_OP_LE_S64_DOUBLE,
246
97b58163
MD
247 /* unary */
248 [ FILTER_OP_UNARY_PLUS ] = &&LABEL_FILTER_OP_UNARY_PLUS,
249 [ FILTER_OP_UNARY_MINUS ] = &&LABEL_FILTER_OP_UNARY_MINUS,
250 [ FILTER_OP_UNARY_NOT ] = &&LABEL_FILTER_OP_UNARY_NOT,
251 [ FILTER_OP_UNARY_PLUS_S64 ] = &&LABEL_FILTER_OP_UNARY_PLUS_S64,
252 [ FILTER_OP_UNARY_MINUS_S64 ] = &&LABEL_FILTER_OP_UNARY_MINUS_S64,
253 [ FILTER_OP_UNARY_NOT_S64 ] = &&LABEL_FILTER_OP_UNARY_NOT_S64,
254 [ FILTER_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE,
255 [ FILTER_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE,
256 [ FILTER_OP_UNARY_NOT_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE,
257
258 /* logical */
259 [ FILTER_OP_AND ] = &&LABEL_FILTER_OP_AND,
260 [ FILTER_OP_OR ] = &&LABEL_FILTER_OP_OR,
261
77aa5901 262 /* load field ref */
97b58163
MD
263 [ FILTER_OP_LOAD_FIELD_REF ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF,
264 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING,
265 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE,
266 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64,
267 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE,
268
77aa5901 269 /* load from immediate operand */
97b58163
MD
270 [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING,
271 [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64,
272 [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE,
273
274 /* cast */
275 [ FILTER_OP_CAST_TO_S64 ] = &&LABEL_FILTER_OP_CAST_TO_S64,
276 [ FILTER_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64,
277 [ FILTER_OP_CAST_NOP ] = &&LABEL_FILTER_OP_CAST_NOP,
77aa5901
MD
278
279 /* get context ref */
280 [ FILTER_OP_GET_CONTEXT_REF ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF,
281 [ FILTER_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING,
282 [ FILTER_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64,
283 [ FILTER_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE,
97b58163
MD
284 };
285#endif /* #ifndef INTERPRETER_USE_SWITCH */
286
287 START_OP
288
289 OP(FILTER_OP_UNKNOWN):
290 OP(FILTER_OP_LOAD_FIELD_REF):
77aa5901 291 OP(FILTER_OP_GET_CONTEXT_REF):
97b58163
MD
292#ifdef INTERPRETER_USE_SWITCH
293 default:
294#endif /* INTERPRETER_USE_SWITCH */
295 ERR("unknown bytecode op %u\n",
296 (unsigned int) *(filter_opcode_t *) pc);
297 ret = -EINVAL;
298 goto end;
299
300 OP(FILTER_OP_RETURN):
8a92ed2a 301 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
9b33aac4 302 retval = !!estack_ax_v;
97b58163
MD
303 ret = 0;
304 goto end;
305
306 /* binary */
307 OP(FILTER_OP_MUL):
308 OP(FILTER_OP_DIV):
309 OP(FILTER_OP_MOD):
310 OP(FILTER_OP_PLUS):
311 OP(FILTER_OP_MINUS):
312 OP(FILTER_OP_RSHIFT):
313 OP(FILTER_OP_LSHIFT):
314 OP(FILTER_OP_BIN_AND):
315 OP(FILTER_OP_BIN_OR):
316 OP(FILTER_OP_BIN_XOR):
317 ERR("unsupported bytecode op %u\n",
318 (unsigned int) *(filter_opcode_t *) pc);
319 ret = -EINVAL;
320 goto end;
321
322 OP(FILTER_OP_EQ):
323 OP(FILTER_OP_NE):
324 OP(FILTER_OP_GT):
325 OP(FILTER_OP_LT):
326 OP(FILTER_OP_GE):
327 OP(FILTER_OP_LE):
328 ERR("unsupported non-specialized bytecode op %u\n",
329 (unsigned int) *(filter_opcode_t *) pc);
330 ret = -EINVAL;
331 goto end;
332
333 OP(FILTER_OP_EQ_STRING):
334 {
0305960f
MD
335 int res;
336
9b33aac4
MD
337 res = (stack_strcmp(stack, top, "==") == 0);
338 estack_pop(stack, top, ax, bx);
339 estack_ax_v = res;
97b58163
MD
340 next_pc += sizeof(struct binary_op);
341 PO;
342 }
343 OP(FILTER_OP_NE_STRING):
344 {
0305960f
MD
345 int res;
346
9b33aac4
MD
347 res = (stack_strcmp(stack, top, "!=") != 0);
348 estack_pop(stack, top, ax, bx);
349 estack_ax_v = res;
97b58163
MD
350 next_pc += sizeof(struct binary_op);
351 PO;
352 }
353 OP(FILTER_OP_GT_STRING):
354 {
0305960f
MD
355 int res;
356
9b33aac4
MD
357 res = (stack_strcmp(stack, top, ">") > 0);
358 estack_pop(stack, top, ax, bx);
359 estack_ax_v = res;
97b58163
MD
360 next_pc += sizeof(struct binary_op);
361 PO;
362 }
363 OP(FILTER_OP_LT_STRING):
364 {
0305960f
MD
365 int res;
366
9b33aac4
MD
367 res = (stack_strcmp(stack, top, "<") < 0);
368 estack_pop(stack, top, ax, bx);
369 estack_ax_v = res;
97b58163
MD
370 next_pc += sizeof(struct binary_op);
371 PO;
372 }
373 OP(FILTER_OP_GE_STRING):
374 {
0305960f
MD
375 int res;
376
9b33aac4
MD
377 res = (stack_strcmp(stack, top, ">=") >= 0);
378 estack_pop(stack, top, ax, bx);
379 estack_ax_v = res;
97b58163
MD
380 next_pc += sizeof(struct binary_op);
381 PO;
382 }
383 OP(FILTER_OP_LE_STRING):
384 {
0305960f
MD
385 int res;
386
9b33aac4
MD
387 res = (stack_strcmp(stack, top, "<=") <= 0);
388 estack_pop(stack, top, ax, bx);
389 estack_ax_v = res;
97b58163
MD
390 next_pc += sizeof(struct binary_op);
391 PO;
392 }
393
394 OP(FILTER_OP_EQ_S64):
395 {
0305960f
MD
396 int res;
397
9b33aac4
MD
398 res = (estack_bx_v == estack_ax_v);
399 estack_pop(stack, top, ax, bx);
400 estack_ax_v = res;
97b58163
MD
401 next_pc += sizeof(struct binary_op);
402 PO;
403 }
404 OP(FILTER_OP_NE_S64):
405 {
0305960f
MD
406 int res;
407
9b33aac4
MD
408 res = (estack_bx_v != estack_ax_v);
409 estack_pop(stack, top, ax, bx);
410 estack_ax_v = res;
97b58163
MD
411 next_pc += sizeof(struct binary_op);
412 PO;
413 }
414 OP(FILTER_OP_GT_S64):
415 {
0305960f
MD
416 int res;
417
9b33aac4
MD
418 res = (estack_bx_v > estack_ax_v);
419 estack_pop(stack, top, ax, bx);
420 estack_ax_v = res;
97b58163
MD
421 next_pc += sizeof(struct binary_op);
422 PO;
423 }
424 OP(FILTER_OP_LT_S64):
425 {
0305960f
MD
426 int res;
427
9b33aac4
MD
428 res = (estack_bx_v < estack_ax_v);
429 estack_pop(stack, top, ax, bx);
430 estack_ax_v = res;
97b58163
MD
431 next_pc += sizeof(struct binary_op);
432 PO;
433 }
434 OP(FILTER_OP_GE_S64):
435 {
0305960f
MD
436 int res;
437
9b33aac4
MD
438 res = (estack_bx_v >= estack_ax_v);
439 estack_pop(stack, top, ax, bx);
440 estack_ax_v = res;
97b58163
MD
441 next_pc += sizeof(struct binary_op);
442 PO;
443 }
444 OP(FILTER_OP_LE_S64):
445 {
0305960f
MD
446 int res;
447
9b33aac4
MD
448 res = (estack_bx_v <= estack_ax_v);
449 estack_pop(stack, top, ax, bx);
450 estack_ax_v = res;
97b58163
MD
451 next_pc += sizeof(struct binary_op);
452 PO;
453 }
454
455 OP(FILTER_OP_EQ_DOUBLE):
456 {
0305960f
MD
457 int res;
458
9b33aac4
MD
459 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
460 estack_pop(stack, top, ax, bx);
461 estack_ax_v = res;
97b58163
MD
462 next_pc += sizeof(struct binary_op);
463 PO;
464 }
465 OP(FILTER_OP_NE_DOUBLE):
466 {
0305960f
MD
467 int res;
468
9b33aac4
MD
469 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
470 estack_pop(stack, top, ax, bx);
471 estack_ax_v = res;
97b58163
MD
472 next_pc += sizeof(struct binary_op);
473 PO;
474 }
475 OP(FILTER_OP_GT_DOUBLE):
476 {
0305960f
MD
477 int res;
478
9b33aac4
MD
479 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
480 estack_pop(stack, top, ax, bx);
481 estack_ax_v = res;
97b58163
MD
482 next_pc += sizeof(struct binary_op);
483 PO;
484 }
485 OP(FILTER_OP_LT_DOUBLE):
486 {
0305960f
MD
487 int res;
488
9b33aac4
MD
489 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
490 estack_pop(stack, top, ax, bx);
491 estack_ax_v = res;
97b58163
MD
492 next_pc += sizeof(struct binary_op);
493 PO;
494 }
495 OP(FILTER_OP_GE_DOUBLE):
496 {
0305960f
MD
497 int res;
498
9b33aac4
MD
499 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
500 estack_pop(stack, top, ax, bx);
501 estack_ax_v = res;
97b58163
MD
502 next_pc += sizeof(struct binary_op);
503 PO;
504 }
505 OP(FILTER_OP_LE_DOUBLE):
506 {
0305960f
MD
507 int res;
508
9b33aac4
MD
509 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
510 estack_pop(stack, top, ax, bx);
511 estack_ax_v = res;
dbea82ec
MD
512 next_pc += sizeof(struct binary_op);
513 PO;
514 }
515
516 /* Mixed S64-double binary comparators */
517 OP(FILTER_OP_EQ_DOUBLE_S64):
518 {
519 int res;
520
9b33aac4
MD
521 res = (estack_bx(stack, top)->u.d == estack_ax_v);
522 estack_pop(stack, top, ax, bx);
523 estack_ax_v = res;
dbea82ec
MD
524 next_pc += sizeof(struct binary_op);
525 PO;
526 }
527 OP(FILTER_OP_NE_DOUBLE_S64):
528 {
529 int res;
530
9b33aac4
MD
531 res = (estack_bx(stack, top)->u.d != estack_ax_v);
532 estack_pop(stack, top, ax, bx);
533 estack_ax_v = res;
dbea82ec
MD
534 next_pc += sizeof(struct binary_op);
535 PO;
536 }
537 OP(FILTER_OP_GT_DOUBLE_S64):
538 {
539 int res;
540
9b33aac4
MD
541 res = (estack_bx(stack, top)->u.d > estack_ax_v);
542 estack_pop(stack, top, ax, bx);
543 estack_ax_v = res;
dbea82ec
MD
544 next_pc += sizeof(struct binary_op);
545 PO;
546 }
547 OP(FILTER_OP_LT_DOUBLE_S64):
548 {
549 int res;
550
9b33aac4
MD
551 res = (estack_bx(stack, top)->u.d < estack_ax_v);
552 estack_pop(stack, top, ax, bx);
553 estack_ax_v = res;
dbea82ec
MD
554 next_pc += sizeof(struct binary_op);
555 PO;
556 }
557 OP(FILTER_OP_GE_DOUBLE_S64):
558 {
559 int res;
560
9b33aac4
MD
561 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
562 estack_pop(stack, top, ax, bx);
563 estack_ax_v = res;
dbea82ec
MD
564 next_pc += sizeof(struct binary_op);
565 PO;
566 }
567 OP(FILTER_OP_LE_DOUBLE_S64):
568 {
569 int res;
570
9b33aac4
MD
571 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
572 estack_pop(stack, top, ax, bx);
573 estack_ax_v = res;
dbea82ec
MD
574 next_pc += sizeof(struct binary_op);
575 PO;
576 }
577
578 OP(FILTER_OP_EQ_S64_DOUBLE):
579 {
580 int res;
581
9b33aac4
MD
582 res = (estack_bx_v == estack_ax(stack, top)->u.d);
583 estack_pop(stack, top, ax, bx);
584 estack_ax_v = res;
dbea82ec
MD
585 next_pc += sizeof(struct binary_op);
586 PO;
587 }
588 OP(FILTER_OP_NE_S64_DOUBLE):
589 {
590 int res;
591
9b33aac4
MD
592 res = (estack_bx_v != estack_ax(stack, top)->u.d);
593 estack_pop(stack, top, ax, bx);
594 estack_ax_v = res;
dbea82ec
MD
595 next_pc += sizeof(struct binary_op);
596 PO;
597 }
598 OP(FILTER_OP_GT_S64_DOUBLE):
599 {
600 int res;
601
9b33aac4
MD
602 res = (estack_bx_v > estack_ax(stack, top)->u.d);
603 estack_pop(stack, top, ax, bx);
604 estack_ax_v = res;
dbea82ec
MD
605 next_pc += sizeof(struct binary_op);
606 PO;
607 }
608 OP(FILTER_OP_LT_S64_DOUBLE):
609 {
610 int res;
611
9b33aac4
MD
612 res = (estack_bx_v < estack_ax(stack, top)->u.d);
613 estack_pop(stack, top, ax, bx);
614 estack_ax_v = res;
dbea82ec
MD
615 next_pc += sizeof(struct binary_op);
616 PO;
617 }
618 OP(FILTER_OP_GE_S64_DOUBLE):
619 {
620 int res;
621
9b33aac4
MD
622 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
623 estack_pop(stack, top, ax, bx);
624 estack_ax_v = res;
dbea82ec
MD
625 next_pc += sizeof(struct binary_op);
626 PO;
627 }
628 OP(FILTER_OP_LE_S64_DOUBLE):
629 {
630 int res;
631
9b33aac4
MD
632 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
633 estack_pop(stack, top, ax, bx);
634 estack_ax_v = res;
97b58163
MD
635 next_pc += sizeof(struct binary_op);
636 PO;
637 }
638
639 /* unary */
640 OP(FILTER_OP_UNARY_PLUS):
641 OP(FILTER_OP_UNARY_MINUS):
642 OP(FILTER_OP_UNARY_NOT):
643 ERR("unsupported non-specialized bytecode op %u\n",
644 (unsigned int) *(filter_opcode_t *) pc);
645 ret = -EINVAL;
646 goto end;
647
648
649 OP(FILTER_OP_UNARY_PLUS_S64):
650 OP(FILTER_OP_UNARY_PLUS_DOUBLE):
651 {
652 next_pc += sizeof(struct unary_op);
653 PO;
654 }
655 OP(FILTER_OP_UNARY_MINUS_S64):
656 {
9b33aac4 657 estack_ax_v = -estack_ax_v;
97b58163
MD
658 next_pc += sizeof(struct unary_op);
659 PO;
660 }
661 OP(FILTER_OP_UNARY_MINUS_DOUBLE):
662 {
9b33aac4 663 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
97b58163
MD
664 next_pc += sizeof(struct unary_op);
665 PO;
666 }
667 OP(FILTER_OP_UNARY_NOT_S64):
668 {
9b33aac4 669 estack_ax_v = !estack_ax_v;
97b58163
MD
670 next_pc += sizeof(struct unary_op);
671 PO;
672 }
673 OP(FILTER_OP_UNARY_NOT_DOUBLE):
674 {
9b33aac4 675 estack_ax(stack, top)->u.d = !estack_ax(stack, top)->u.d;
97b58163
MD
676 next_pc += sizeof(struct unary_op);
677 PO;
678 }
679
680 /* logical */
681 OP(FILTER_OP_AND):
682 {
683 struct logical_op *insn = (struct logical_op *) pc;
684
0305960f 685 /* If AX is 0, skip and evaluate to 0 */
9b33aac4 686 if (unlikely(estack_ax_v == 0)) {
97b58163
MD
687 dbg_printf("Jumping to bytecode offset %u\n",
688 (unsigned int) insn->skip_offset);
689 next_pc = start_pc + insn->skip_offset;
690 } else {
71c1ceeb 691 /* Pop 1 when jump not taken */
9b33aac4 692 estack_pop(stack, top, ax, bx);
97b58163
MD
693 next_pc += sizeof(struct logical_op);
694 }
695 PO;
696 }
697 OP(FILTER_OP_OR):
698 {
699 struct logical_op *insn = (struct logical_op *) pc;
700
0305960f 701 /* If AX is nonzero, skip and evaluate to 1 */
97b58163 702
9b33aac4
MD
703 if (unlikely(estack_ax_v != 0)) {
704 estack_ax_v = 1;
97b58163
MD
705 dbg_printf("Jumping to bytecode offset %u\n",
706 (unsigned int) insn->skip_offset);
707 next_pc = start_pc + insn->skip_offset;
708 } else {
71c1ceeb 709 /* Pop 1 when jump not taken */
9b33aac4 710 estack_pop(stack, top, ax, bx);
97b58163
MD
711 next_pc += sizeof(struct logical_op);
712 }
713 PO;
714 }
715
716
77aa5901 717 /* load field ref */
97b58163
MD
718 OP(FILTER_OP_LOAD_FIELD_REF_STRING):
719 {
720 struct load_op *insn = (struct load_op *) pc;
721 struct field_ref *ref = (struct field_ref *) insn->data;
722
723 dbg_printf("load field ref offset %u type string\n",
724 ref->offset);
9b33aac4
MD
725 estack_push(stack, top, ax, bx);
726 estack_ax(stack, top)->u.s.str =
97b58163 727 *(const char * const *) &filter_stack_data[ref->offset];
9b33aac4 728 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
729 dbg_printf("Filter warning: loading a NULL string.\n");
730 ret = -EINVAL;
731 goto end;
732 }
9b33aac4
MD
733 estack_ax(stack, top)->u.s.seq_len = UINT_MAX;
734 estack_ax(stack, top)->u.s.literal = 0;
735 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
97b58163
MD
736 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
737 PO;
738 }
739
740 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE):
741 {
742 struct load_op *insn = (struct load_op *) pc;
743 struct field_ref *ref = (struct field_ref *) insn->data;
744
745 dbg_printf("load field ref offset %u type sequence\n",
746 ref->offset);
9b33aac4
MD
747 estack_push(stack, top, ax, bx);
748 estack_ax(stack, top)->u.s.seq_len =
97b58163 749 *(unsigned long *) &filter_stack_data[ref->offset];
9b33aac4 750 estack_ax(stack, top)->u.s.str =
97b58163
MD
751 *(const char **) (&filter_stack_data[ref->offset
752 + sizeof(unsigned long)]);
9b33aac4 753 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
754 dbg_printf("Filter warning: loading a NULL sequence.\n");
755 ret = -EINVAL;
756 goto end;
757 }
9b33aac4 758 estack_ax(stack, top)->u.s.literal = 0;
97b58163
MD
759 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
760 PO;
761 }
762
763 OP(FILTER_OP_LOAD_FIELD_REF_S64):
764 {
765 struct load_op *insn = (struct load_op *) pc;
766 struct field_ref *ref = (struct field_ref *) insn->data;
767
768 dbg_printf("load field ref offset %u type s64\n",
769 ref->offset);
9b33aac4
MD
770 estack_push(stack, top, ax, bx);
771 estack_ax_v =
772 ((struct literal_numeric *) &filter_stack_data[ref->offset])->v;
773 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
774 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
775 PO;
776 }
777
778 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE):
779 {
780 struct load_op *insn = (struct load_op *) pc;
781 struct field_ref *ref = (struct field_ref *) insn->data;
782
783 dbg_printf("load field ref offset %u type double\n",
784 ref->offset);
9b33aac4
MD
785 estack_push(stack, top, ax, bx);
786 memcpy(&estack_ax(stack, top)->u.d, &filter_stack_data[ref->offset],
97b58163 787 sizeof(struct literal_double));
9b33aac4 788 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
789 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
790 PO;
791 }
792
77aa5901 793 /* load from immediate operand */
97b58163
MD
794 OP(FILTER_OP_LOAD_STRING):
795 {
796 struct load_op *insn = (struct load_op *) pc;
797
798 dbg_printf("load string %s\n", insn->data);
9b33aac4
MD
799 estack_push(stack, top, ax, bx);
800 estack_ax(stack, top)->u.s.str = insn->data;
801 estack_ax(stack, top)->u.s.seq_len = UINT_MAX;
802 estack_ax(stack, top)->u.s.literal = 1;
97b58163
MD
803 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
804 PO;
805 }
806
807 OP(FILTER_OP_LOAD_S64):
808 {
809 struct load_op *insn = (struct load_op *) pc;
810
9b33aac4
MD
811 estack_push(stack, top, ax, bx);
812 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
813 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
814 next_pc += sizeof(struct load_op)
815 + sizeof(struct literal_numeric);
816 PO;
817 }
818
819 OP(FILTER_OP_LOAD_DOUBLE):
820 {
821 struct load_op *insn = (struct load_op *) pc;
822
9b33aac4
MD
823 estack_push(stack, top, ax, bx);
824 memcpy(&estack_ax(stack, top)->u.d, insn->data,
97b58163 825 sizeof(struct literal_double));
9b33aac4 826 dbg_printf("load s64 %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
827 next_pc += sizeof(struct load_op)
828 + sizeof(struct literal_double);
829 PO;
830 }
831
832 /* cast */
833 OP(FILTER_OP_CAST_TO_S64):
834 ERR("unsupported non-specialized bytecode op %u\n",
835 (unsigned int) *(filter_opcode_t *) pc);
836 ret = -EINVAL;
837 goto end;
838
839 OP(FILTER_OP_CAST_DOUBLE_TO_S64):
840 {
9b33aac4 841 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
97b58163
MD
842 next_pc += sizeof(struct cast_op);
843 PO;
844 }
845
846 OP(FILTER_OP_CAST_NOP):
847 {
848 next_pc += sizeof(struct cast_op);
849 PO;
850 }
851
77aa5901
MD
852 /* get context ref */
853 OP(FILTER_OP_GET_CONTEXT_REF_STRING):
854 {
855 struct load_op *insn = (struct load_op *) pc;
856 struct field_ref *ref = (struct field_ref *) insn->data;
857 struct lttng_ctx_field *ctx_field;
858 union lttng_ctx_value v;
859
860 dbg_printf("get context ref offset %u type string\n",
861 ref->offset);
a0a3bef9 862 ctx_field = &lttng_static_ctx->fields[ref->offset];
77aa5901
MD
863 ctx_field->get_value(ctx_field, &v);
864 estack_push(stack, top, ax, bx);
865 estack_ax(stack, top)->u.s.str = v.str;
866 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
867 dbg_printf("Filter warning: loading a NULL string.\n");
868 ret = -EINVAL;
869 goto end;
870 }
871 estack_ax(stack, top)->u.s.seq_len = UINT_MAX;
872 estack_ax(stack, top)->u.s.literal = 0;
873 dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
874 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
875 PO;
876 }
877
878 OP(FILTER_OP_GET_CONTEXT_REF_S64):
879 {
880 struct load_op *insn = (struct load_op *) pc;
881 struct field_ref *ref = (struct field_ref *) insn->data;
882 struct lttng_ctx_field *ctx_field;
883 union lttng_ctx_value v;
884
885 dbg_printf("get context ref offset %u type s64\n",
886 ref->offset);
a0a3bef9 887 ctx_field = &lttng_static_ctx->fields[ref->offset];
77aa5901
MD
888 ctx_field->get_value(ctx_field, &v);
889 estack_push(stack, top, ax, bx);
890 estack_ax_v = v.s64;
891 dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v);
892 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
893 PO;
894 }
895
896 OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE):
897 {
898 struct load_op *insn = (struct load_op *) pc;
899 struct field_ref *ref = (struct field_ref *) insn->data;
900 struct lttng_ctx_field *ctx_field;
901 union lttng_ctx_value v;
902
903 dbg_printf("get context ref offset %u type double\n",
904 ref->offset);
a0a3bef9 905 ctx_field = &lttng_static_ctx->fields[ref->offset];
77aa5901
MD
906 ctx_field->get_value(ctx_field, &v);
907 estack_push(stack, top, ax, bx);
908 memcpy(&estack_ax(stack, top)->u.d, &v.d, sizeof(struct literal_double));
909 dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d);
910 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
911 PO;
912 }
913
97b58163
MD
914 END_OP
915end:
916 /* return 0 (discard) on error */
917 if (ret)
918 return 0;
919 return retval;
920}
921
922#undef START_OP
923#undef OP
924#undef PO
925#undef END_OP
This page took 0.065069 seconds and 4 git commands to generate.