X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=include%2Fside%2Ftrace.h;h=7f6f04e9fb1aab4e5f68d46b10869b19aace4d73;hb=f5e650d7ed962c334c835acfb47668fdc5dadcc0;hp=f09463d7f7e1bcd5ade93ea8a05b63bc46fad729;hpb=f7653b43159689efebb82efe25e327511964e076;p=libside.git diff --git a/include/side/trace.h b/include/side/trace.h index f09463d..7f6f04e 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -12,6 +12,7 @@ #include #include #include +#include /* SIDE stands for "Static Instrumentation Dynamically Enabled" */ @@ -30,6 +31,7 @@ struct side_tracer_dynamic_struct_visitor_ctx; struct side_tracer_dynamic_vla_visitor_ctx; struct side_event_description; struct side_arg_dynamic_event_struct; +struct side_events_register_handle; enum side_type { /* Basic types */ @@ -43,6 +45,7 @@ enum side_type { SIDE_TYPE_S32, SIDE_TYPE_S64, SIDE_TYPE_BYTE, + SIDE_TYPE_POINTER, SIDE_TYPE_FLOAT_BINARY16, SIDE_TYPE_FLOAT_BINARY32, SIDE_TYPE_FLOAT_BINARY64, @@ -64,6 +67,7 @@ enum side_type { SIDE_TYPE_ARRAY_S32, SIDE_TYPE_ARRAY_S64, SIDE_TYPE_ARRAY_BYTE, + SIDE_TYPE_ARRAY_POINTER, SIDE_TYPE_VLA_U8, SIDE_TYPE_VLA_U16, @@ -74,6 +78,7 @@ enum side_type { SIDE_TYPE_VLA_S32, SIDE_TYPE_VLA_S64, SIDE_TYPE_VLA_BYTE, + SIDE_TYPE_VLA_POINTER, /* Enumeration types */ SIDE_TYPE_ENUM, @@ -96,6 +101,7 @@ enum side_dynamic_type { SIDE_DYNAMIC_TYPE_S32, SIDE_DYNAMIC_TYPE_S64, SIDE_DYNAMIC_TYPE_BYTE, + SIDE_DYNAMIC_TYPE_POINTER, SIDE_DYNAMIC_TYPE_FLOAT_BINARY16, SIDE_DYNAMIC_TYPE_FLOAT_BINARY32, SIDE_DYNAMIC_TYPE_FLOAT_BINARY64, @@ -110,6 +116,7 @@ enum side_dynamic_type { }; enum side_attr_type { + SIDE_ATTR_TYPE_NULL, SIDE_ATTR_TYPE_BOOL, SIDE_ATTR_TYPE_U8, SIDE_ATTR_TYPE_U16, @@ -119,6 +126,7 @@ enum side_attr_type { SIDE_ATTR_TYPE_S16, SIDE_ATTR_TYPE_S32, SIDE_ATTR_TYPE_S64, + SIDE_ATTR_TYPE_POINTER, SIDE_ATTR_TYPE_FLOAT_BINARY16, SIDE_ATTR_TYPE_FLOAT_BINARY32, SIDE_ATTR_TYPE_FLOAT_BINARY64, @@ -142,6 +150,32 @@ enum side_visitor_status { SIDE_VISITOR_STATUS_ERROR = -1, }; +enum side_error { + SIDE_ERROR_OK = 0, + SIDE_ERROR_INVAL = 1, + SIDE_ERROR_EXIST = 2, + SIDE_ERROR_NOMEM = 3, + SIDE_ERROR_NOENT = 4, + SIDE_ERROR_EXITING = 5, +}; + +enum side_type_byte_order { + SIDE_TYPE_BYTE_ORDER_LE = 0, + SIDE_TYPE_BYTE_ORDER_BE = 1, +}; + +#if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN) +# define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE +#else +# define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE +#endif + +#if (SIDE_FLOAT_WORD_ORDER == SIDE_LITTLE_ENDIAN) +# define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE +#else +# define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE +#endif + typedef enum side_visitor_status (*side_visitor)( const struct side_tracer_visitor_ctx *tracer_ctx, void *app_ctx); @@ -164,6 +198,7 @@ struct side_attr_value { int16_t side_s16; int32_t side_s32; int64_t side_s64; + uintptr_t side_pointer; #if __HAVE_FLOAT16 _Float16 side_float_binary16; #endif @@ -200,8 +235,8 @@ struct side_enum_mappings { }; struct side_enum_bitmap_mapping { - int64_t range_begin; - int64_t range_end; + uint64_t range_begin; + uint64_t range_end; const char *label; }; @@ -226,6 +261,7 @@ struct side_type_description { struct { const struct side_attr *attr; uint32_t nr_attr; + uint32_t byte_order; /* enum side_type_byte_order */ } side_basic; /* Compound types */ @@ -282,24 +318,19 @@ struct side_callback { void *priv; }; -struct side_callbacks { - struct side_callback *cb; - uint32_t nr_cb; -}; - struct side_event_description { - uint32_t version; - uint32_t *enabled; - uint32_t loglevel; /* enum side_loglevel */ - uint32_t nr_fields; - uint32_t nr_attr; - uint32_t _unused; - uint64_t flags; + uintptr_t *enabled; const char *provider_name; const char *event_name; const struct side_event_field *fields; const struct side_attr *attr; - struct side_callbacks *callbacks; + const struct side_callback *callbacks; + uint64_t flags; + uint32_t version; + uint32_t loglevel; /* enum side_loglevel */ + uint32_t nr_fields; + uint32_t nr_attr; + uint32_t nr_callbacks; }; struct side_arg_dynamic_vec { @@ -309,6 +340,7 @@ struct side_arg_dynamic_vec { struct { const struct side_attr *attr; uint32_t nr_attr; + uint32_t byte_order; /* enum side_type_byte_order */ union { uint8_t side_bool; uint8_t side_u8; @@ -320,6 +352,7 @@ struct side_arg_dynamic_vec { int32_t side_s32; int64_t side_s64; uint8_t side_byte; + uintptr_t side_pointer; #if __HAVE_FLOAT16 _Float16 side_float_binary16; #endif @@ -387,6 +420,7 @@ struct side_arg_vec { int32_t side_s32; int64_t side_s64; uint8_t side_byte; + uintptr_t side_pointer; #if __HAVE_FLOAT16 _Float16 side_float_binary16; #endif @@ -455,6 +489,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_attr_list(...) \ SIDE_COMPOUND_LITERAL(const struct side_attr, __VA_ARGS__) +#define side_attr_null(_val) { .type = SIDE_ATTR_TYPE_NULL } #define side_attr_bool(_val) { .type = SIDE_ATTR_TYPE_BOOL, .u = { .side_bool = !!(_val) } } #define side_attr_u8(_val) { .type = SIDE_ATTR_TYPE_U8, .u = { .side_u8 = (_val) } } #define side_attr_u16(_val) { .type = SIDE_ATTR_TYPE_U16, .u = { .side_u16 = (_val) } } @@ -464,6 +499,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_attr_s16(_val) { .type = SIDE_ATTR_TYPE_S16, .u = { .side_s16 = (_val) } } #define side_attr_s32(_val) { .type = SIDE_ATTR_TYPE_S32, .u = { .side_s32 = (_val) } } #define side_attr_s64(_val) { .type = SIDE_ATTR_TYPE_S64, .u = { .side_s64 = (_val) } } +#define side_attr_pointer(_val) { .type = SIDE_ATTR_TYPE_POINTER, .u = { .side_pointer = (uintptr_t) (_val) } } #define side_attr_float_binary16(_val) { .type = SIDE_ATTR_TYPE_FLOAT_BINARY16, .u = { .side_float_binary16 = (_val) } } #define side_attr_float_binary32(_val) { .type = SIDE_ATTR_TYPE_FLOAT_BINARY32, .u = { .side_float_binary32 = (_val) } } #define side_attr_float_binary64(_val) { .type = SIDE_ATTR_TYPE_FLOAT_BINARY64, .u = { .side_float_binary64 = (_val) } } @@ -472,40 +508,43 @@ struct side_tracer_dynamic_vla_visitor_ctx { /* Static field definition */ -#define _side_type_basic(_type, _attr) \ +#define _side_type_basic(_type, _byte_order, _attr) \ { \ .type = _type, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ }, \ }, \ } -#define side_type_bool(_attr) _side_type_basic(SIDE_TYPE_BOOL, SIDE_PARAM(_attr)) -#define side_type_u8(_attr) _side_type_basic(SIDE_TYPE_U8, SIDE_PARAM(_attr)) -#define side_type_u16(_attr) _side_type_basic(SIDE_TYPE_U16, SIDE_PARAM(_attr)) -#define side_type_u32(_attr) _side_type_basic(SIDE_TYPE_U32, SIDE_PARAM(_attr)) -#define side_type_u64(_attr) _side_type_basic(SIDE_TYPE_U64, SIDE_PARAM(_attr)) -#define side_type_s8(_attr) _side_type_basic(SIDE_TYPE_S8, SIDE_PARAM(_attr)) -#define side_type_s16(_attr) _side_type_basic(SIDE_TYPE_S16, SIDE_PARAM(_attr)) -#define side_type_s32(_attr) _side_type_basic(SIDE_TYPE_S32, SIDE_PARAM(_attr)) -#define side_type_s64(_attr) _side_type_basic(SIDE_TYPE_S64, SIDE_PARAM(_attr)) -#define side_type_byte(_attr) _side_type_basic(SIDE_TYPE_BYTE, SIDE_PARAM(_attr)) -#define side_type_float_binary16(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY16, SIDE_PARAM(_attr)) -#define side_type_float_binary32(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY32, SIDE_PARAM(_attr)) -#define side_type_float_binary64(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY64, SIDE_PARAM(_attr)) -#define side_type_float_binary128(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY128, SIDE_PARAM(_attr)) -#define side_type_string(_attr) _side_type_basic(SIDE_TYPE_STRING, SIDE_PARAM(_attr)) -#define side_type_dynamic(_attr) _side_type_basic(SIDE_TYPE_DYNAMIC, SIDE_PARAM(_attr)) - #define _side_field(_name, _type) \ { \ .field_name = _name, \ .side_type = _type, \ } +/* Host endian */ +#define side_type_bool(_attr) _side_type_basic(SIDE_TYPE_BOOL, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_u8(_attr) _side_type_basic(SIDE_TYPE_U8, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_u16(_attr) _side_type_basic(SIDE_TYPE_U16, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_u32(_attr) _side_type_basic(SIDE_TYPE_U32, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_u64(_attr) _side_type_basic(SIDE_TYPE_U64, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_s8(_attr) _side_type_basic(SIDE_TYPE_S8, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_s16(_attr) _side_type_basic(SIDE_TYPE_S16, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_s32(_attr) _side_type_basic(SIDE_TYPE_S32, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_s64(_attr) _side_type_basic(SIDE_TYPE_S64, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_byte(_attr) _side_type_basic(SIDE_TYPE_BYTE, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_pointer(_attr) _side_type_basic(SIDE_TYPE_POINTER, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_float_binary16(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY16, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_float_binary32(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY32, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_float_binary64(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY64, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_float_binary128(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY128, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_string(_attr) _side_type_basic(SIDE_TYPE_STRING, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_type_dynamic(_attr) _side_type_basic(SIDE_TYPE_DYNAMIC, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) + #define side_field_bool(_name, _attr) _side_field(_name, side_type_bool(SIDE_PARAM(_attr))) #define side_field_u8(_name, _attr) _side_field(_name, side_type_u8(SIDE_PARAM(_attr))) #define side_field_u16(_name, _attr) _side_field(_name, side_type_u16(SIDE_PARAM(_attr))) @@ -516,6 +555,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_field_s32(_name, _attr) _side_field(_name, side_type_s32(SIDE_PARAM(_attr))) #define side_field_s64(_name, _attr) _side_field(_name, side_type_s64(SIDE_PARAM(_attr))) #define side_field_byte(_name, _attr) _side_field(_name, side_type_byte(SIDE_PARAM(_attr))) +#define side_field_pointer(_name, _attr) _side_field(_name, side_type_pointer(SIDE_PARAM(_attr))) #define side_field_float_binary16(_name, _attr) _side_field(_name, side_type_float_binary16(SIDE_PARAM(_attr))) #define side_field_float_binary32(_name, _attr) _side_field(_name, side_type_float_binary32(SIDE_PARAM(_attr))) #define side_field_float_binary64(_name, _attr) _side_field(_name, side_type_float_binary64(SIDE_PARAM(_attr))) @@ -523,6 +563,56 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_field_string(_name, _attr) _side_field(_name, side_type_string(SIDE_PARAM(_attr))) #define side_field_dynamic(_name, _attr) _side_field(_name, side_type_dynamic(SIDE_PARAM(_attr))) +/* Little endian */ +#define side_type_u16_le(_attr) _side_type_basic(SIDE_TYPE_U16, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_u32_le(_attr) _side_type_basic(SIDE_TYPE_U32, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_u64_le(_attr) _side_type_basic(SIDE_TYPE_U64, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_s16_le(_attr) _side_type_basic(SIDE_TYPE_S16, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_s32_le(_attr) _side_type_basic(SIDE_TYPE_S32, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_s64_le(_attr) _side_type_basic(SIDE_TYPE_S64, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_pointer_le(_attr) _side_type_basic(SIDE_TYPE_POINTER, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_float_binary16_le(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY16, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_float_binary32_le(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY32, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_float_binary64_le(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY64, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_type_float_binary128_le(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY128, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) + +#define side_field_u16_le(_name, _attr) _side_field(_name, side_type_u16_le(SIDE_PARAM(_attr))) +#define side_field_u32_le(_name, _attr) _side_field(_name, side_type_u32_le(SIDE_PARAM(_attr))) +#define side_field_u64_le(_name, _attr) _side_field(_name, side_type_u64_le(SIDE_PARAM(_attr))) +#define side_field_s16_le(_name, _attr) _side_field(_name, side_type_s16_le(SIDE_PARAM(_attr))) +#define side_field_s32_le(_name, _attr) _side_field(_name, side_type_s32_le(SIDE_PARAM(_attr))) +#define side_field_s64_le(_name, _attr) _side_field(_name, side_type_s64_le(SIDE_PARAM(_attr))) +#define side_field_pointer_le(_name, _attr) _side_field(_name, side_type_pointer_le(SIDE_PARAM(_attr))) +#define side_field_float_binary16_le(_name, _attr) _side_field(_name, side_type_float_binary16_le(SIDE_PARAM(_attr))) +#define side_field_float_binary32_le(_name, _attr) _side_field(_name, side_type_float_binary32_le(SIDE_PARAM(_attr))) +#define side_field_float_binary64_le(_name, _attr) _side_field(_name, side_type_float_binary64_le(SIDE_PARAM(_attr))) +#define side_field_float_binary128_le(_name, _attr) _side_field(_name, side_type_float_binary128_le(SIDE_PARAM(_attr))) + +/* Big endian */ +#define side_type_u16_be(_attr) _side_type_basic(SIDE_TYPE_U16, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_u32_be(_attr) _side_type_basic(SIDE_TYPE_U32, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_u64_be(_attr) _side_type_basic(SIDE_TYPE_U64, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_s16_be(_attr) _side_type_basic(SIDE_TYPE_S16, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_s32_be(_attr) _side_type_basic(SIDE_TYPE_S32, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_s64_be(_attr) _side_type_basic(SIDE_TYPE_S64, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_pointer_be(_attr) _side_type_basic(SIDE_TYPE_POINTER, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_float_binary16_be(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY16, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_float_binary32_be(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY32, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_float_binary64_be(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY64, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_type_float_binary128_be(_attr) _side_type_basic(SIDE_TYPE_FLOAT_BINARY128, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) + +#define side_field_u16_be(_name, _attr) _side_field(_name, side_type_u16_be(SIDE_PARAM(_attr))) +#define side_field_u32_be(_name, _attr) _side_field(_name, side_type_u32_be(SIDE_PARAM(_attr))) +#define side_field_u64_be(_name, _attr) _side_field(_name, side_type_u64_be(SIDE_PARAM(_attr))) +#define side_field_s16_be(_name, _attr) _side_field(_name, side_type_s16_be(SIDE_PARAM(_attr))) +#define side_field_s32_be(_name, _attr) _side_field(_name, side_type_s32_be(SIDE_PARAM(_attr))) +#define side_field_s64_be(_name, _attr) _side_field(_name, side_type_s64_be(SIDE_PARAM(_attr))) +#define side_field_pointer_be(_name, _attr) _side_field(_name, side_type_pointer_be(SIDE_PARAM(_attr))) +#define side_field_float_binary16_be(_name, _attr) _side_field(_name, side_type_float_binary16_be(SIDE_PARAM(_attr))) +#define side_field_float_binary32_be(_name, _attr) _side_field(_name, side_type_float_binary32_be(SIDE_PARAM(_attr))) +#define side_field_float_binary64_be(_name, _attr) _side_field(_name, side_type_float_binary64_be(SIDE_PARAM(_attr))) +#define side_field_float_binary128_be(_name, _attr) _side_field(_name, side_type_float_binary128_be(SIDE_PARAM(_attr))) + #define side_type_enum(_mappings, _elem_type) \ { \ .type = SIDE_TYPE_ENUM, \ @@ -636,6 +726,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_arg_s32(_val) { .type = SIDE_TYPE_S32, .u = { .side_s32 = (_val) } } #define side_arg_s64(_val) { .type = SIDE_TYPE_S64, .u = { .side_s64 = (_val) } } #define side_arg_byte(_val) { .type = SIDE_TYPE_BYTE, .u = { .side_byte = (_val) } } +#define side_arg_pointer(_val) { .type = SIDE_TYPE_POINTER, .u = { .side_pointer = (uintptr_t) (_val) } } #define side_arg_enum_bitmap8(_val) { .type = SIDE_TYPE_ENUM_BITMAP8, .u = { .side_u8 = (_val) } } #define side_arg_enum_bitmap16(_val) { .type = SIDE_TYPE_ENUM_BITMAP16, .u = { .side_u16 = (_val) } } #define side_arg_enum_bitmap32(_val) { .type = SIDE_TYPE_ENUM_BITMAP32, .u = { .side_u32 = (_val) } } @@ -662,6 +753,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_arg_array_s32(_ptr) { .type = SIDE_TYPE_ARRAY_S32, .u = { .side_array_fixint = (_ptr) } } #define side_arg_array_s64(_ptr) { .type = SIDE_TYPE_ARRAY_S64, .u = { .side_array_fixint = (_ptr) } } #define side_arg_array_byte(_ptr) { .type = SIDE_TYPE_ARRAY_BYTE, .u = { .side_array_fixint = (_ptr) } } +#define side_arg_array_pointer(_ptr) { .type = SIDE_TYPE_ARRAY_POINTER, .u = { .side_array_fixint = (_ptr) } } #define side_arg_vla_u8(_ptr, _length) { .type = SIDE_TYPE_VLA_U8, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } #define side_arg_vla_u16(_ptr, _length) { .type = SIDE_TYPE_VLA_U16, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } @@ -672,6 +764,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_arg_vla_s32(_ptr, _length) { .type = SIDE_TYPE_VLA_S32, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } #define side_arg_vla_s64(_ptr, _length) { .type = SIDE_TYPE_VLA_S64, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } #define side_arg_vla_byte(_ptr, _length) { .type = SIDE_TYPE_VLA_BYTE, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } +#define side_arg_vla_pointer(_ptr, _length) { .type = SIDE_TYPE_VLA_POINTER, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } #define side_arg_dynamic(_dynamic_arg_type) \ { \ @@ -690,6 +783,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ }, \ }, \ } @@ -701,6 +795,7 @@ struct side_tracer_dynamic_vla_visitor_ctx { .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ .u = { \ .side_bool = !!(_val), \ }, \ @@ -715,164 +810,205 @@ struct side_tracer_dynamic_vla_visitor_ctx { .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ .u = { \ .side_u8 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_u16(_val, _attr) \ +#define side_arg_dynamic_s8(_val, _attr) \ { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_U16, \ + .dynamic_type = SIDE_DYNAMIC_TYPE_S8, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ .u = { \ - .side_u16 = (_val), \ + .side_s8 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_u32(_val, _attr) \ +#define side_arg_dynamic_byte(_val, _attr) \ { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_U32, \ + .dynamic_type = SIDE_DYNAMIC_TYPE_BYTE, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ .u = { \ - .side_u32 = (_val), \ + .side_byte = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_u64(_val, _attr) \ +#define side_arg_dynamic_string(_val, _attr) \ { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_U64, \ + .dynamic_type = SIDE_DYNAMIC_TYPE_STRING, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = SIDE_TYPE_BYTE_ORDER_HOST, \ .u = { \ - .side_u64 = (_val), \ + .string = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_s8(_val, _attr) \ +#define _side_arg_dynamic_u16(_val, _byte_order, _attr) \ { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_S8, \ + .dynamic_type = SIDE_DYNAMIC_TYPE_U16, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ - .side_s8 = (_val), \ + .side_u16 = (_val), \ + }, \ + }, \ + }, \ + } +#define _side_arg_dynamic_u32(_val, _byte_order, _attr) \ + { \ + .dynamic_type = SIDE_DYNAMIC_TYPE_U32, \ + .u = { \ + .side_basic = { \ + .attr = _attr, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ + .u = { \ + .side_u32 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_s16(_val, _attr) \ +#define _side_arg_dynamic_u64(_val, _byte_order, _attr) \ + { \ + .dynamic_type = SIDE_DYNAMIC_TYPE_U64, \ + .u = { \ + .side_basic = { \ + .attr = _attr, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ + .u = { \ + .side_u64 = (_val), \ + }, \ + }, \ + }, \ + } + +#define _side_arg_dynamic_s16(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_S16, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_s16 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_s32(_val, _attr) \ +#define _side_arg_dynamic_s32(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_S32, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_s32 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_s64(_val, _attr) \ +#define _side_arg_dynamic_s64(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_S64, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_s64 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_byte(_val, _attr) \ +#define _side_arg_dynamic_pointer(_val, _byte_order, _attr) \ { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_BYTE, \ + .dynamic_type = SIDE_DYNAMIC_TYPE_POINTER, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ - .side_byte = (_val), \ + .side_pointer = (uintptr_t) (_val), \ }, \ }, \ }, \ } - -#define side_arg_dynamic_float_binary16(_val, _attr) \ +#define _side_arg_dynamic_float_binary16(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_FLOAT_BINARY16, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_float_binary16 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_float_binary32(_val, _attr) \ +#define _side_arg_dynamic_float_binary32(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_FLOAT_BINARY32, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_float_binary32 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_float_binary64(_val, _attr) \ +#define _side_arg_dynamic_float_binary64(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_FLOAT_BINARY64, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_float_binary64 = (_val), \ }, \ }, \ }, \ } -#define side_arg_dynamic_float_binary128(_val, _attr) \ +#define _side_arg_dynamic_float_binary128(_val, _byte_order, _attr) \ { \ .dynamic_type = SIDE_DYNAMIC_TYPE_FLOAT_BINARY128, \ .u = { \ .side_basic = { \ .attr = _attr, \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .byte_order = _byte_order, \ .u = { \ .side_float_binary128 = (_val), \ }, \ @@ -880,19 +1016,44 @@ struct side_tracer_dynamic_vla_visitor_ctx { }, \ } -#define side_arg_dynamic_string(_val, _attr) \ - { \ - .dynamic_type = SIDE_DYNAMIC_TYPE_STRING, \ - .u = { \ - .side_basic = { \ - .attr = _attr, \ - .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ - .u = { \ - .string = (_val), \ - }, \ - }, \ - }, \ - } +/* Host endian */ +#define side_arg_dynamic_u16(_val, _attr) _side_arg_dynamic_u16(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u32(_val, _attr) _side_arg_dynamic_u32(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u64(_val, _attr) _side_arg_dynamic_u64(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s16(_val, _attr) _side_arg_dynamic_s16(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s32(_val, _attr) _side_arg_dynamic_s32(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s64(_val, _attr) _side_arg_dynamic_s64(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_pointer(_val, _attr) _side_arg_dynamic_pointer(_val, SIDE_TYPE_BYTE_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary16(_val, _attr) _side_arg_dynamic_float_binary16(_val, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary32(_val, _attr) _side_arg_dynamic_float_binary32(_val, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary64(_val, _attr) _side_arg_dynamic_float_binary64(_val, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary128(_val, _attr) _side_arg_dynamic_float_binary128(_val, SIDE_TYPE_FLOAT_WORD_ORDER_HOST, SIDE_PARAM(_attr)) + +/* Little endian */ +#define side_arg_dynamic_u16_le(_val, _attr) _side_arg_dynamic_u16(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u32_le(_val, _attr) _side_arg_dynamic_u32(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u64_le(_val, _attr) _side_arg_dynamic_u64(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s16_le(_val, _attr) _side_arg_dynamic_s16(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s32_le(_val, _attr) _side_arg_dynamic_s32(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s64_le(_val, _attr) _side_arg_dynamic_s64(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_pointer_le(_val, _attr) _side_arg_dynamic_pointer(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary16_le(_val, _attr) _side_arg_dynamic_float_binary16(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary32_le(_val, _attr) _side_arg_dynamic_float_binary32(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary64_le(_val, _attr) _side_arg_dynamic_float_binary64(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary128_le(_val, _attr) _side_arg_dynamic_float_binary128(_val, SIDE_TYPE_BYTE_ORDER_LE, SIDE_PARAM(_attr)) + +/* Big endian */ +#define side_arg_dynamic_u16_be(_val, _attr) _side_arg_dynamic_u16(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u32_be(_val, _attr) _side_arg_dynamic_u32(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_u64_be(_val, _attr) _side_arg_dynamic_u64(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s16_be(_val, _attr) _side_arg_dynamic_s16(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s32_be(_val, _attr) _side_arg_dynamic_s32(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_s64_be(_val, _attr) _side_arg_dynamic_s64(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_pointer_be(_val, _attr) _side_arg_dynamic_pointer(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary16_be(_val, _attr) _side_arg_dynamic_float_binary16(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary32_be(_val, _attr) _side_arg_dynamic_float_binary32(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary64_be(_val, _attr) _side_arg_dynamic_float_binary64(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) +#define side_arg_dynamic_float_binary128_be(_val, _attr) _side_arg_dynamic_float_binary128(_val, SIDE_TYPE_BYTE_ORDER_BE, SIDE_PARAM(_attr)) #define side_arg_dynamic_vla(_vla) \ { \ @@ -1019,23 +1180,25 @@ struct side_tracer_dynamic_vla_visitor_ctx { .label = _label, \ } -#define side_event_cond(_desc) if (side_unlikely(_desc##_enabled)) +#define side_event_cond(_identifier) \ + if (side_unlikely(__atomic_load_n(&side_event_enable__##_identifier, \ + __ATOMIC_RELAXED))) -#define side_event_call(_desc, _sav) \ +#define side_event_call(_identifier, _sav) \ { \ const struct side_arg_vec side_sav[] = { _sav }; \ const struct side_arg_vec_description sav_desc = { \ .sav = side_sav, \ .len = SIDE_ARRAY_SIZE(side_sav), \ }; \ - side_call(&(_desc), &sav_desc); \ + side_call(&(_identifier), &sav_desc); \ } -#define side_event(_desc, _sav) \ - side_event_cond(_desc) \ - side_event_call(_desc, SIDE_PARAM(_sav)) +#define side_event(_identifier, _sav) \ + side_event_cond(_identifier) \ + side_event_call(_identifier, SIDE_PARAM(_sav)) -#define side_event_call_variadic(_desc, _sav, _var_fields, _attr) \ +#define side_event_call_variadic(_identifier, _sav, _var_fields, _attr) \ { \ const struct side_arg_vec side_sav[] = { _sav }; \ const struct side_arg_vec_description sav_desc = { \ @@ -1049,42 +1212,62 @@ struct side_tracer_dynamic_vla_visitor_ctx { .len = SIDE_ARRAY_SIZE(side_fields), \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ }; \ - side_call_variadic(&(_desc), &sav_desc, &var_struct); \ + side_call_variadic(&(_identifier), &sav_desc, &var_struct); \ } -#define side_event_variadic(_desc, _sav, _var, _attr) \ - side_event_cond(_desc) \ - side_event_call_variadic(_desc, SIDE_PARAM(_sav), SIDE_PARAM(_var), SIDE_PARAM(_attr)) +#define side_event_variadic(_identifier, _sav, _var, _attr) \ + side_event_cond(_identifier) \ + side_event_call_variadic(_identifier, SIDE_PARAM(_sav), SIDE_PARAM(_var), SIDE_PARAM(_attr)) -#define _side_define_event(_identifier, _provider, _event, _loglevel, _fields, _attr, _flags) \ - uint32_t _identifier##_enabled __attribute__((section("side_event_enable"))); \ - struct side_callbacks _identifier##_callbacks __attribute__((section("side_event_callbacks"))); \ - const struct side_event_description _identifier = { \ +#define _side_define_event(_linkage, _identifier, _provider, _event, _loglevel, _fields, _attr, _flags) \ + _linkage uintptr_t side_event_enable__##_identifier __attribute__((section("side_event_enable"))); \ + _linkage struct side_event_description __attribute__((section("side_event_description"))) \ + _identifier = { \ .version = 0, \ - .enabled = &(_identifier##_enabled), \ + .enabled = &(side_event_enable__##_identifier), \ .loglevel = _loglevel, \ .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .nr_callbacks = 0, \ .flags = (_flags), \ .provider_name = _provider, \ .event_name = _event, \ .fields = _fields, \ .attr = _attr, \ - .callbacks = &(_identifier##_callbacks), \ + .callbacks = &side_empty_callback, \ }; \ - const struct side_event_description *_identifier##_ptr \ - __attribute__((section("side_event_description"), used)) = &(_identifier); + static const struct side_event_description *side_event_ptr__##_identifier \ + __attribute__((section("side_event_description_ptr"), used)) = &(_identifier); -#define side_define_event(_identifier, _provider, _event, _loglevel, _fields, _attr) \ - _side_define_event(_identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ +#define side_static_event(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(static, _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ SIDE_PARAM(_attr), 0) -#define side_define_event_variadic(_identifier, _provider, _event, _loglevel, _fields, _attr) \ - _side_define_event(_identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ +#define side_static_event_variadic(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(static, _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ + SIDE_PARAM(_attr), SIDE_EVENT_FLAG_VARIADIC) + +#define side_hidden_event(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(__attribute__((visibility("hidden"))), _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ + SIDE_PARAM(_attr), 0) + +#define side_hidden_event_variadic(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(__attribute__((visibility("hidden"))), _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ + SIDE_PARAM(_attr), SIDE_EVENT_FLAG_VARIADIC) + +#define side_export_event(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(__attribute__((visibility("default"))), _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ + SIDE_PARAM(_attr), 0) + +#define side_export_event_variadic(_identifier, _provider, _event, _loglevel, _fields, _attr) \ + _side_define_event(__attribute__((visibility("default"))), _identifier, _provider, _event, _loglevel, SIDE_PARAM(_fields), \ SIDE_PARAM(_attr), SIDE_EVENT_FLAG_VARIADIC) #define side_declare_event(_identifier) \ - struct side_event_description _identifier + extern uintptr_t side_event_enable_##_identifier; \ + extern struct side_event_description _identifier + +extern const struct side_callback side_empty_callback; void side_call(const struct side_event_description *desc, const struct side_arg_vec_description *sav_desc); @@ -1092,4 +1275,85 @@ void side_call_variadic(const struct side_event_description *desc, const struct side_arg_vec_description *sav_desc, const struct side_arg_dynamic_event_struct *var_struct); +int side_tracer_callback_register(struct side_event_description *desc, + void (*call)(const struct side_event_description *desc, + const struct side_arg_vec_description *sav_desc, + void *priv), + void *priv); +int side_tracer_callback_variadic_register(struct side_event_description *desc, + void (*call_variadic)(const struct side_event_description *desc, + const struct side_arg_vec_description *sav_desc, + const struct side_arg_dynamic_event_struct *var_struct, + void *priv), + void *priv); +int side_tracer_callback_unregister(struct side_event_description *desc, + void (*call)(const struct side_event_description *desc, + const struct side_arg_vec_description *sav_desc, + void *priv), + void *priv); +int side_tracer_callback_variadic_unregister(struct side_event_description *desc, + void (*call_variadic)(const struct side_event_description *desc, + const struct side_arg_vec_description *sav_desc, + const struct side_arg_dynamic_event_struct *var_struct, + void *priv), + void *priv); + +struct side_events_register_handle *side_events_register(struct side_event_description **events, uint32_t nr_events); +void side_events_unregister(struct side_events_register_handle *handle); + +enum side_tracer_notification { + SIDE_TRACER_NOTIFICATION_INSERT_EVENTS, + SIDE_TRACER_NOTIFICATION_REMOVE_EVENTS, +}; + +/* Callback is invoked with side library internal lock held. */ +struct side_tracer_handle *side_tracer_event_notification_register( + void (*cb)(enum side_tracer_notification notif, + struct side_event_description **events, uint32_t nr_events, void *priv), + void *priv); +void side_tracer_event_notification_unregister(struct side_tracer_handle *handle); + +void side_init(void); +void side_exit(void); + +/* + * These weak symbols, the constructor, and destructor take care of + * registering only _one_ instance of the side instrumentation per + * shared-ojbect (or for the whole main program). + */ +extern struct side_event_description * __start_side_event_description_ptr[] + __attribute__((weak, visibility("hidden"))); +extern struct side_event_description * __stop_side_event_description_ptr[] + __attribute__((weak, visibility("hidden"))); +int side_event_description_ptr_registered + __attribute__((weak, visibility("hidden"))); +struct side_events_register_handle *side_events_handle + __attribute__((weak, visibility("hidden"))); + +static void +side_event_description_ptr_init(void) + __attribute__((no_instrument_function)) + __attribute__((constructor)); +static void +side_event_description_ptr_init(void) +{ + if (side_event_description_ptr_registered++) + return; + side_events_handle = side_events_register(__start_side_event_description_ptr, + __stop_side_event_description_ptr - __start_side_event_description_ptr); +} + +static void +side_event_description_ptr_exit(void) + __attribute__((no_instrument_function)) + __attribute__((destructor)); +static void +side_event_description_ptr_exit(void) +{ + if (--side_event_description_ptr_registered) + return; + side_events_unregister(side_events_handle); + side_events_handle = NULL; +} + #endif /* _SIDE_TRACE_H */