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,
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 */
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;
#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, \
);
}
}
+
+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();
test_gather_byte();
test_gather_bool();
test_gather_pointer();
+ test_gather_enum();
return 0;
}
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);
}
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: [ ");
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
}
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:
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;
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:
}
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
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);
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)
{
fprintf(stderr, "<gather VLA expects integer gather length type>\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;