struct side_arg_dynamic_vec_vla;
struct side_type_description;
struct side_event_field;
+struct side_event_field_sg;
struct side_tracer_visitor_ctx;
struct side_tracer_dynamic_struct_visitor_ctx;
struct side_tracer_dynamic_vla_visitor_ctx;
/* Compound types */
SIDE_TYPE_STRUCT,
+ SIDE_TYPE_STRUCT_SG,
SIDE_TYPE_ARRAY,
SIDE_TYPE_VLA,
SIDE_TYPE_VLA_VISITOR,
SIDE_ATTR_TYPE_STRING,
};
+enum side_type_sg {
+ SIDE_TYPE_SG_UNSIGNED_INT,
+ SIDE_TYPE_SG_SIGNED_INT,
+};
+
enum side_loglevel {
SIDE_LOGLEVEL_EMERG = 0,
SIDE_LOGLEVEL_ALERT = 1,
const struct side_attr *attr;
};
+struct side_type_sg_description {
+ uint32_t type; /* enum side_type_sg */
+ union {
+ /* Basic types */
+ struct {
+ uint64_t integer_offset; /* bytes */
+ const struct side_attr *attr;
+ uint32_t nr_attr;
+ uint32_t byte_order; /* enum side_type_byte_order */
+ uint8_t integer_size_bits; /* bits */
+ uint8_t offset_bits; /* bits */
+ uint8_t len_bits; /* bits */
+ } side_basic;
+ } u;
+};
+
+struct side_struct_field_sg {
+ const char *field_name;
+ struct side_type_sg_description side_type;
+};
+
+/* Structure fields scatter-gather. */
+struct side_type_struct_sg {
+ uint32_t nr_fields;
+ uint32_t nr_attr;
+ const struct side_struct_field_sg *fields_sg;
+ const struct side_attr *attr;
+};
+
struct side_type_description {
uint32_t type; /* enum side_type */
union {
uint32_t nr_attr;
} side_vla_visitor;
const struct side_type_struct *side_struct;
+ const struct side_type_struct_sg *side_struct_sg;
/* Enumeration types */
struct {
void *p;
uint32_t length;
} side_vla_fixint;
+ void *side_struct_sg_ptr;
/* Dynamic type */
struct side_arg_dynamic_vec dynamic;
SIDE_COMPOUND_LITERAL(const struct side_type_struct, \
_side_type_struct_define(SIDE_PARAM(_fields), SIDE_PARAM(_attr)))
+/* Scatter-gather struct */
+
+#define _side_type_sg_integer(_type, _byte_order, _integer_offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \
+ { \
+ .type = _type, \
+ .u = { \
+ .side_basic = { \
+ .attr = _attr, \
+ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ .byte_order = _byte_order, \
+ .integer_offset = _integer_offset, \
+ .integer_size_bits = _integer_size_bits, \
+ .offset_bits = _offset_bits, \
+ .len_bits = _len_bits, \
+ }, \
+ }, \
+ }
+
+#define _side_field_sg(_name, _type) \
+ { \
+ .field_name = _name, \
+ .side_type = _type, \
+ }
+
+#define side_type_sg_unsigned_integer(_integer_offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \
+ _side_type_sg_integer(SIDE_TYPE_SG_UNSIGNED_INT, SIDE_TYPE_BYTE_ORDER_HOST, \
+ _integer_offset, _integer_size_bits, _offset_bits, _len_bits, SIDE_PARAM(_attr))
+#define side_type_sg_signed_integer(_integer_offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \
+ _side_type_sg_integer(SIDE_TYPE_SG_SIGNED_INT, SIDE_TYPE_BYTE_ORDER_HOST, \
+ _integer_offset, _integer_size_bits, _offset_bits, _len_bits, SIDE_PARAM(_attr))
+
+#define side_field_sg_unsigned_integer(_name, _integer_offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \
+ _side_field_sg(_name, side_type_sg_unsigned_integer(_integer_offset, _integer_size_bits, _offset_bits, _len_bits, SIDE_PARAM(_attr)))
+#define side_field_sg_signed_integer(_name, _integer_offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \
+ _side_field_sg(_name, side_type_sg_signed_integer(_integer_offset, _integer_size_bits, _offset_bits, _len_bits, SIDE_PARAM(_attr)))
+
+#define side_type_struct_sg(_struct_sg) \
+ { \
+ .type = SIDE_TYPE_STRUCT_SG, \
+ .u = { \
+ .side_struct_sg = _struct_sg, \
+ }, \
+ }
+#define side_field_struct_sg(_name, _struct_sg) \
+ _side_field(_name, side_type_struct_sg(SIDE_PARAM(_struct_sg)))
+
+#define _side_type_struct_sg_define(_fields_sg, _attr) \
+ { \
+ .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields_sg)), \
+ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ .fields_sg = _fields_sg, \
+ .attr = _attr, \
+ }
+
+#define side_define_struct_sg(_identifier, _fields_sg, _attr) \
+ const struct side_type_struct_sg _identifier = _side_type_struct_sg_define(SIDE_PARAM(_fields_sg), SIDE_PARAM(_attr))
+
+#define side_struct_sg_literal(_fields_sg, _attr) \
+ SIDE_COMPOUND_LITERAL(const struct side_type_struct_sg, \
+ _side_type_struct_sg_define(SIDE_PARAM(_fields_sg), SIDE_PARAM(_attr)))
+
#define side_type_array(_elem_type, _length, _attr) \
{ \
.type = SIDE_TYPE_ARRAY, \
#define side_field_list(...) \
SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
+#define side_field_sg_list(...) \
+ SIDE_COMPOUND_LITERAL(const struct side_struct_field_sg, __VA_ARGS__)
+
/* Static field arguments */
#define side_arg_bool(_val) { .type = SIDE_TYPE_BOOL, .u = { .side_bool = !!(_val) } }
#define side_arg_string(_val) { .type = SIDE_TYPE_STRING, .u = { .string = (uintptr_t) (_val) } }
#define side_arg_struct(_side_type) { .type = SIDE_TYPE_STRUCT, .u = { .side_struct = (_side_type) } }
+#define side_arg_struct_sg(_ptr) { .type = SIDE_TYPE_STRUCT_SG, .u = { .side_struct_sg_ptr = (_ptr) } }
#define side_arg_array(_side_type) { .type = SIDE_TYPE_ARRAY, .u = { .side_array = (_side_type) } }
#define side_arg_vla(_side_type) { .type = SIDE_TYPE_VLA, .u = { .side_vla = (_side_type) } }
#define side_arg_vla_visitor(_ctx) { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_vla_app_visitor_ctx = (_ctx) } }
static
void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
static
+void tracer_print_struct_sg(const struct side_type_description *type_desc, void *ptr);
+static
void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
static
void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
}
}
+static
+bool sg_type_to_host_reverse_bo(const struct side_type_sg_description *sg_type)
+{
+ switch (sg_type->type) {
+ case SIDE_TYPE_SG_UNSIGNED_INT:
+ case SIDE_TYPE_SG_SIGNED_INT:
+ if (sg_type->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
+ return true;
+ else
+ return false;
+ break;
+ default:
+ fprintf(stderr, "Unexpected type\n");
+ abort();
+ }
+}
+
static
bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec *item)
{
case SIDE_TYPE_STRUCT:
tracer_print_struct(type_desc, item->u.side_struct);
break;
+ case SIDE_TYPE_STRUCT_SG:
+ tracer_print_struct_sg(type_desc, item->u.side_struct_sg_ptr);
+ break;
case SIDE_TYPE_ARRAY:
tracer_print_array(type_desc, item->u.side_array);
break;
printf(" }");
}
+static
+void tracer_print_sg_integer_type_header(const struct side_type_sg_description *sg_type)
+{
+ print_attributes("attr", ":", sg_type->u.side_basic.attr, sg_type->u.side_basic.nr_attr);
+ printf("%s", sg_type->u.side_basic.nr_attr ? ", " : "");
+ printf("value: ");
+}
+
+static
+void tracer_print_sg_type(const struct side_type_sg_description *sg_type, void *_ptr)
+{
+ enum tracer_display_base base = TRACER_DISPLAY_BASE_10;
+ const char *ptr = (const char *) _ptr;
+
+ switch (sg_type->type) {
+ case SIDE_TYPE_SG_UNSIGNED_INT:
+ case SIDE_TYPE_SG_SIGNED_INT:
+ base = get_attr_display_base(sg_type->u.side_basic.attr,
+ sg_type->u.side_basic.nr_attr);
+ break;
+ default:
+ break;
+ }
+
+ printf("{ ");
+ switch (sg_type->type) {
+ case SIDE_TYPE_SG_UNSIGNED_INT:
+ {
+ tracer_print_sg_integer_type_header(sg_type);
+ switch (sg_type->u.side_basic.integer_size_bits) {
+ case 8:
+ {
+ uint8_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 8)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo8, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRIu8, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx8, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 16:
+ {
+ uint16_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_16(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 16)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo16, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRIu16, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx16, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 32:
+ {
+ uint32_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_32(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 32)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo32, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRIu32, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx32, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 64:
+ {
+ uint64_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_64(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 64)
+ v &= (1ULL << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo64, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRIu64, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx64, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
+ abort();
+ }
+ break;
+ }
+ case SIDE_TYPE_SG_SIGNED_INT:
+ {
+ tracer_print_sg_integer_type_header(sg_type);
+ switch (sg_type->u.side_basic.integer_size_bits) {
+ case 8:
+ {
+ int8_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 8)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo8, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRId8, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx8, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 16:
+ {
+ int16_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_16(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 16)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo16, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRId16, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx16, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 32:
+ {
+ uint32_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_32(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 32)
+ v &= (1U << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo32, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRId32, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx32, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ case 64:
+ {
+ uint64_t v;
+
+ memcpy(&v, ptr + sg_type->u.side_basic.integer_offset, sizeof(v));
+ if (sg_type_to_host_reverse_bo(sg_type))
+ v = side_bswap_64(v);
+ v >>= sg_type->u.side_basic.offset_bits;
+ if (sg_type->u.side_basic.len_bits < 64)
+ v &= (1ULL << sg_type->u.side_basic.len_bits) - 1;
+ switch (base) {
+ case TRACER_DISPLAY_BASE_2:
+ print_integer_binary(v, sg_type->u.side_basic.len_bits);
+ break;
+ case TRACER_DISPLAY_BASE_8:
+ printf("0%" PRIo64, v);
+ break;
+ case TRACER_DISPLAY_BASE_10:
+ printf("%" PRId64, v);
+ break;
+ case TRACER_DISPLAY_BASE_16:
+ printf("0x%" PRIx64, v);
+ break;
+ default:
+ abort();
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
+ abort();
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "<UNKNOWN SCATTER-GATHER TYPE>");
+ abort();
+ }
+ printf(" }");
+}
+
+static
+void tracer_print_sg_field(const struct side_struct_field_sg *field_sg, void *ptr)
+{
+ printf("%s: ", field_sg->field_name);
+ tracer_print_sg_type(&field_sg->side_type, ptr);
+}
+
+static
+void tracer_print_struct_sg(const struct side_type_description *type_desc, void *ptr)
+{
+ const struct side_type_struct_sg *struct_sg = type_desc->u.side_struct_sg;
+ int i;
+
+ print_attributes("attr", ":", struct_sg->attr, struct_sg->nr_attr);
+ printf("%s", struct_sg->nr_attr ? ", " : "");
+ printf("fields: { ");
+ for (i = 0; i < struct_sg->nr_fields; i++) {
+ printf("%s", i ? ", " : "");
+ tracer_print_sg_field(&struct_sg->fields_sg[i], ptr);
+ }
+ printf(" }");
+}
+
static
void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
{