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 "common/macros.h"
16 #include <lttng/ust-events.h>
17 #include "common/ust-context-provider.h"
24 #include "common/logging.h"
26 #include "lib/lttng-ust/events.h"
28 /* Interpreter stack length, in number of entries */
29 #define INTERPRETER_STACK_LEN 10 /* includes 2 dummy */
30 #define INTERPRETER_STACK_EMPTY 1
32 #define BYTECODE_MAX_DATA_LEN 65536
35 #define min_t(type, a, b) \
36 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
40 #define likely(x) __builtin_expect(!!(x), 1)
44 #define unlikely(x) __builtin_expect(!!(x), 0)
48 #define dbg_printf(fmt, args...) \
49 printf("[debug bytecode in %s:%s@%u] " fmt, \
50 __FILE__, __func__, __LINE__, ## args)
52 #define dbg_printf(fmt, args...) \
54 /* do nothing but check printf format */ \
56 printf("[debug bytecode in %s:%s@%u] " fmt, \
57 __FILE__, __func__, __LINE__, ## args); \
61 /* Linked bytecode. Child of struct lttng_ust_bytecode_runtime. */
62 struct bytecode_runtime
{
63 struct lttng_ust_bytecode_runtime p
;
65 size_t data_alloc_len
;
83 LOAD_ROOT_APP_CONTEXT
,
98 OBJECT_TYPE_SIGNED_ENUM
,
99 OBJECT_TYPE_UNSIGNED_ENUM
,
103 OBJECT_TYPE_STRING_SEQUENCE
,
105 OBJECT_TYPE_SEQUENCE
,
113 struct bytecode_get_index_data
{
114 uint64_t offset
; /* in bytes */
118 * Field is only populated for LOAD_ROOT_CONTEXT, LOAD_ROOT_APP_CONTEXT
119 * and LOAD_ROOT_PAYLOAD. Left NULL for LOAD_OBJECT, considering that the
120 * interpreter needs to find it from the event fields and types to
123 const struct lttng_ust_event_field
*field
;
126 enum object_type type
;
127 bool rev_bo
; /* reverse byte order */
131 /* Validation stack */
134 enum object_type object_type
;
135 const struct lttng_ust_event_field
*field
;
136 bool rev_bo
; /* reverse byte order */
139 struct vstack_entry
{
140 enum entry_type type
;
141 struct vstack_load load
;
145 int top
; /* top of stack */
146 struct vstack_entry e
[INTERPRETER_STACK_LEN
];
150 void vstack_init(struct vstack
*stack
)
156 struct vstack_entry
*vstack_ax(struct vstack
*stack
)
158 if (unlikely(stack
->top
< 0))
160 return &stack
->e
[stack
->top
];
164 struct vstack_entry
*vstack_bx(struct vstack
*stack
)
166 if (unlikely(stack
->top
< 1))
168 return &stack
->e
[stack
->top
- 1];
172 int vstack_push(struct vstack
*stack
)
174 if (stack
->top
>= INTERPRETER_STACK_LEN
- 1) {
183 int vstack_pop(struct vstack
*stack
)
185 if (unlikely(stack
->top
< 0)) {
186 ERR("Stack empty\n");
193 /* Execution stack */
194 enum estack_string_literal_type
{
195 ESTACK_STRING_LITERAL_TYPE_NONE
,
196 ESTACK_STRING_LITERAL_TYPE_PLAIN
,
197 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
,
202 enum object_type object_type
;
206 /* Temporary place-holders for contexts. */
212 const struct lttng_ust_event_field
*field
;
215 struct estack_entry
{
216 enum entry_type type
; /* For dynamic typing. */
224 enum estack_string_literal_type literal_type
;
231 int top
; /* top of stack */
232 struct estack_entry e
[INTERPRETER_STACK_LEN
];
236 * Always use aliased type for ax/bx (top of stack).
237 * When ax/bx are S64, use aliased value.
239 #define estack_ax_v ax
240 #define estack_bx_v bx
241 #define estack_ax_t ax_t
242 #define estack_bx_t bx_t
245 * ax and bx registers can hold either integer, double or string.
247 #define estack_ax(stack, top) \
249 assert((top) > INTERPRETER_STACK_EMPTY); \
253 #define estack_bx(stack, top) \
255 assert((top) > INTERPRETER_STACK_EMPTY + 1); \
256 &(stack)->e[(top) - 1]; \
260 * Currently, only integers (REG_S64) can be pushed into the stack.
262 #define estack_push(stack, top, ax, bx, ax_t, bx_t) \
264 assert((top) < INTERPRETER_STACK_LEN - 1); \
265 (stack)->e[(top) - 1].u.v = (bx); \
266 (stack)->e[(top) - 1].type = (bx_t); \
272 #define estack_pop(stack, top, ax, bx, ax_t, bx_t) \
274 assert((top) > INTERPRETER_STACK_EMPTY); \
277 (bx) = (stack)->e[(top) - 2].u.v; \
278 (bx_t) = (stack)->e[(top) - 2].type; \
282 enum lttng_interpreter_type
{
283 LTTNG_INTERPRETER_TYPE_S64
,
284 LTTNG_INTERPRETER_TYPE_U64
,
285 LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
,
286 LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
,
287 LTTNG_INTERPRETER_TYPE_DOUBLE
,
288 LTTNG_INTERPRETER_TYPE_STRING
,
289 LTTNG_INTERPRETER_TYPE_SEQUENCE
,
293 * Represents the output parameter of the lttng interpreter.
294 * Currently capturable field classes are integer, double, string and sequence
297 struct lttng_interpreter_output
{
298 enum lttng_interpreter_type type
;
313 const struct lttng_ust_type_common
*nested_type
;
318 const char *lttng_bytecode_print_op(enum bytecode_op op
)
319 __attribute__((visibility("hidden")));
321 void lttng_bytecode_sync_state(struct lttng_ust_bytecode_runtime
*runtime
)
322 __attribute__((visibility("hidden")));
324 int lttng_bytecode_validate(struct bytecode_runtime
*bytecode
)
325 __attribute__((visibility("hidden")));
327 int lttng_bytecode_specialize(const struct lttng_ust_event_desc
*event_desc
,
328 struct bytecode_runtime
*bytecode
)
329 __attribute__((visibility("hidden")));
331 int lttng_bytecode_interpret_error(struct lttng_ust_bytecode_runtime
*bytecode_runtime
,
332 const char *stack_data
,
333 struct lttng_ust_probe_ctx
*probe_ctx
,
335 __attribute__((visibility("hidden")));
337 int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime
*bytecode_runtime
,
338 const char *stack_data
,
339 struct lttng_ust_probe_ctx
*probe_ctx
,
341 __attribute__((visibility("hidden")));
343 #endif /* _LTTNG_BYTECODE_H */