From 0519cb863b4ef058b09ca0653ac8218a56022ab0 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 9 Nov 2022 16:08:40 -0500 Subject: [PATCH] Implement gather enum Signed-off-by: Mathieu Desnoyers --- include/side/trace.h | 22 ++++++++++++ src/test.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/tracer.c | 80 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 171 insertions(+), 12 deletions(-) diff --git a/include/side/trace.h b/include/side/trace.h index 65892d7..5c182ac 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -128,6 +128,9 @@ enum side_type_label { SIDE_TYPE_GATHER_ARRAY, SIDE_TYPE_GATHER_VLA, + /* Gather enumeration types */ + SIDE_TYPE_GATHER_ENUM, + /* Dynamic basic types */ SIDE_TYPE_DYNAMIC_NULL, SIDE_TYPE_DYNAMIC_BOOL, @@ -395,6 +398,11 @@ struct side_type_gather_float { struct side_type_float type; } SIDE_PACKED; +struct side_type_gather_enum { + const struct side_enum_mappings *mappings; + const struct side_type *elem_type; +} SIDE_PACKED; + struct side_type_gather_struct { uint64_t offset; /* bytes */ uint8_t access_mode; /* enum side_type_gather_access_mode */ @@ -422,6 +430,7 @@ struct side_type_gather { struct side_type_gather_byte side_byte; struct side_type_gather_integer side_integer; struct side_type_gather_float side_float; + struct side_type_gather_enum side_enum; struct side_type_gather_array side_array; struct side_type_gather_vla side_vla; struct side_type_gather_struct side_struct; @@ -1132,6 +1141,19 @@ struct side_event_description { #define side_field_gather_float_be(_name, _offset, _float_size, _access_mode, _attr) \ _side_field(_name, side_type_gather_float_be(_offset, _float_size, _access_mode, _attr)) +#define side_type_gather_enum(_mappings, _elem_type) \ + { \ + .type = SIDE_TYPE_GATHER_ENUM, \ + .u = { \ + .side_enum = { \ + .mappings = _mappings, \ + .elem_type = _elem_type, \ + }, \ + }, \ + } +#define side_field_gather_enum(_name, _mappings, _elem_type) \ + _side_field(_name, side_type_gather_enum(SIDE_PARAM(_mappings), SIDE_PARAM(_elem_type))) + #define side_type_gather_struct(_struct_gather, _offset, _size, _access_mode) \ { \ .type = SIDE_TYPE_GATHER_STRUCT, \ diff --git a/src/test.c b/src/test.c index 42716d7..ee74e3c 100644 --- a/src/test.c +++ b/src/test.c @@ -2038,6 +2038,86 @@ void test_gather_pointer(void) ); } } + +static side_define_enum(myenumgather, + side_enum_mapping_list( + side_enum_mapping_range("one-ten", 1, 10), + side_enum_mapping_range("100-200", 100, 200), + side_enum_mapping_value("200", 200), + side_enum_mapping_value("300", 300), + ), + side_attr_list() +); + +side_static_event(my_provider_event_enum_gather, "myprovider", "myeventenumgather", SIDE_LOGLEVEL_DEBUG, + side_field_list( + side_field_gather_enum("5", &myenumgather, + side_elem( + side_type_gather_unsigned_integer(0, sizeof(uint32_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + side_field_gather_enum("400", &myenumgather, + side_elem( + side_type_gather_unsigned_integer(0, sizeof(uint64_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + side_field_gather_enum("200", &myenumgather, + side_elem( + side_type_gather_unsigned_integer(0, sizeof(uint8_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + side_field_gather_enum("-100", &myenumgather, + side_elem( + side_type_gather_signed_integer(0, sizeof(int8_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + side_field_gather_enum("6_be", &myenumgather, + side_elem( + side_type_gather_unsigned_integer_be(0, sizeof(uint32_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + side_field_gather_enum("6_le", &myenumgather, + side_elem( + side_type_gather_unsigned_integer_le(0, sizeof(uint32_t), 0, 0, + SIDE_TYPE_GATHER_ACCESS_DIRECT, side_attr_list()) + ) + ), + ), + side_attr_list() +); + +static +void test_gather_enum(void) +{ + uint32_t v1 = 5; + uint64_t v2 = 400; + uint8_t v3 = 200; + int8_t v4 = -100; +#if SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN + uint32_t v5 = side_bswap_32(6); + uint32_t v6 = 6; +#else + uint32_t v5 = 6; + uint32_t v6 = side_bswap_32(6); +#endif + + side_event(my_provider_event_enum_gather, + side_arg_list( + side_arg_gather_integer(&v1), + side_arg_gather_integer(&v2), + side_arg_gather_integer(&v3), + side_arg_gather_integer(&v4), + side_arg_gather_integer(&v5), + side_arg_gather_integer(&v6), + ) + ); +} + int main() { test_fields(); @@ -2086,5 +2166,6 @@ int main() test_gather_byte(); test_gather_bool(); test_gather_pointer(); + test_gather_enum(); return 0; } diff --git a/src/tracer.c b/src/tracer.c index 8b83727..864799e 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -46,6 +46,8 @@ uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_ga static uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr); static +uint32_t tracer_print_gather_enum_type(const struct side_type_gather *type_gather, const void *_ptr); +static uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr); static uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr); @@ -304,9 +306,8 @@ union int64_value tracer_load_integer_value(const struct side_type_integer *type } static -void print_enum_labels(const struct side_type *type_desc, union int64_value v64) +void print_enum_labels(const struct side_enum_mappings *mappings, union int64_value v64) { - const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings; uint32_t i, print_count = 0; printf(", labels: [ "); @@ -344,7 +345,7 @@ void tracer_print_enum(const struct side_type *type_desc, const struct side_arg print_attributes("attr", ":", mappings->attr, mappings->nr_attr); printf("%s", mappings->nr_attr ? ", " : ""); tracer_print_type(elem_type, item); - print_enum_labels(type_desc, v64); + print_enum_labels(mappings, v64); } static @@ -714,6 +715,17 @@ void tracer_print_type(const struct side_type *type_desc, const struct side_arg } break; + case SIDE_TYPE_GATHER_ENUM: + switch (item->type) { + case SIDE_TYPE_GATHER_INTEGER: + break; + default: + fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); + abort(); + break; + } + break; + case SIDE_TYPE_DYNAMIC: switch (item->type) { case SIDE_TYPE_DYNAMIC_NULL: @@ -743,7 +755,8 @@ void tracer_print_type(const struct side_type *type_desc, const struct side_arg break; } - if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP) + if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP || + type_desc->type == SIDE_TYPE_GATHER_ENUM) type = (enum side_type_label) type_desc->type; else type = (enum side_type_label) item->type; @@ -847,6 +860,11 @@ void tracer_print_type(const struct side_type *type_desc, const struct side_arg item->u.side_static.side_vla_gather.length_ptr); break; + /* Gather enumeration types */ + case SIDE_TYPE_GATHER_ENUM: + (void) tracer_print_gather_enum_type(&type_desc->u.side_gather, item->u.side_static.side_integer_gather_ptr); + break; + /* Dynamic basic types */ case SIDE_TYPE_DYNAMIC_NULL: case SIDE_TYPE_DYNAMIC_BOOL: @@ -964,18 +982,19 @@ uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode, uint3 } static -union int64_value tracer_load_gather_integer_value(const struct side_type_gather *type_gather, - const void *_ptr, uint16_t offset_bits) +union int64_value tracer_load_gather_integer_value(const struct side_type_gather_integer *side_integer, + const void *_ptr) { enum side_type_gather_access_mode access_mode = - (enum side_type_gather_access_mode) type_gather->u.side_integer.access_mode; - uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size; + (enum side_type_gather_access_mode) side_integer->access_mode; + uint32_t integer_size_bytes = side_integer->type.integer_size; const char *ptr = (const char *) _ptr; union side_integer_value value; - ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset); + ptr = tracer_gather_access(access_mode, ptr + side_integer->offset); memcpy(&value, ptr, integer_size_bytes); - return tracer_load_integer_value(&type_gather->u.side_integer.type, &value, offset_bits, NULL); + return tracer_load_integer_value(&side_integer->type, &value, + side_integer->offset_bits, NULL); } static @@ -1095,6 +1114,11 @@ uint32_t tracer_print_gather_type(const struct side_type *type_desc, const void len = tracer_print_gather_float_type(&type_desc->u.side_gather, ptr); break; + /* Gather enum types */ + case SIDE_TYPE_GATHER_ENUM: + len = tracer_print_gather_enum_type(&type_desc->u.side_gather, ptr); + break; + /* Gather compound types */ case SIDE_TYPE_GATHER_STRUCT: len = tracer_print_gather_struct(&type_desc->u.side_gather, ptr); @@ -1113,6 +1137,38 @@ uint32_t tracer_print_gather_type(const struct side_type *type_desc, const void return len; } +static +uint32_t tracer_print_gather_enum_type(const struct side_type_gather *type_gather, const void *_ptr) +{ + const struct side_enum_mappings *mappings = type_gather->u.side_enum.mappings; + const struct side_type *enum_elem_type = type_gather->u.side_enum.elem_type; + const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer; + enum side_type_gather_access_mode access_mode = + (enum side_type_gather_access_mode) side_integer->access_mode; + uint32_t integer_size_bytes = side_integer->type.integer_size; + const char *ptr = (const char *) _ptr; + union side_integer_value value; + union int64_value v64; + + switch (integer_size_bytes) { + case 1: + case 2: + case 4: + case 8: + break; + default: + abort(); + } + ptr = tracer_gather_access(access_mode, ptr + side_integer->offset); + memcpy(&value, ptr, integer_size_bytes); + v64 = tracer_load_gather_integer_value(side_integer, &value); + print_attributes("attr", ":", mappings->attr, mappings->nr_attr); + printf("%s", mappings->nr_attr ? ", " : ""); + tracer_print_gather_type(enum_elem_type, ptr); + print_enum_labels(mappings, v64); + return tracer_gather_size(access_mode, integer_size_bytes); +} + static void tracer_print_gather_field(const struct side_event_field *field, const void *ptr) { @@ -1188,8 +1244,8 @@ uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, con fprintf(stderr, "\n"); abort(); } - v64 = tracer_load_gather_integer_value(&type_gather->u.side_vla.length_type->u.side_gather, - length_ptr, 0); + v64 = tracer_load_gather_integer_value(&type_gather->u.side_vla.length_type->u.side_gather.u.side_integer, + length_ptr); length = (uint32_t) v64.u; ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset); orig_ptr = ptr; -- 2.34.1