From 2e1974975ff974509e836bc489737ea4ee597aea Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 23 Nov 2023 14:32:02 -0500 Subject: [PATCH] Enforce ABI size checks Signed-off-by: Mathieu Desnoyers --- include/side/endian.h | 9 +- include/side/macros-bkp.h | 71 ++++++++++++++++ include/side/macros.h | 128 ++++++++++++++++++++++------ include/side/trace.h | 174 ++++++++++++++++++++++++++++---------- src/.tracer.c.swp | Bin 0 -> 81920 bytes src/tracer.c | 12 +-- 6 files changed, 313 insertions(+), 81 deletions(-) create mode 100644 include/side/macros-bkp.h create mode 100644 src/.tracer.c.swp diff --git a/include/side/endian.h b/include/side/endian.h index de8ccd7..c89d486 100644 --- a/include/side/endian.h +++ b/include/side/endian.h @@ -29,9 +29,16 @@ #ifndef _SIDE_ENDIAN_H #define _SIDE_ENDIAN_H -#include #include +#if defined(__SIZEOF_LONG__) +# define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) +#elif defined(_LP64) +# define SIDE_BITS_PER_LONG 64 +#else +# define SIDE_BITS_PER_LONG 32 +#endif + #if (defined(__linux__) || defined(__CYGWIN__)) #include #include diff --git a/include/side/macros-bkp.h b/include/side/macros-bkp.h new file mode 100644 index 0000000..3c9f6b7 --- /dev/null +++ b/include/side/macros-bkp.h @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2022 Mathieu Desnoyers + */ + +#ifndef _SIDE_MACROS_H +#define _SIDE_MACROS_H + +#include +#include + +/* Helper macros */ + +#define SIDE_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/* + * Compound literals with static storage are needed by SIDE + * instrumentation. + * Compound literals are part of the C99 and C11 standards, but not + * part of the C++ standards. They are supported by most C++ compilers + * though. + * + * Example use: + * static struct mystruct *var = LTTNG_UST_COMPOUND_LITERAL(struct mystruct, { 1, 2, 3 }); + */ +#define SIDE_COMPOUND_LITERAL(type, ...) (type[]) { __VA_ARGS__ } + +#define side_likely(x) __builtin_expect(!!(x), 1) +#define side_unlikely(x) __builtin_expect(!!(x), 0) + +#define SIDE_PARAM(...) __VA_ARGS__ + +/* Select arg1 in list of arguments. */ +#define SIDE_PARAM_SELECT_ARG1(_arg0, _arg1, ...) _arg1 + +/* + * Use the default parameter if no additional arguments are provided, +.* else use the following arguments. Use inside macros to implement + * optional last macro argument. + */ +#define SIDE_PARAM_DEFAULT(_default, ...) \ + SIDE_PARAM_SELECT_ARG1(dummy, ##__VA_ARGS__, _default) + +/* + * side_container_of - Get the address of an object containing a field. + * + * @ptr: pointer to the field. + * @type: type of the object. + * @member: name of the field within the object. + */ +#define side_container_of(ptr, type, member) \ + __extension__ \ + ({ \ + const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \ + (type *)((char *)__ptr - offsetof(type, member)); \ + }) + +#define side_struct_field_sizeof(_struct, _field) \ + sizeof(((_struct * )NULL)->_field) + +#if defined(__SIZEOF_LONG__) +#define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) +#elif defined(_LP64) +#define SIDE_BITS_PER_LONG 64 +#else +#define SIDE_BITS_PER_LONG 32 +#endif + +#define SIDE_PACKED __attribute__((packed)) + +#endif /* _SIDE_MACROS_H */ diff --git a/include/side/macros.h b/include/side/macros.h index 3915374..26fc079 100644 --- a/include/side/macros.h +++ b/include/side/macros.h @@ -8,6 +8,8 @@ #include #include +#include +#include /* Helper macros */ @@ -54,6 +56,38 @@ */ #define SIDE_PARAM_SELECT_ARG1(_arg0, _arg1, ...) _arg1 +/* + * Compile time assertion. + * - predicate: boolean expression to evaluate, + * - msg: string to print to the user on failure when `static_assert()` is + * supported, + * - c_identifier_msg: message to be included in the typedef to emulate a + * static assertion. This parameter must be a valid C identifier as it will + * be used as a typedef name. + */ +#ifdef __cplusplus +#define side_static_assert(predicate, msg, c_identifier_msg) \ + static_assert(predicate, msg) +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define side_static_assert(predicate, msg, c_identifier_msg) \ + _Static_assert(predicate, msg) +#else +/* + * Evaluates the predicate and emit a compilation error on failure. + * + * If the predicate evaluates to true, this macro emits a function + * prototype with an argument type which is an array of size 0. + * + * If the predicate evaluates to false, this macro emits a function + * prototype with an argument type which is an array of negative size + * which is invalid in C and forces a compiler error. The + * c_identifier_msg parameter is used as the argument identifier so it + * is printed to the user when the error is reported. + */ +#define side_static_assert(predicate, msg, c_identifier_msg) \ + void side_static_assert_proto(char c_identifier_msg[2*!!(predicate)-1]) +#endif + /* * side_container_of - Get the address of an object containing a field. * @@ -71,57 +105,93 @@ #define side_struct_field_sizeof(_struct, _field) \ sizeof(((_struct * )NULL)->_field) -#if defined(__SIZEOF_LONG__) -# define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) -#elif defined(_LP64) -# define SIDE_BITS_PER_LONG 64 +#define SIDE_PACKED __attribute__((packed)) + +#define side_padding(bytes) char padding[bytes] + +#define side_check_size(_type, _len) \ + side_static_assert(sizeof(_type) == (_len), \ + "Unexpected size for type: `" #_type "`", \ + unexpected_size_for_type_##_type) + +#if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN) +#define SIDE_ENDIAN_ORDER(_low, _high) _low, _high #else -# define SIDE_BITS_PER_LONG 32 +#define SIDE_ENDIAN_ORDER(_low, _high) _high, _low #endif -#define SIDE_PACKED __attribute__((packed)) - /* * The side_ptr macros allow defining a pointer type which is suitable - * for use by 32-bit and 64-bit kernels without compatibility code, - * while preserving information about the pointer type. + * for use by 32-bit, 64-bit and 128-bit kernels without compatibility + * code, while preserving information about the pointer type. * - * Those pointers are stored as 64-bit integers, and the type of the - * actual pointer is kept alongside with the 64-bit pointer value in a + * Those pointers are stored as 128-bit integers, and the type of the + * actual pointer is kept alongside with the 128-bit pointer value in a * 0-len array within a union. - * - * uintptr_t will fit within a uint64_t except on architectures with - * 128-bit pointers. This provides fixed-size pointers on architectures - * with pointer size of 64-bit or less. Architectures with larger - * pointer size will have to handle the ABI offset specifics explicitly. */ #if (__SIZEOF_POINTER__ <= 8) -# define side_ptr_t(_type) \ +# define side_raw_ptr_t(_type) \ union { \ - uint64_t v; \ - _type *t[0]; \ + struct { \ + uint64_t SIDE_ENDIAN_ORDER(low, high); \ + } v; \ + struct { \ + _type t[0]; \ + } SIDE_PACKED s; \ + side_padding(16); \ } # define side_ptr_get(_field) \ - ((__typeof__((_field).t[0]))(uintptr_t)(_field).v) + ((__typeof__((_field).s.t[0]))(uintptr_t)(_field).v.low) # define side_ptr_set(_field, _ptr) \ do { \ - (_field).v = (uint64_t)(uintptr_t)(_ptr); \ + (_field).v.low = (uint64_t)(uintptr_t)(_ptr); \ + (_field).v.high = 0; \ } while (0) -#else -# define side_ptr_t(_type) \ + +/* Keep the correct field init order to make old g++ happy. */ +# if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN) +# define SIDE_PTR_INIT(...) \ + { \ + .v = { \ + .low = (uintptr_t) (__VA_ARGS__), \ + .high = 0, \ + }, \ + } +# else +# define SIDE_PTR_INIT(...) \ + { \ + .v = { \ + .high = 0, \ + .low = (uintptr_t) (__VA_ARGS__), \ + }, \ + } +# endif +#elif (__SIZEOF_POINTER__ == 16) +# define side_raw_ptr_t(_type) \ union { \ uintptr_t v; \ - _type *t[0]; \ + struct { \ + _type t[0]; \ + } SIDE_PACKED s; \ + side_padding(16); \ } # define side_ptr_get(_field) \ - ((__typeof__((_field).t[0]))(_field).v) + ((__typeof__((_field).s.t[0]))(_field).v) # define side_ptr_set(_field, _ptr) \ do { \ (_field).v = (uintptr_t)(_ptr); \ } while (0) +# define SIDE_PTR_INIT(...) { .v = (uintptr_t) (__VA_ARGS__) } +#else +# error "Unsupported pointer size" #endif -#define SIDE_PTR_INIT(...) { .v = (uintptr_t) (__VA_ARGS__) } +#define side_ptr_t(_type) side_raw_ptr_t(_type *) +#define side_func_ptr_t(_type) side_raw_ptr_t(_type) + +side_static_assert(sizeof(side_ptr_t(int)) == 16, + "Unexpected size for side_ptr_t", + unexpected_size_side_ptr_t); /* * side_enum_t allows defining fixed-sized enumerations while preserving @@ -130,11 +200,13 @@ #define side_enum_t(_enum_type, _size_type) \ union { \ _size_type v; \ - _enum_type t[0]; \ + struct { \ + _enum_type t[0]; \ + } SIDE_PACKED s; \ } #define side_enum_get(_field) \ - ((__typeof__((_field).t[0]))(_field).v) + ((__typeof__((_field).s.t[0]))(_field).v) #define side_enum_set(_field, _v) \ do { \ diff --git a/include/side/trace.h b/include/side/trace.h index fad7c2b..329bec1 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -18,11 +18,11 @@ /* * SIDE stands for "Software Instrumentation Dynamically Enabled" * - * This is an instrumentation API for Linux user-space, which exposes an + * This is an instrumentation ABI for Linux user-space, which exposes an * instrumentation type system and facilities allowing a kernel or * user-space tracer to consume user-space instrumentation. * - * This instrumentation API exposes 3 type systems: + * This instrumentation ABI exposes 3 type systems: * * * Stack-copy type system: This is the core type system which can * represent all supported types and into which all other type systems @@ -65,6 +65,28 @@ * Those dynamic types can be either used as arguments to a variadic * field list, or as on-stack instrumentation argument for a static * type SIDE_TYPE_DYNAMIC place holder in the stack-copy type system. + * + * The extensibility scheme for the SIDE ABI is as follows: + * + * * Existing field types are never changed nor extended. Field types + * can be added to the ABI by reserving a label within + * enum side_type_label. + * * Existing attribute types are never changed nor extended. Attribute + * types can be added to the ABI by reserving a label within + * enum side_attr_type. + * * Each union part of the ABI has an explicit side defined by a + * side_padding() member. Each structure and union have a static + * assert validating its size. + * + * Handling of unknown types by the tracers: + * + * * A tracer may choose to support only a subset of the types supported + * by libside. When encountering an unknown or unsupported type, the + * tracer has the option to either disallow the entire event or skip + * over the unknown type, both at event registration and when + * receiving the side_call arguments. + * + * TODO: extend event description with new fields ? */ //TODO: as those structures will be ABI, we need to either consider them @@ -85,6 +107,7 @@ struct side_arg_dynamic_struct; struct side_events_register_handle; struct side_arg_variant; struct side_event_state; +struct side_callback; enum side_type_label { /* Stack-copy basic types */ @@ -226,6 +249,12 @@ typedef enum side_visitor_status (*side_visitor_func)( typedef enum side_visitor_status (*side_dynamic_struct_visitor_func)( const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx, void *app_ctx); +typedef enum side_visitor_status (*side_write_elem_func)( + const struct side_tracer_visitor_ctx *tracer_ctx, + const struct side_arg *elem); +typedef enum side_visitor_status (*side_write_field_func)( + const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx, + const struct side_arg_dynamic_field *dynamic_field); union side_integer_value { uint8_t side_u8; @@ -237,14 +266,18 @@ union side_integer_value { int32_t side_s32; int64_t side_s64; uintptr_t side_uptr; + side_padding(32); } SIDE_PACKED; +side_check_size(union side_integer_value, 32); union side_bool_value { uint8_t side_bool8; uint16_t side_bool16; uint32_t side_bool32; uint64_t side_bool64; + side_padding(32); } SIDE_PACKED; +side_check_size(union side_bool_value, 32); union side_float_value { #if __HAVE_FLOAT16 @@ -259,13 +292,16 @@ union side_float_value { #if __HAVE_FLOAT128 _Float128 side_float_binary128; #endif + side_padding(32); } SIDE_PACKED; +side_check_size(union side_float_value, 32); struct side_type_raw_string { side_ptr_t(const void) p; /* pointer to string */ uint8_t unit_size; /* 1, 2, or 4 bytes */ side_enum_t(enum side_type_label_byte_order, uint8_t) byte_order; } SIDE_PACKED; +side_check_size(struct side_type_raw_string, 18); struct side_attr_value { side_enum_t(enum side_attr_type, uint32_t) type; @@ -274,20 +310,24 @@ struct side_attr_value { struct side_type_raw_string string_value; union side_integer_value integer_value; union side_float_value float_value; + side_padding(32); } SIDE_PACKED u; }; +side_check_size(struct side_attr_value, 36); /* User attributes. */ struct side_attr { const struct side_type_raw_string key; const struct side_attr_value value; } SIDE_PACKED; +side_check_size(struct side_attr, 54); /* Type descriptions */ struct side_type_null { side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_null, 20); struct side_type_bool { side_ptr_t(const struct side_attr) attr; @@ -296,11 +336,13 @@ struct side_type_bool { uint16_t len_bits; /* bits. 0 for (bool_size * CHAR_BITS) */ side_enum_t(enum side_type_label_byte_order, uint8_t) byte_order; } SIDE_PACKED; +side_check_size(struct side_type_bool, 25); struct side_type_byte { side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_byte, 20); struct side_type_string { side_ptr_t(const struct side_attr) attr; @@ -308,6 +350,7 @@ struct side_type_string { uint8_t unit_size; /* 1, 2, or 4 bytes */ side_enum_t(enum side_type_label_byte_order, uint8_t) byte_order; } SIDE_PACKED; +side_check_size(struct side_type_string, 22); struct side_type_integer { side_ptr_t(const struct side_attr) attr; @@ -317,6 +360,7 @@ struct side_type_integer { uint8_t signedness; /* true/false */ side_enum_t(enum side_type_label_byte_order, uint8_t) byte_order; } SIDE_PACKED; +side_check_size(struct side_type_integer, 26); struct side_type_float { side_ptr_t(const struct side_attr) attr; @@ -324,12 +368,14 @@ struct side_type_float { uint16_t float_size; /* bytes */ side_enum_t(enum side_type_label_byte_order, uint8_t) byte_order; } SIDE_PACKED; +side_check_size(struct side_type_float, 23); struct side_enum_mapping { int64_t range_begin; int64_t range_end; struct side_type_raw_string label; } SIDE_PACKED; +side_check_size(struct side_enum_mapping, 16 + sizeof(struct side_type_raw_string)); struct side_enum_mappings { side_ptr_t(const struct side_enum_mapping) mappings; @@ -337,12 +383,14 @@ struct side_enum_mappings { uint32_t nr_mappings; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_enum_mappings, 40); struct side_enum_bitmap_mapping { uint64_t range_begin; uint64_t range_end; struct side_type_raw_string label; } SIDE_PACKED; +side_check_size(struct side_enum_bitmap_mapping, 16 + sizeof(struct side_type_raw_string)); struct side_enum_bitmap_mappings { side_ptr_t(const struct side_enum_bitmap_mapping) mappings; @@ -350,6 +398,7 @@ struct side_enum_bitmap_mappings { uint32_t nr_mappings; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_enum_bitmap_mappings, 40); struct side_type_struct { side_ptr_t(const struct side_event_field) fields; @@ -357,6 +406,7 @@ struct side_type_struct { uint32_t nr_fields; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_struct, 40); struct side_type_array { side_ptr_t(const struct side_type) elem_type; @@ -364,87 +414,100 @@ struct side_type_array { uint32_t length; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_array, 40); struct side_type_vla { side_ptr_t(const struct side_type) elem_type; side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_vla, 36); struct side_type_vla_visitor { side_ptr_t(const struct side_type) elem_type; - side_visitor_func visitor; + side_func_ptr_t(side_visitor_func) visitor; side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_type_vla_visitor, 52); struct side_type_enum { side_ptr_t(const struct side_enum_mappings) mappings; side_ptr_t(const struct side_type) elem_type; } SIDE_PACKED; +side_check_size(struct side_type_enum, 32); struct side_type_enum_bitmap { side_ptr_t(const struct side_enum_bitmap_mappings) mappings; side_ptr_t(const struct side_type) elem_type; } SIDE_PACKED; +side_check_size(struct side_type_enum_bitmap, 32); struct side_type_gather_bool { uint64_t offset; /* bytes */ + uint16_t offset_bits; /* bits */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_bool type; - uint16_t offset_bits; /* bits */ } SIDE_PACKED; +side_check_size(struct side_type_gather_bool, 11 + sizeof(struct side_type_bool)); struct side_type_gather_byte { uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_byte type; } SIDE_PACKED; +side_check_size(struct side_type_gather_byte, 9 + sizeof(struct side_type_byte)); struct side_type_gather_integer { uint64_t offset; /* bytes */ + uint16_t offset_bits; /* bits */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_integer type; - uint16_t offset_bits; /* bits */ } SIDE_PACKED; +side_check_size(struct side_type_gather_integer, 11 + sizeof(struct side_type_integer)); struct side_type_gather_float { uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_float type; } SIDE_PACKED; +side_check_size(struct side_type_gather_float, 9 + sizeof(struct side_type_float)); struct side_type_gather_string { uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_string type; } SIDE_PACKED; +side_check_size(struct side_type_gather_string, 9 + sizeof(struct side_type_string)); struct side_type_gather_enum { side_ptr_t(const struct side_enum_mappings) mappings; side_ptr_t(const struct side_type) elem_type; } SIDE_PACKED; +side_check_size(struct side_type_gather_enum, 32); struct side_type_gather_struct { + side_ptr_t(const struct side_type_struct) type; uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ - side_ptr_t(const struct side_type_struct) type; uint32_t size; /* bytes */ } SIDE_PACKED; +side_check_size(struct side_type_gather_struct, 29); struct side_type_gather_array { uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_array type; } SIDE_PACKED; +side_check_size(struct side_type_gather_array, 9 + sizeof(struct side_type_array)); struct side_type_gather_vla { side_ptr_t(const struct side_type) length_type; /* side_length() */ - uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ struct side_type_vla type; } SIDE_PACKED; +side_check_size(struct side_type_gather_vla, 25 + sizeof(struct side_type_vla)); struct side_type_gather { union { @@ -457,11 +520,13 @@ struct side_type_gather { struct side_type_gather_array side_array; struct side_type_gather_vla side_vla; struct side_type_gather_struct side_struct; + side_padding(61); } SIDE_PACKED u; } SIDE_PACKED; +side_check_size(struct side_type_gather, 61); struct side_type { - side_enum_t(enum side_type_label, uint32_t) type; + side_enum_t(enum side_type_label, uint16_t) type; union { /* Stack-copy basic types */ struct side_type_null side_null; @@ -484,45 +549,37 @@ struct side_type { /* Gather types */ struct side_type_gather side_gather; + side_padding(62); } SIDE_PACKED u; } SIDE_PACKED; +side_check_size(struct side_type, 64); struct side_variant_option { int64_t range_begin; int64_t range_end; const struct side_type side_type; } SIDE_PACKED; +side_check_size(struct side_variant_option, 16 + sizeof(const struct side_type)); struct side_type_variant { - const struct side_type selector; side_ptr_t(const struct side_variant_option) options; side_ptr_t(const struct side_attr) attr; uint32_t nr_options; uint32_t nr_attr; + const struct side_type selector; } SIDE_PACKED; +side_check_size(struct side_type_variant, 40 + sizeof(const struct side_type)); struct side_event_field { side_ptr_t(const char) field_name; struct side_type side_type; } SIDE_PACKED; +side_check_size(struct side_event_field, 16 + sizeof(struct side_type)); enum side_event_flags { SIDE_EVENT_FLAG_VARIADIC = (1 << 0), }; -struct side_callback { - union { - void (*call)(const struct side_event_description *desc, - const struct side_arg_vec *side_arg_vec, - void *priv); - void (*call_variadic)(const struct side_event_description *desc, - const struct side_arg_vec *side_arg_vec, - const struct side_arg_dynamic_struct *var_struct, - void *priv); - } SIDE_PACKED u; - void *priv; -} SIDE_PACKED; - union side_arg_static { /* Stack-copy basic types */ union side_bool_value bool_value; @@ -552,7 +609,9 @@ union side_arg_static { side_ptr_t(const void) ptr; side_ptr_t(const void) length_ptr; } SIDE_PACKED side_vla_gather; + side_padding(32); } SIDE_PACKED; +side_check_size(union side_arg_static, 32); struct side_arg_dynamic_vla { side_ptr_t(const struct side_arg) sav; @@ -560,6 +619,7 @@ struct side_arg_dynamic_vla { uint32_t len; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_arg_dynamic_vla, 40); struct side_arg_dynamic_struct { side_ptr_t(const struct side_arg_dynamic_field) fields; @@ -567,20 +627,23 @@ struct side_arg_dynamic_struct { uint32_t len; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_arg_dynamic_struct, 40); struct side_dynamic_struct_visitor { - void *app_ctx; - side_dynamic_struct_visitor_func visitor; + side_func_ptr_t(side_dynamic_struct_visitor_func) visitor; + side_ptr_t(void) app_ctx; side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_dynamic_struct_visitor, 52); struct side_dynamic_vla_visitor { - void *app_ctx; - side_visitor_func visitor; + side_func_ptr_t(side_visitor_func) visitor; + side_ptr_t(void) app_ctx; side_ptr_t(const struct side_attr) attr; uint32_t nr_attr; } SIDE_PACKED; +side_check_size(struct side_dynamic_vla_visitor, 52); union side_arg_dynamic { /* Dynamic basic types */ @@ -612,45 +675,38 @@ union side_arg_dynamic { struct side_dynamic_struct_visitor side_dynamic_struct_visitor; struct side_dynamic_vla_visitor side_dynamic_vla_visitor; + + side_padding(58); } SIDE_PACKED; +side_check_size(union side_arg_dynamic, 58); struct side_arg { - side_enum_t(enum side_type_label, uint32_t) type; + side_enum_t(enum side_type_label, uint16_t) type; union { union side_arg_static side_static; union side_arg_dynamic side_dynamic; + side_padding(62); } SIDE_PACKED u; } SIDE_PACKED; +side_check_size(struct side_arg, 64); struct side_arg_variant { struct side_arg selector; struct side_arg option; } SIDE_PACKED; +side_check_size(struct side_arg_variant, 128); struct side_arg_vec { side_ptr_t(const struct side_arg) sav; uint32_t len; } SIDE_PACKED; +side_check_size(struct side_arg_vec, 20); struct side_arg_dynamic_field { side_ptr_t(const char) field_name; const struct side_arg elem; } SIDE_PACKED; - -/* The visitor pattern is a double-dispatch visitor. */ -struct side_tracer_visitor_ctx { - enum side_visitor_status (*write_elem)( - const struct side_tracer_visitor_ctx *tracer_ctx, - const struct side_arg *elem); - void *priv; /* Private tracer context. */ -} SIDE_PACKED; - -struct side_tracer_dynamic_struct_visitor_ctx { - enum side_visitor_status (*write_field)( - const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx, - const struct side_arg_dynamic_field *dynamic_field); - void *priv; /* Private tracer context. */ -} SIDE_PACKED; +side_check_size(struct side_arg_dynamic_field, 16 + sizeof(const struct side_arg)); struct side_event_description { side_ptr_t(struct side_event_state) state; @@ -1100,7 +1156,7 @@ struct side_event_state { .u = { \ .side_vla_visitor = { \ .elem_type = SIDE_PTR_INIT(_elem_type), \ - .visitor = _visitor, \ + .visitor = SIDE_PTR_INIT(_visitor), \ .attr = SIDE_PTR_INIT(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ }, \ @@ -1694,8 +1750,8 @@ struct side_event_state { .u = { \ .side_dynamic = { \ .side_dynamic_vla_visitor = { \ - .app_ctx = _ctx, \ - .visitor = _dynamic_vla_visitor, \ + .app_ctx = SIDE_PTR_INIT(_ctx), \ + .visitor = SIDE_PTR_INIT(_dynamic_vla_visitor), \ .attr = SIDE_PTR_INIT(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ }, \ @@ -1719,8 +1775,8 @@ struct side_event_state { .u = { \ .side_dynamic = { \ .side_dynamic_struct_visitor = { \ - .app_ctx = _ctx, \ - .visitor = _dynamic_struct_visitor, \ + .app_ctx = SIDE_PTR_INIT(_ctx), \ + .visitor = SIDE_PTR_INIT(_dynamic_struct_visitor), \ .attr = SIDE_PTR_INIT(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ }, \ @@ -1863,6 +1919,30 @@ struct side_event_state { extern "C" { #endif +struct side_callback { + union { + void (*call)(const struct side_event_description *desc, + const struct side_arg_vec *side_arg_vec, + void *priv); + void (*call_variadic)(const struct side_event_description *desc, + const struct side_arg_vec *side_arg_vec, + const struct side_arg_dynamic_struct *var_struct, + void *priv); + } SIDE_PACKED u; + void *priv; +} SIDE_PACKED; + +/* The visitor pattern is a double-dispatch visitor. */ +struct side_tracer_visitor_ctx { + side_write_elem_func write_elem; + void *priv; /* Private tracer context. */ +} SIDE_PACKED; + +struct side_tracer_dynamic_struct_visitor_ctx { + side_write_field_func write_field; + void *priv; /* Private tracer context. */ +} SIDE_PACKED; + extern const struct side_callback side_empty_callback; void side_call(const struct side_event_state *state, diff --git a/src/.tracer.c.swp b/src/.tracer.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..362d5e1be9cf0573ee3d1d72dfc1cc2d407b45c0 GIT binary patch literal 81920 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 G?f(KchcwXu literal 0 HcmV?d00001 diff --git a/src/tracer.c b/src/tracer.c index 486dc19..33c6990 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -1517,12 +1517,14 @@ void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx) .write_elem = tracer_write_elem_cb, .priv = &tracer_priv, }; + side_visitor_func func; print_attributes("attr", ":", side_ptr_get(type_desc->u.side_vla_visitor.attr), type_desc->u.side_vla_visitor.nr_attr); printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : ""); printf("elements: "); printf("[ "); - status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx); + func = side_ptr_get(type_desc->u.side_vla_visitor.visitor); + status = func(&tracer_ctx, app_ctx); switch (status) { case SIDE_VISITOR_STATUS_OK: break; @@ -1580,13 +1582,13 @@ void tracer_print_dynamic_struct_visitor(const struct side_arg *item) .write_field = tracer_dynamic_struct_write_elem_cb, .priv = &tracer_priv, }; - void *app_ctx = item->u.side_dynamic.side_dynamic_struct_visitor.app_ctx; + void *app_ctx = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.app_ctx); print_attributes("attr", "::", side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.attr), item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr); printf("%s", item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr ? ", " : ""); printf("fields:: "); printf("[ "); - status = item->u.side_dynamic.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx); + status = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.visitor)(&tracer_ctx, app_ctx); switch (status) { case SIDE_VISITOR_STATUS_OK: break; @@ -1642,13 +1644,13 @@ void tracer_print_dynamic_vla_visitor(const struct side_arg *item) .write_elem = tracer_dynamic_vla_write_elem_cb, .priv = &tracer_priv, }; - void *app_ctx = item->u.side_dynamic.side_dynamic_vla_visitor.app_ctx; + void *app_ctx = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.app_ctx); print_attributes("attr", "::", side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.attr), item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr); printf("%s", item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr ? ", " : ""); printf("elements:: "); printf("[ "); - status = item->u.side_dynamic.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx); + status = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.visitor)(&tracer_ctx, app_ctx); switch (status) { case SIDE_VISITOR_STATUS_OK: break; -- 2.34.1