Implement variant type
[libside.git] / include / side / trace.h
index 2c2ab0822ba0d28efe655098b2f1279ba552634d..e341047af5a14fcf9d8ec4194d779d8e4867edb5 100644 (file)
@@ -15,7 +15,7 @@
 #include <side/endian.h>
 
 /*
- * SIDE stands for "Static Instrumentation Dynamically Enabled"
+ * SIDE stands for "Software Instrumentation Dynamically Enabled"
  *
  * This is an instrumentation API for Linux user-space, which exposes an
  * instrumentation type system and facilities allowing a kernel or
@@ -82,6 +82,7 @@ struct side_tracer_dynamic_struct_visitor_ctx;
 struct side_event_description;
 struct side_arg_dynamic_struct;
 struct side_events_register_handle;
+struct side_arg_variant;
 
 enum side_type_label {
        /* Stack-copy basic types */
@@ -107,6 +108,7 @@ enum side_type_label {
 
        /* Stack-copy compound types */
        SIDE_TYPE_STRUCT,
+       SIDE_TYPE_VARIANT,
        SIDE_TYPE_ARRAY,
        SIDE_TYPE_VLA,
        SIDE_TYPE_VLA_VISITOR,
@@ -165,9 +167,7 @@ enum side_attr_type {
        SIDE_ATTR_TYPE_FLOAT_BINARY32,
        SIDE_ATTR_TYPE_FLOAT_BINARY64,
        SIDE_ATTR_TYPE_FLOAT_BINARY128,
-       SIDE_ATTR_TYPE_STRING_UTF8,
-       SIDE_ATTR_TYPE_STRING_UTF16,
-       SIDE_ATTR_TYPE_STRING_UTF32,
+       SIDE_ATTR_TYPE_STRING,
 };
 
 enum side_loglevel {
@@ -258,22 +258,22 @@ union side_float_value {
 #endif
 } SIDE_PACKED;
 
+struct side_type_raw_string {
+       const void *p;                  /* pointer to string */
+       uint8_t unit_size;              /* 1, 2, or 4 bytes */
+       uint8_t byte_order;             /* enum side_type_label_byte_order */
+} SIDE_PACKED;
+
 struct side_attr_value {
        uint32_t type;  /* enum side_attr_type */
        union {
                uint8_t bool_value;
-               uint64_t string_value;  /* const { uint8_t, uint16_t, uint32_t } * */
+               struct side_type_raw_string string_value;
                union side_integer_value integer_value;
                union side_float_value float_value;
        } SIDE_PACKED u;
 };
 
-struct side_type_raw_string {
-       const void *p;                  /* pointer to string */
-       uint8_t unit_size;              /* 1, 2, or 4 bytes */
-       uint8_t byte_order;             /* enum side_type_label_byte_order */
-} SIDE_PACKED;
-
 /* User attributes. */
 struct side_attr {
        const struct side_type_raw_string key;
@@ -473,6 +473,7 @@ struct side_type {
                struct side_type_vla side_vla;
                struct side_type_vla_visitor side_vla_visitor;
                const struct side_type_struct *side_struct;
+               const struct side_type_variant *side_variant;
 
                /* Stack-copy enumeration types */
                struct side_type_enum side_enum;
@@ -483,6 +484,20 @@ struct side_type {
        } SIDE_PACKED u;
 } SIDE_PACKED;
 
+struct side_variant_option {
+       int64_t range_begin;
+       int64_t range_end;
+       const struct side_type side_type;
+} SIDE_PACKED;
+
+struct side_type_variant {
+       const struct side_type selector;
+       const struct side_variant_option *options;
+       const struct side_attr *attr;
+       uint32_t nr_options;
+       uint32_t nr_attr;
+} SIDE_PACKED;
+
 struct side_event_field {
        const char *field_name;
        struct side_type side_type;
@@ -515,23 +530,24 @@ struct side_arg_static {
 
        /* Stack-copy compound types */
        const struct side_arg_vec *side_struct;
+       const struct side_arg_variant *side_variant;
        const struct side_arg_vec *side_array;
        const struct side_arg_vec *side_vla;
        void *side_vla_app_visitor_ctx;
 
        /* Gather basic types */
-       void *side_bool_gather_ptr;
-       void *side_byte_gather_ptr;
-       void *side_integer_gather_ptr;
-       void *side_float_gather_ptr;
-       void *side_string_gather_ptr;
+       const void *side_bool_gather_ptr;
+       const void *side_byte_gather_ptr;
+       const void *side_integer_gather_ptr;
+       const void *side_float_gather_ptr;
+       const void *side_string_gather_ptr;
 
        /* Gather compound types */
-       void *side_array_gather_ptr;
-       void *side_struct_gather_ptr;
+       const void *side_array_gather_ptr;
+       const void *side_struct_gather_ptr;
        struct {
-               void *ptr;
-               void *length_ptr;
+               const void *ptr;
+               const void *length_ptr;
        } SIDE_PACKED side_vla_gather;
 } SIDE_PACKED;
 
@@ -603,6 +619,11 @@ struct side_arg {
        } SIDE_PACKED u;
 } SIDE_PACKED;
 
+struct side_arg_variant {
+       struct side_arg selector;
+       struct side_arg option;
+} SIDE_PACKED;
+
 struct side_arg_vec {
        const struct side_arg *sav;
        uint32_t len;
@@ -672,9 +693,22 @@ struct side_event_description {
 #define side_attr_float_binary32(_val) { .type = SIDE_ATTR_TYPE_FLOAT_BINARY32, .u = { .float_value = { .side_float_binary32 = (_val) } } }
 #define side_attr_float_binary64(_val) { .type = SIDE_ATTR_TYPE_FLOAT_BINARY64, .u = { .float_value = { .side_float_binary64 = (_val) } } }
 #define side_attr_float_binary128(_val)        { .type = SIDE_ATTR_TYPE_FLOAT_BINARY128, .u = { .float_value = { .side_float_binary128 = (_val) } } }
-#define side_attr_string(_val)         { .type = SIDE_ATTR_TYPE_STRING_UTF8, .u = { .string_value = (uintptr_t) (_val) } }
-#define side_attr_string16(_val)       { .type = SIDE_ATTR_TYPE_STRING_UTF16, .u = { .string_value = (uintptr_t) (_val) } }
-#define side_attr_string32(_val)       { .type = SIDE_ATTR_TYPE_STRING_UTF32, .u = { .string_value = (uintptr_t) (_val) } }
+
+#define _side_attr_string(_val, _byte_order, _unit_size) \
+       { \
+               .type = SIDE_ATTR_TYPE_STRING, \
+               .u = { \
+                       .string_value = { \
+                               .p = (const void *) (_val), \
+                               .unit_size = _unit_size, \
+                               .byte_order = _byte_order, \
+                       }, \
+               }, \
+       }
+
+#define side_attr_string(_val)         _side_attr_string(_val, SIDE_TYPE_BYTE_ORDER_HOST, sizeof(uint8_t))
+#define side_attr_string16(_val)       _side_attr_string(_val, SIDE_TYPE_BYTE_ORDER_HOST, sizeof(uint16_t))
+#define side_attr_string32(_val)       _side_attr_string(_val, SIDE_TYPE_BYTE_ORDER_HOST, sizeof(uint32_t))
 
 /* Stack-copy enumeration type definitions */
 
@@ -834,6 +868,16 @@ struct side_event_description {
                .side_type = _type, \
        }
 
+#define side_option_range(_range_begin, _range_end, _type) \
+       { \
+               .range_begin = _range_begin, \
+               .range_end = _range_end, \
+               .side_type = _type, \
+       }
+
+#define side_option(_value, _type) \
+       side_option_range(_value, _value, SIDE_PARAM(_type))
+
 /* Host endian */
 #define side_type_u8(_attr)                            _side_type_integer(SIDE_TYPE_U8, false, SIDE_TYPE_BYTE_ORDER_HOST, sizeof(uint8_t), 0, SIDE_PARAM(_attr))
 #define side_type_u16(_attr)                           _side_type_integer(SIDE_TYPE_U16, false, SIDE_TYPE_BYTE_ORDER_HOST, sizeof(uint16_t), 0, SIDE_PARAM(_attr))
@@ -982,6 +1026,33 @@ struct side_event_description {
        SIDE_COMPOUND_LITERAL(const struct side_type_struct, \
                _side_type_struct_define(SIDE_PARAM(_fields), SIDE_PARAM(_attr)))
 
+#define side_type_variant(_variant) \
+       { \
+               .type = SIDE_TYPE_VARIANT, \
+               .u = { \
+                       .side_variant = _variant, \
+               }, \
+       }
+#define side_field_variant(_name, _variant) \
+       _side_field(_name, side_type_variant(SIDE_PARAM(_variant)))
+
+#define _side_type_variant_define(_selector, _options, _attr) \
+       { \
+               .selector = _selector, \
+               .options = _options, \
+               .attr = _attr, \
+               .nr_options = SIDE_ARRAY_SIZE(SIDE_PARAM(_options)), \
+               .nr_attr  = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+       }
+
+#define side_define_variant(_identifier, _selector, _options, _attr) \
+       const struct side_type_variant _identifier = \
+               _side_type_variant_define(SIDE_PARAM(_selector), SIDE_PARAM(_options), SIDE_PARAM(_attr))
+
+#define side_variant_literal(_selector, _options, _attr) \
+       SIDE_COMPOUND_LITERAL(const struct side_type_variant, \
+               _side_type_variant_define(SIDE_PARAM(_selector), SIDE_PARAM(_options), SIDE_PARAM(_attr)))
+
 #define side_type_array(_elem_type, _length, _attr) \
        { \
                .type = SIDE_TYPE_ARRAY, \
@@ -1339,6 +1410,9 @@ struct side_event_description {
 #define side_field_list(...) \
        SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
 
+#define side_option_list(...) \
+       SIDE_COMPOUND_LITERAL(const struct side_variant_option, __VA_ARGS__)
+
 /* Stack-copy field arguments */
 
 #define side_arg_null(_val)            { .type = SIDE_TYPE_NULL }
@@ -1363,6 +1437,22 @@ struct side_event_description {
 #define side_arg_float_binary128(_val) { .type = SIDE_TYPE_FLOAT_BINARY128, .u = { .side_static = { .float_value = { .side_float_binary128 = (_val) } } } }
 
 #define side_arg_struct(_side_type)    { .type = SIDE_TYPE_STRUCT, .u = { .side_static = { .side_struct = (_side_type) } } }
+
+#define side_arg_define_variant(_identifier, _selector_val, _option) \
+       const struct side_arg_variant _identifier = { \
+               .selector = _selector_val, \
+               .option = _option, \
+       }
+#define side_arg_variant(_side_variant) \
+       { \
+               .type = SIDE_TYPE_VARIANT, \
+               .u = { \
+                       .side_static = { \
+                               .side_variant = (_side_variant), \
+                       }, \
+               }, \
+       }
+
 #define side_arg_array(_side_type)     { .type = SIDE_TYPE_ARRAY, .u = { .side_static = { .side_array = (_side_type) } } }
 #define side_arg_vla(_side_type)       { .type = SIDE_TYPE_VLA, .u = { .side_static = { .side_vla = (_side_type) } } }
 #define side_arg_vla_visitor(_ctx)     { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_static = { .side_vla_app_visitor_ctx = (_ctx) } } }
@@ -1809,8 +1899,8 @@ void side_tracer_event_notification_unregister(struct side_tracer_handle *handle
  * Explicit hooks to initialize/finalize the side instrumentation
  * library. Those are also library constructor/destructor.
  */
-void side_init(void);
-void side_exit(void);
+void side_init(void) __attribute__((constructor));
+void side_exit(void) __attribute__((destructor));
 
 /*
  * The following constructors/destructors perform automatic registration
This page took 0.027096 seconds and 4 git commands to generate.