2 * SPDX-License-Identifier: MIT
4 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * LTTng UST bytecode header.
9 #ifndef _LTTNG_BYTECODE_H
10 #define _LTTNG_BYTECODE_H
15 #include <ust-helper.h>
16 #include <lttng/ust-events.h>
17 #include <ust-context-provider.h>
24 #include <usterr-signal-safe.h>
27 /* Interpreter stack length, in number of entries */
28 #define INTERPRETER_STACK_LEN 10 /* includes 2 dummy */
29 #define INTERPRETER_STACK_EMPTY 1
31 #define BYTECODE_MAX_DATA_LEN 65536
34 #define min_t(type, a, b) \
35 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
39 #define likely(x) __builtin_expect(!!(x), 1)
43 #define unlikely(x) __builtin_expect(!!(x), 0)
47 #define dbg_printf(fmt, args...) \
48 printf("[debug bytecode in %s:%s@%u] " fmt, \
49 __FILE__, __func__, __LINE__, ## args)
51 #define dbg_printf(fmt, args...) \
53 /* do nothing but check printf format */ \
55 printf("[debug bytecode in %s:%s@%u] " fmt, \
56 __FILE__, __func__, __LINE__, ## args); \
60 /* Linked bytecode. Child of struct lttng_bytecode_runtime. */
61 struct bytecode_runtime
{
62 struct lttng_ust_bytecode_runtime p
;
64 size_t data_alloc_len
;
82 LOAD_ROOT_APP_CONTEXT
,
97 OBJECT_TYPE_SIGNED_ENUM
,
98 OBJECT_TYPE_UNSIGNED_ENUM
,
102 OBJECT_TYPE_STRING_SEQUENCE
,
104 OBJECT_TYPE_SEQUENCE
,
112 struct bytecode_get_index_data
{
113 uint64_t offset
; /* in bytes */
117 * Field is only populated for LOAD_ROOT_CONTEXT, LOAD_ROOT_APP_CONTEXT
118 * and LOAD_ROOT_PAYLOAD. Left NULL for LOAD_OBJECT, considering that the
119 * interpreter needs to find it from the event fields and types to
122 struct lttng_ust_event_field
*field
;
125 enum object_type type
;
126 bool rev_bo
; /* reverse byte order */
130 /* Validation stack */
133 enum object_type object_type
;
134 struct lttng_ust_event_field
*field
;
135 bool rev_bo
; /* reverse byte order */
138 struct vstack_entry
{
139 enum entry_type type
;
140 struct vstack_load load
;
144 int top
; /* top of stack */
145 struct vstack_entry e
[INTERPRETER_STACK_LEN
];
149 void vstack_init(struct vstack
*stack
)
155 struct vstack_entry
*vstack_ax(struct vstack
*stack
)
157 if (unlikely(stack
->top
< 0))
159 return &stack
->e
[stack
->top
];
163 struct vstack_entry
*vstack_bx(struct vstack
*stack
)
165 if (unlikely(stack
->top
< 1))
167 return &stack
->e
[stack
->top
- 1];
171 int vstack_push(struct vstack
*stack
)
173 if (stack
->top
>= INTERPRETER_STACK_LEN
- 1) {
182 int vstack_pop(struct vstack
*stack
)
184 if (unlikely(stack
->top
< 0)) {
185 ERR("Stack empty\n");
192 /* Execution stack */
193 enum estack_string_literal_type
{
194 ESTACK_STRING_LITERAL_TYPE_NONE
,
195 ESTACK_STRING_LITERAL_TYPE_PLAIN
,
196 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
,
201 enum object_type object_type
;
205 /* Temporary place-holders for contexts. */
211 const struct lttng_ust_event_field
*field
;
214 struct estack_entry
{
215 enum entry_type type
; /* For dynamic typing. */
223 enum estack_string_literal_type literal_type
;
230 int top
; /* top of stack */
231 struct estack_entry e
[INTERPRETER_STACK_LEN
];
235 * Always use aliased type for ax/bx (top of stack).
236 * When ax/bx are S64, use aliased value.
238 #define estack_ax_v ax
239 #define estack_bx_v bx
240 #define estack_ax_t ax_t
241 #define estack_bx_t bx_t
244 * ax and bx registers can hold either integer, double or string.
246 #define estack_ax(stack, top) \
248 assert((top) > INTERPRETER_STACK_EMPTY); \
252 #define estack_bx(stack, top) \
254 assert((top) > INTERPRETER_STACK_EMPTY + 1); \
255 &(stack)->e[(top) - 1]; \
259 * Currently, only integers (REG_S64) can be pushed into the stack.
261 #define estack_push(stack, top, ax, bx, ax_t, bx_t) \
263 assert((top) < INTERPRETER_STACK_LEN - 1); \
264 (stack)->e[(top) - 1].u.v = (bx); \
265 (stack)->e[(top) - 1].type = (bx_t); \
271 #define estack_pop(stack, top, ax, bx, ax_t, bx_t) \
273 assert((top) > INTERPRETER_STACK_EMPTY); \
276 (bx) = (stack)->e[(top) - 2].u.v; \
277 (bx_t) = (stack)->e[(top) - 2].type; \
281 enum lttng_interpreter_type
{
282 LTTNG_INTERPRETER_TYPE_S64
,
283 LTTNG_INTERPRETER_TYPE_U64
,
284 LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
,
285 LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
,
286 LTTNG_INTERPRETER_TYPE_DOUBLE
,
287 LTTNG_INTERPRETER_TYPE_STRING
,
288 LTTNG_INTERPRETER_TYPE_SEQUENCE
,
292 * Represents the output parameter of the lttng interpreter.
293 * Currently capturable field classes are integer, double, string and sequence
296 struct lttng_interpreter_output
{
297 enum lttng_interpreter_type type
;
312 struct lttng_ust_type_common
*nested_type
;
317 __attribute__((visibility("hidden")))
318 const char *lttng_bytecode_print_op(enum bytecode_op op
);
320 __attribute__((visibility("hidden")))
321 void lttng_bytecode_filter_sync_state(struct lttng_ust_bytecode_runtime
*runtime
);
323 __attribute__((visibility("hidden")))
324 void lttng_bytecode_capture_sync_state(struct lttng_ust_bytecode_runtime
*runtime
);
326 __attribute__((visibility("hidden")))
327 int lttng_bytecode_validate(struct bytecode_runtime
*bytecode
);
329 __attribute__((visibility("hidden")))
330 int lttng_bytecode_specialize(struct lttng_ust_event_desc
*event_desc
,
331 struct bytecode_runtime
*bytecode
);
333 __attribute__((visibility("hidden")))
334 uint64_t lttng_bytecode_filter_interpret_false(void *filter_data
,
335 const char *filter_stack_data
);
337 __attribute__((visibility("hidden")))
338 uint64_t lttng_bytecode_filter_interpret(void *filter_data
,
339 const char *filter_stack_data
);
341 __attribute__((visibility("hidden")))
342 uint64_t lttng_bytecode_capture_interpret_false(void *capture_data
,
343 const char *capture_stack_data
,
344 struct lttng_interpreter_output
*output
);
346 __attribute__((visibility("hidden")))
347 uint64_t lttng_bytecode_capture_interpret(void *capture_data
,
348 const char *capture_stack_data
,
349 struct lttng_interpreter_output
*output
);
351 #endif /* _LTTNG_BYTECODE_H */