Run clang-format on the whole tree
[lttng-tools.git] / src / common / filter / filter-visitor-generate-bytecode.cpp
CommitLineData
953192ba
MD
1/*
2 * filter-visitor-generate-bytecode.c
3 *
4 * LTTng filter bytecode generation
5 *
ab5be9fa 6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
953192ba 7 *
ab5be9fa 8 * SPDX-License-Identifier: LGPL-2.1-only
953192ba 9 *
953192ba
MD
10 */
11
c9e313bc
SM
12#include "common/align.hpp"
13#include "common/bytecode/bytecode.hpp"
14#include "common/compat/string.hpp"
15#include "common/macros.hpp"
16#include "common/string-utils/string-utils.hpp"
17#include "filter-ast.hpp"
18#include "filter-ir.hpp"
a187da1a 19
28ab034a
JG
20#include <common/align.hpp>
21#include <common/compat/errno.hpp>
22#include <common/compat/string.hpp>
23
24#include <stdlib.h>
25#include <string.h>
26
27static int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, struct ir_op *node);
953192ba 28
28ab034a
JG
29static int
30bytecode_patch(struct lttng_bytecode_alloc **fb, const void *data, uint16_t offset, uint32_t len)
953192ba
MD
31{
32 if (offset >= (*fb)->b.len) {
33 return -EINVAL;
34 }
35 memcpy(&(*fb)->b.data[offset], data, len);
36 return 0;
37}
38
28ab034a 39static int visit_node_root(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
40{
41 int ret;
42 struct return_op insn;
43
44 /* Visit child */
45 ret = recursive_visit_gen_bytecode(ctx, node->u.root.child);
46 if (ret)
47 return ret;
48
49 /* Generate end of bytecode instruction */
2b00d462 50 insn.op = BYTECODE_OP_RETURN;
953192ba
MD
51 return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
52}
53
016dbbb4
MD
54/*
55 * 1: match
56 * 0: no match
57 * < 0: error
58 */
28ab034a
JG
59static int load_expression_legacy_match(const struct ir_load_expression *exp,
60 enum bytecode_op *op_type,
61 char **symbol)
016dbbb4
MD
62{
63 const struct ir_load_expression_op *op;
64 bool need_dot = false;
65
66 op = exp->child;
67 switch (op->type) {
68 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
2b00d462 69 *op_type = BYTECODE_OP_GET_CONTEXT_REF;
4ff75060 70 if (strutils_append_str(symbol, "$ctx.")) {
016dbbb4
MD
71 return -ENOMEM;
72 }
73 need_dot = false;
74 break;
75 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
2b00d462 76 *op_type = BYTECODE_OP_GET_CONTEXT_REF;
4ff75060 77 if (strutils_append_str(symbol, "$app.")) {
016dbbb4
MD
78 return -ENOMEM;
79 }
80 need_dot = false;
81 break;
82 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
2b00d462 83 *op_type = BYTECODE_OP_LOAD_FIELD_REF;
016dbbb4
MD
84 need_dot = false;
85 break;
86
87 case IR_LOAD_EXPRESSION_GET_SYMBOL:
88 case IR_LOAD_EXPRESSION_GET_INDEX:
89 case IR_LOAD_EXPRESSION_LOAD_FIELD:
90 default:
28ab034a 91 return 0; /* no match */
016dbbb4
MD
92 }
93
94 for (;;) {
95 op = op->next;
96 if (!op) {
28ab034a 97 return 0; /* no match */
016dbbb4
MD
98 }
99 switch (op->type) {
100 case IR_LOAD_EXPRESSION_LOAD_FIELD:
101 goto end;
102 case IR_LOAD_EXPRESSION_GET_SYMBOL:
4ff75060 103 if (need_dot && strutils_append_str(symbol, ".")) {
016dbbb4
MD
104 return -ENOMEM;
105 }
4ff75060 106 if (strutils_append_str(symbol, op->u.symbol)) {
016dbbb4
MD
107 return -ENOMEM;
108 }
109 break;
110 default:
28ab034a 111 return 0; /* no match */
016dbbb4
MD
112 }
113 need_dot = true;
114 }
115end:
28ab034a 116 return 1; /* Legacy match */
016dbbb4
MD
117}
118
119/*
120 * 1: legacy match
121 * 0: no legacy match
122 * < 0: error
123 */
28ab034a
JG
124static int visit_node_load_expression_legacy(struct filter_parser_ctx *ctx,
125 const struct ir_load_expression *exp,
126 const struct ir_load_expression_op *op)
016dbbb4
MD
127{
128 struct load_op *insn = NULL;
28ab034a 129 uint32_t insn_len = sizeof(struct load_op) + sizeof(struct field_ref);
016dbbb4
MD
130 struct field_ref ref_offset;
131 uint32_t reloc_offset_u32;
132 uint16_t reloc_offset;
2b00d462 133 enum bytecode_op op_type;
016dbbb4
MD
134 char *symbol = NULL;
135 int ret;
136
137 ret = load_expression_legacy_match(exp, &op_type, &symbol);
138 if (ret <= 0) {
139 goto end;
140 }
348ddc5c 141 insn = (load_op *) calloc(insn_len, 1);
016dbbb4
MD
142 if (!insn) {
143 ret = -ENOMEM;
144 goto end;
145 }
146 insn->op = op_type;
147 ref_offset.offset = (uint16_t) -1U;
148 memcpy(insn->data, &ref_offset, sizeof(ref_offset));
149 /* reloc_offset points to struct load_op */
150 reloc_offset_u32 = bytecode_get_len(&ctx->bytecode->b);
151 if (reloc_offset_u32 > LTTNG_FILTER_MAX_LEN - 1) {
152 ret = -EINVAL;
153 goto end;
154 }
155 reloc_offset = (uint16_t) reloc_offset_u32;
156 ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
157 if (ret) {
158 goto end;
159 }
160 /* append reloc */
28ab034a 161 ret = bytecode_push(&ctx->bytecode_reloc, &reloc_offset, 1, sizeof(reloc_offset));
016dbbb4
MD
162 if (ret) {
163 goto end;
164 }
28ab034a 165 ret = bytecode_push(&ctx->bytecode_reloc, symbol, 1, strlen(symbol) + 1);
73e38068
JG
166 if (ret) {
167 goto end;
168 }
28ab034a 169 ret = 1; /* legacy */
016dbbb4
MD
170end:
171 free(insn);
172 free(symbol);
173 return ret;
174}
175
28ab034a 176static int visit_node_load_expression(struct filter_parser_ctx *ctx, const struct ir_op *node)
bff988fa
MD
177{
178 struct ir_load_expression *exp;
179 struct ir_load_expression_op *op;
016dbbb4 180 int ret;
bff988fa
MD
181
182 exp = node->u.load.u.expression;
183 if (!exp) {
184 return -EINVAL;
185 }
186 op = exp->child;
187 if (!op) {
188 return -EINVAL;
189 }
016dbbb4 190
b4bc01f7
MD
191 /*
192 * TODO: if we remove legacy load for application contexts, we
193 * need to update session bytecode parser as well.
194 */
016dbbb4
MD
195 ret = visit_node_load_expression_legacy(ctx, exp, op);
196 if (ret < 0) {
197 return ret;
198 }
199 if (ret > 0) {
28ab034a 200 return 0; /* legacy */
016dbbb4
MD
201 }
202
bff988fa
MD
203 for (; op != NULL; op = op->next) {
204 switch (op->type) {
205 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
206 {
9de37b2b 207 ret = bytecode_push_get_context_root(&ctx->bytecode);
bff988fa 208
bff988fa
MD
209 if (ret) {
210 return ret;
211 }
6afbab01 212
bff988fa
MD
213 break;
214 }
215 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
216 {
28ab034a 217 ret = bytecode_push_get_app_context_root(&ctx->bytecode);
bff988fa 218
bff988fa
MD
219 if (ret) {
220 return ret;
221 }
6afbab01 222
bff988fa
MD
223 break;
224 }
225 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
226 {
9de37b2b 227 ret = bytecode_push_get_payload_root(&ctx->bytecode);
bff988fa 228
bff988fa
MD
229 if (ret) {
230 return ret;
231 }
6afbab01 232
bff988fa
MD
233 break;
234 }
235 case IR_LOAD_EXPRESSION_GET_SYMBOL:
236 {
28ab034a
JG
237 ret = bytecode_push_get_symbol(
238 &ctx->bytecode, &ctx->bytecode_reloc, op->u.symbol);
bff988fa 239
bff988fa
MD
240 if (ret) {
241 return ret;
242 }
6afbab01 243
bff988fa
MD
244 break;
245 }
246 case IR_LOAD_EXPRESSION_GET_INDEX:
247 {
28ab034a 248 ret = bytecode_push_get_index_u64(&ctx->bytecode, op->u.index);
bff988fa 249
bff988fa
MD
250 if (ret) {
251 return ret;
252 }
6afbab01 253
bff988fa
MD
254 break;
255 }
256 case IR_LOAD_EXPRESSION_LOAD_FIELD:
257 {
258 struct load_op *insn;
259 uint32_t insn_len = sizeof(struct load_op);
bff988fa 260
348ddc5c 261 insn = (load_op *) calloc(insn_len, 1);
bff988fa
MD
262 if (!insn)
263 return -ENOMEM;
2b00d462 264 insn->op = BYTECODE_OP_LOAD_FIELD;
bff988fa
MD
265 ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
266 free(insn);
267 if (ret) {
268 return ret;
269 }
270 break;
271 }
272 }
273 }
274 return 0;
275}
276
28ab034a 277static int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
278{
279 int ret;
280
281 switch (node->data_type) {
282 case IR_DATA_UNKNOWN:
283 default:
28ab034a 284 fprintf(stderr, "[error] Unknown data type in %s\n", __func__);
953192ba
MD
285 return -EINVAL;
286
287 case IR_DATA_STRING:
288 {
289 struct load_op *insn;
28ab034a
JG
290 uint32_t insn_len =
291 sizeof(struct load_op) + strlen(node->u.load.u.string.value) + 1;
953192ba 292
348ddc5c 293 insn = (load_op *) calloc(insn_len, 1);
953192ba
MD
294 if (!insn)
295 return -ENOMEM;
9f449915
PP
296
297 switch (node->u.load.u.string.type) {
298 case IR_LOAD_STRING_TYPE_GLOB_STAR:
299 /*
300 * We explicitly tell the interpreter here that
301 * this load is a full star globbing pattern so
302 * that the appropriate matching function can be
303 * called. Also, see comment below.
304 */
2b00d462 305 insn->op = BYTECODE_OP_LOAD_STAR_GLOB_STRING;
9f449915
PP
306 break;
307 default:
308 /*
309 * This is the "legacy" string, which includes
310 * star globbing patterns with a star only at
311 * the end. Both "plain" and "star at the end"
312 * literal strings are handled at the same place
313 * by the tracer's filter bytecode interpreter,
314 * whereas full star globbing patterns (stars
315 * can be anywhere in the string) is a special
316 * case.
317 */
2b00d462 318 insn->op = BYTECODE_OP_LOAD_STRING;
9f449915
PP
319 break;
320 }
321
322 strcpy(insn->data, node->u.load.u.string.value);
953192ba
MD
323 ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
324 free(insn);
325 return ret;
326 }
327 case IR_DATA_NUMERIC:
328 {
329 struct load_op *insn;
28ab034a 330 uint32_t insn_len = sizeof(struct load_op) + sizeof(struct literal_numeric);
953192ba 331
348ddc5c 332 insn = (load_op *) calloc(insn_len, 1);
953192ba
MD
333 if (!insn)
334 return -ENOMEM;
2b00d462 335 insn->op = BYTECODE_OP_LOAD_S64;
58d494e4 336 memcpy(insn->data, &node->u.load.u.num, sizeof(int64_t));
953192ba
MD
337 ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
338 free(insn);
339 return ret;
340 }
e90d8561
MD
341 case IR_DATA_FLOAT:
342 {
343 struct load_op *insn;
28ab034a 344 uint32_t insn_len = sizeof(struct load_op) + sizeof(struct literal_double);
e90d8561 345
348ddc5c 346 insn = (load_op *) calloc(insn_len, 1);
e90d8561
MD
347 if (!insn)
348 return -ENOMEM;
2b00d462 349 insn->op = BYTECODE_OP_LOAD_DOUBLE;
58d494e4 350 memcpy(insn->data, &node->u.load.u.flt, sizeof(double));
e90d8561
MD
351 ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
352 free(insn);
353 return ret;
354 }
bff988fa
MD
355 case IR_DATA_EXPRESSION:
356 return visit_node_load_expression(ctx, node);
953192ba
MD
357 }
358}
359
28ab034a 360static int visit_node_unary(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
361{
362 int ret;
363 struct unary_op insn;
364
365 /* Visit child */
366 ret = recursive_visit_gen_bytecode(ctx, node->u.unary.child);
367 if (ret)
368 return ret;
369
370 /* Generate end of bytecode instruction */
371 switch (node->u.unary.type) {
372 case AST_UNARY_UNKNOWN:
373 default:
28ab034a 374 fprintf(stderr, "[error] Unknown unary node type in %s\n", __func__);
953192ba
MD
375 return -EINVAL;
376 case AST_UNARY_PLUS:
377 /* Nothing to do. */
378 return 0;
379 case AST_UNARY_MINUS:
2b00d462 380 insn.op = BYTECODE_OP_UNARY_MINUS;
953192ba
MD
381 return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
382 case AST_UNARY_NOT:
2b00d462 383 insn.op = BYTECODE_OP_UNARY_NOT;
953192ba 384 return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
116d3c01 385 case AST_UNARY_BIT_NOT:
2b00d462 386 insn.op = BYTECODE_OP_UNARY_BIT_NOT;
116d3c01 387 return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
953192ba
MD
388 }
389}
390
391/*
392 * Binary comparator nesting is disallowed. This allows fitting into
393 * only 2 registers.
394 */
28ab034a 395static int visit_node_binary(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
396{
397 int ret;
398 struct binary_op insn;
399
400 /* Visit child */
401 ret = recursive_visit_gen_bytecode(ctx, node->u.binary.left);
402 if (ret)
403 return ret;
404 ret = recursive_visit_gen_bytecode(ctx, node->u.binary.right);
405 if (ret)
406 return ret;
407
408 switch (node->u.binary.type) {
409 case AST_OP_UNKNOWN:
410 default:
28ab034a 411 fprintf(stderr, "[error] Unknown unary node type in %s\n", __func__);
953192ba
MD
412 return -EINVAL;
413
414 case AST_OP_AND:
415 case AST_OP_OR:
28ab034a 416 fprintf(stderr, "[error] Unexpected logical node type in %s\n", __func__);
953192ba
MD
417 return -EINVAL;
418
419 case AST_OP_MUL:
2b00d462 420 insn.op = BYTECODE_OP_MUL;
953192ba
MD
421 break;
422 case AST_OP_DIV:
2b00d462 423 insn.op = BYTECODE_OP_DIV;
953192ba
MD
424 break;
425 case AST_OP_MOD:
2b00d462 426 insn.op = BYTECODE_OP_MOD;
953192ba
MD
427 break;
428 case AST_OP_PLUS:
2b00d462 429 insn.op = BYTECODE_OP_PLUS;
953192ba
MD
430 break;
431 case AST_OP_MINUS:
2b00d462 432 insn.op = BYTECODE_OP_MINUS;
953192ba 433 break;
116d3c01 434 case AST_OP_BIT_RSHIFT:
2b00d462 435 insn.op = BYTECODE_OP_BIT_RSHIFT;
953192ba 436 break;
116d3c01 437 case AST_OP_BIT_LSHIFT:
2b00d462 438 insn.op = BYTECODE_OP_BIT_LSHIFT;
953192ba 439 break;
bff988fa 440 case AST_OP_BIT_AND:
2b00d462 441 insn.op = BYTECODE_OP_BIT_AND;
953192ba 442 break;
bff988fa 443 case AST_OP_BIT_OR:
2b00d462 444 insn.op = BYTECODE_OP_BIT_OR;
953192ba 445 break;
bff988fa 446 case AST_OP_BIT_XOR:
2b00d462 447 insn.op = BYTECODE_OP_BIT_XOR;
953192ba
MD
448 break;
449
450 case AST_OP_EQ:
2b00d462 451 insn.op = BYTECODE_OP_EQ;
953192ba
MD
452 break;
453 case AST_OP_NE:
2b00d462 454 insn.op = BYTECODE_OP_NE;
953192ba
MD
455 break;
456 case AST_OP_GT:
2b00d462 457 insn.op = BYTECODE_OP_GT;
953192ba
MD
458 break;
459 case AST_OP_LT:
2b00d462 460 insn.op = BYTECODE_OP_LT;
953192ba
MD
461 break;
462 case AST_OP_GE:
2b00d462 463 insn.op = BYTECODE_OP_GE;
953192ba
MD
464 break;
465 case AST_OP_LE:
2b00d462 466 insn.op = BYTECODE_OP_LE;
953192ba
MD
467 break;
468 }
469 return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
470}
471
8cf9540a
MD
472/*
473 * A logical op always return a s64 (1 or 0).
474 */
28ab034a 475static int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
476{
477 int ret;
478 struct logical_op insn;
479 uint16_t skip_offset_loc;
480 uint16_t target_loc;
481
482 /* Visit left child */
483 ret = recursive_visit_gen_bytecode(ctx, node->u.binary.left);
484 if (ret)
485 return ret;
8cf9540a 486 /* Cast to s64 if float or field ref */
28ab034a
JG
487 if ((node->u.binary.left->data_type == IR_DATA_FIELD_REF ||
488 node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF ||
489 node->u.binary.left->data_type == IR_DATA_EXPRESSION) ||
490 node->u.binary.left->data_type == IR_DATA_FLOAT) {
8cf9540a
MD
491 struct cast_op cast_insn;
492
28ab034a
JG
493 if (node->u.binary.left->data_type == IR_DATA_FIELD_REF ||
494 node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF ||
495 node->u.binary.left->data_type == IR_DATA_EXPRESSION) {
2b00d462 496 cast_insn.op = BYTECODE_OP_CAST_TO_S64;
29fefef8 497 } else {
2b00d462 498 cast_insn.op = BYTECODE_OP_CAST_DOUBLE_TO_S64;
29fefef8 499 }
28ab034a 500 ret = bytecode_push(&ctx->bytecode, &cast_insn, 1, sizeof(cast_insn));
8cf9540a
MD
501 if (ret)
502 return ret;
503 }
953192ba
MD
504 switch (node->u.logical.type) {
505 default:
28ab034a 506 fprintf(stderr, "[error] Unknown node type in %s\n", __func__);
953192ba
MD
507 return -EINVAL;
508
509 case AST_OP_AND:
2b00d462 510 insn.op = BYTECODE_OP_AND;
953192ba
MD
511 break;
512 case AST_OP_OR:
2b00d462 513 insn.op = BYTECODE_OP_OR;
953192ba
MD
514 break;
515 }
28ab034a
JG
516 insn.skip_offset = (uint16_t) -1UL; /* Temporary */
517 ret = bytecode_push_logical(&ctx->bytecode, &insn, 1, sizeof(insn), &skip_offset_loc);
953192ba
MD
518 if (ret)
519 return ret;
520 /* Visit right child */
521 ret = recursive_visit_gen_bytecode(ctx, node->u.binary.right);
522 if (ret)
523 return ret;
8cf9540a 524 /* Cast to s64 if float or field ref */
28ab034a
JG
525 if ((node->u.binary.right->data_type == IR_DATA_FIELD_REF ||
526 node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF ||
527 node->u.binary.right->data_type == IR_DATA_EXPRESSION) ||
528 node->u.binary.right->data_type == IR_DATA_FLOAT) {
8cf9540a
MD
529 struct cast_op cast_insn;
530
28ab034a
JG
531 if (node->u.binary.right->data_type == IR_DATA_FIELD_REF ||
532 node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF ||
533 node->u.binary.right->data_type == IR_DATA_EXPRESSION) {
2b00d462 534 cast_insn.op = BYTECODE_OP_CAST_TO_S64;
29fefef8 535 } else {
2b00d462 536 cast_insn.op = BYTECODE_OP_CAST_DOUBLE_TO_S64;
29fefef8 537 }
28ab034a 538 ret = bytecode_push(&ctx->bytecode, &cast_insn, 1, sizeof(cast_insn));
8cf9540a
MD
539 if (ret)
540 return ret;
541 }
953192ba
MD
542 /* We now know where the logical op can skip. */
543 target_loc = (uint16_t) bytecode_get_len(&ctx->bytecode->b);
544 ret = bytecode_patch(&ctx->bytecode,
28ab034a
JG
545 &target_loc, /* Offset to jump to */
546 skip_offset_loc, /* Where to patch */
547 sizeof(uint16_t));
953192ba
MD
548 return ret;
549}
550
551/*
552 * Postorder traversal of the tree. We need the children result before
553 * we can evaluate the parent.
554 */
28ab034a 555static int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, struct ir_op *node)
953192ba
MD
556{
557 switch (node->op) {
558 case IR_OP_UNKNOWN:
559 default:
28ab034a 560 fprintf(stderr, "[error] Unknown node type in %s\n", __func__);
953192ba
MD
561 return -EINVAL;
562
563 case IR_OP_ROOT:
564 return visit_node_root(ctx, node);
565 case IR_OP_LOAD:
566 return visit_node_load(ctx, node);
567 case IR_OP_UNARY:
568 return visit_node_unary(ctx, node);
569 case IR_OP_BINARY:
570 return visit_node_binary(ctx, node);
571 case IR_OP_LOGICAL:
572 return visit_node_logical(ctx, node);
573 }
574}
575
576void filter_bytecode_free(struct filter_parser_ctx *ctx)
577{
7ca1dc6f
DG
578 if (!ctx) {
579 return;
580 }
581
3f0c8837
DG
582 if (ctx->bytecode) {
583 free(ctx->bytecode);
584 ctx->bytecode = NULL;
585 }
586
587 if (ctx->bytecode_reloc) {
588 free(ctx->bytecode_reloc);
589 ctx->bytecode_reloc = NULL;
590 }
953192ba
MD
591}
592
593int filter_visitor_bytecode_generate(struct filter_parser_ctx *ctx)
594{
595 int ret;
596
597 ret = bytecode_init(&ctx->bytecode);
598 if (ret)
599 return ret;
600 ret = bytecode_init(&ctx->bytecode_reloc);
601 if (ret)
602 goto error;
603 ret = recursive_visit_gen_bytecode(ctx, ctx->ir_root);
604 if (ret)
605 goto error;
606
607 /* Finally, append symbol table to bytecode */
608 ctx->bytecode->b.reloc_table_offset = bytecode_get_len(&ctx->bytecode->b);
28ab034a
JG
609 return bytecode_push(&ctx->bytecode,
610 ctx->bytecode_reloc->b.data,
611 1,
612 bytecode_get_len(&ctx->bytecode_reloc->b));
953192ba
MD
613
614error:
615 filter_bytecode_free(ctx);
616 return ret;
617}
This page took 0.093807 seconds and 4 git commands to generate.