From: Mathieu Desnoyers Date: Thu, 2 Apr 2020 17:37:17 +0000 (-0400) Subject: tracepoint: Refactor representation of nested types X-Git-Tag: v2.13.0-rc1~515 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=218deb69baab;p=lttng-ust.git tracepoint: Refactor representation of nested types Refactor enumeration, sequence, array, structure, and variant types. Implement internal data structures to support nested types. All probe providers using ctf_enum(), ctf_array*() and ctf_sequence*() are switched to this new binary layout, and the prior enum, array and sequence abstract types are kept only for backward compatibility with probe providers generated by older lttng-ust headers. Each of sequence, array, struct and variant gain a "alignment" property, which is a feature which was needed in lttng-modules to express alignment for an array or sequence of bits. The ust-ctl protocol with session daemon is extended to support those new types. Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h index 4b254efa..19fba726 100644 --- a/include/lttng/ust-ctl.h +++ b/include/lttng/ust-ctl.h @@ -313,13 +313,18 @@ enum ustctl_channel_header { enum ustctl_abstract_types { ustctl_atype_integer, - ustctl_atype_enum, - ustctl_atype_array, - ustctl_atype_sequence, + ustctl_atype_enum, /* legacy */ + ustctl_atype_array, /* legacy */ + ustctl_atype_sequence, /* legacy */ ustctl_atype_string, ustctl_atype_float, - ustctl_atype_variant, - ustctl_atype_struct, + ustctl_atype_variant, /* legacy */ + ustctl_atype_struct, /* legacy */ + ustctl_atype_enum_nestable, + ustctl_atype_array_nestable, + ustctl_atype_sequence_nestable, + ustctl_atype_struct_nestable, + ustctl_atype_variant_nestable, NR_USTCTL_ABSTRACT_TYPES, }; @@ -373,6 +378,7 @@ struct ustctl_enum_entry { } u; } LTTNG_PACKED; +/* legacy */ #define USTCTL_UST_BASIC_TYPE_PADDING 296 union _ustctl_basic_type { struct ustctl_integer_type integer; @@ -388,6 +394,7 @@ union _ustctl_basic_type { char padding[USTCTL_UST_BASIC_TYPE_PADDING]; } LTTNG_PACKED; +/* legacy */ struct ustctl_basic_type { enum ustctl_abstract_types atype; union { @@ -395,28 +402,67 @@ struct ustctl_basic_type { } u; } LTTNG_PACKED; -#define USTCTL_UST_TYPE_PADDING 128 +/* + * Padding is derived from largest member: u.legacy.sequence which + * contains two basic types, each with USTCTL_UST_BASIC_TYPE_PADDING. + */ +#define USTCTL_UST_TYPE_PADDING (2 * USTCTL_UST_BASIC_TYPE_PADDING) struct ustctl_type { enum ustctl_abstract_types atype; union { - union _ustctl_basic_type basic; + struct ustctl_integer_type integer; + struct ustctl_float_type _float; + struct { + int32_t encoding; /* enum ustctl_string_encodings */ + } string; + struct { + char name[LTTNG_UST_SYM_NAME_LEN]; + uint64_t id; /* enum ID in sessiond. */ + /* container_type follows after this struct ustctl_field. */ + } enum_nestable; struct { - struct ustctl_basic_type elem_type; uint32_t length; /* num. elems. */ - } array; + uint32_t alignment; + /* elem_type follows after this struct ustctl_field. */ + } array_nestable; struct { - struct ustctl_basic_type length_type; - struct ustctl_basic_type elem_type; - } sequence; + char length_name[LTTNG_UST_SYM_NAME_LEN]; + uint32_t alignment; /* Alignment before elements. */ + /* elem_type follows after the length_type. */ + } sequence_nestable; + struct { + uint32_t nr_fields; + uint32_t alignment; + /* Followed by nr_fields struct ustctl_field. */ + } struct_nestable; struct { uint32_t nr_choices; char tag_name[LTTNG_UST_SYM_NAME_LEN]; + uint32_t alignment; /* Followed by nr_choices struct ustctl_field. */ - } variant; - struct { - uint32_t nr_fields; - /* Followed by nr_fields struct ustctl_field. */ - } _struct; + } variant_nestable; + + /* Legacy ABI */ + union { + union _ustctl_basic_type basic; + struct { + struct ustctl_basic_type elem_type; + uint32_t length; /* num. elems. */ + } array; + struct { + struct ustctl_basic_type length_type; + struct ustctl_basic_type elem_type; + } sequence; + struct { + uint32_t nr_fields; + /* Followed by nr_fields struct ustctl_field. */ + } _struct; + struct { + uint32_t nr_choices; + char tag_name[LTTNG_UST_SYM_NAME_LEN]; + /* Followed by nr_choices struct ustctl_field. */ + } variant; + } legacy; char padding[USTCTL_UST_TYPE_PADDING]; } u; } LTTNG_PACKED; diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 938e12bc..54eb0955 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -88,13 +88,17 @@ enum lttng_client_types { /* Update the astract_types name table in lttng-types.c along with this enum */ enum lttng_abstract_types { atype_integer, - atype_enum, - atype_array, - atype_sequence, + atype_enum, /* legacy */ + atype_array, /* legacy */ + atype_sequence, /* legacy */ atype_string, atype_float, atype_dynamic, - atype_struct, + atype_struct, /* legacy */ + atype_enum_nestable, + atype_array_nestable, + atype_sequence_nestable, + atype_struct_nestable, NR_ABSTRACT_TYPES, }; @@ -132,17 +136,14 @@ struct lttng_enum_entry { .atype = atype_integer, \ .u = \ { \ - .basic = \ + .integer = \ { \ - .integer = \ - { \ - .size = sizeof(_type) * CHAR_BIT, \ - .alignment = lttng_alignof(_type) * CHAR_BIT, \ - .signedness = lttng_is_signed_type(_type), \ - .reverse_byte_order = _byte_order != BYTE_ORDER, \ - .base = _base, \ - .encoding = lttng_encode_##_encoding, \ - } \ + .size = sizeof(_type) * CHAR_BIT, \ + .alignment = lttng_alignof(_type) * CHAR_BIT, \ + .signedness = lttng_is_signed_type(_type), \ + .reverse_byte_order = _byte_order != BYTE_ORDER, \ + .base = _base, \ + .encoding = lttng_encode_##_encoding, \ } \ }, \ } \ @@ -172,18 +173,15 @@ struct lttng_integer_type { .atype = atype_float, \ .u = \ { \ - .basic = \ + ._float = \ { \ - ._float = \ - { \ - .exp_dig = sizeof(_type) * CHAR_BIT \ - - _float_mant_dig(_type), \ - .mant_dig = _float_mant_dig(_type), \ - .alignment = lttng_alignof(_type) * CHAR_BIT, \ - .reverse_byte_order = BYTE_ORDER != FLOAT_WORD_ORDER, \ - } \ + .exp_dig = sizeof(_type) * CHAR_BIT \ + - _float_mant_dig(_type), \ + .mant_dig = _float_mant_dig(_type), \ + .alignment = lttng_alignof(_type) * CHAR_BIT, \ + .reverse_byte_order = BYTE_ORDER != FLOAT_WORD_ORDER, \ } \ - }, \ + } \ } \ #define LTTNG_UST_FLOAT_TYPE_PADDING 24 @@ -195,20 +193,22 @@ struct lttng_float_type { char padding[LTTNG_UST_FLOAT_TYPE_PADDING]; }; +/* legacy */ #define LTTNG_UST_BASIC_TYPE_PADDING 128 union _lttng_basic_type { - struct lttng_integer_type integer; + struct lttng_integer_type integer; /* legacy */ struct { const struct lttng_enum_desc *desc; /* Enumeration mapping */ struct lttng_integer_type container_type; - } enumeration; + } enumeration; /* legacy */ struct { enum lttng_string_encodings encoding; - } string; - struct lttng_float_type _float; + } string; /* legacy */ + struct lttng_float_type _float; /* legacy */ char padding[LTTNG_UST_BASIC_TYPE_PADDING]; }; +/* legacy */ struct lttng_basic_type { enum lttng_abstract_types atype; union { @@ -220,19 +220,48 @@ struct lttng_basic_type { struct lttng_type { enum lttng_abstract_types atype; union { - union _lttng_basic_type basic; + /* provider ABI 2.0 */ + struct lttng_integer_type integer; + struct lttng_float_type _float; + struct { + enum lttng_string_encodings encoding; + } string; + struct { + const struct lttng_enum_desc *desc; /* Enumeration mapping */ + struct lttng_type *container_type; + } enum_nestable; struct { - struct lttng_basic_type elem_type; - unsigned int length; /* num. elems. */ - } array; + const struct lttng_type *elem_type; + unsigned int length; /* Num. elems. */ + unsigned int alignment; + } array_nestable; struct { - struct lttng_basic_type length_type; - struct lttng_basic_type elem_type; - } sequence; + const char *length_name; /* Length field name. */ + const struct lttng_type *elem_type; + unsigned int alignment; /* Alignment before elements. */ + } sequence_nestable; struct { - uint32_t nr_fields; - struct lttng_event_field *fields; /* Array of fields. */ - } _struct; + unsigned int nr_fields; + const struct lttng_event_field *fields; /* Array of fields. */ + unsigned int alignment; + } struct_nestable; + + union { + /* legacy provider ABI 1.0 */ + union _lttng_basic_type basic; /* legacy */ + struct { + struct lttng_basic_type elem_type; + unsigned int length; /* Num. elems. */ + } array; /* legacy */ + struct { + struct lttng_basic_type length_type; + struct lttng_basic_type elem_type; + } sequence; /* legacy */ + struct { + unsigned int nr_fields; + struct lttng_event_field *fields; /* Array of fields. */ + } _struct; /* legacy */ + } legacy; char padding[LTTNG_UST_TYPE_PADDING]; } u; }; @@ -258,7 +287,12 @@ struct lttng_event_field { const char *name; struct lttng_type type; unsigned int nowrite; /* do not write into trace */ - char padding[LTTNG_UST_EVENT_FIELD_PADDING]; + union { + struct { + unsigned int nofilter:1; /* do not consider for filter */ + } ext; + char padding[LTTNG_UST_EVENT_FIELD_PADDING]; + } u; }; enum lttng_ust_dynamic_type { diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index ff266e8f..27f1686a 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -237,6 +237,11 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) .name = #_item, \ .type = __type_integer(_type, _byte_order, _base, none),\ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef _ctf_float @@ -245,6 +250,11 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) .name = #_item, \ .type = __type_float(_type), \ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef _ctf_array_encoded @@ -255,38 +265,62 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) .name = #_item, \ .type = \ { \ - .atype = atype_array, \ + .atype = atype_array_nestable, \ .u = \ { \ - .array = \ + .array_nestable = \ { \ - .elem_type = __type_integer(_type, _byte_order, _elem_type_base, _encoding), \ + .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \ + __type_integer(_type, _byte_order, _elem_type_base, _encoding)), \ .length = _length, \ + .alignment = 0, \ } \ } \ }, \ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef _ctf_sequence_encoded #define _ctf_sequence_encoded(_type, _item, _src, _byte_order, \ _length_type, _src_length, _encoding, _nowrite, \ _elem_type_base) \ + { \ + .name = "_" #_item "_length", \ + .type = __type_integer(_length_type, BYTE_ORDER, 10, none), \ + .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 1, \ + }, \ + }, \ + }, \ { \ .name = #_item, \ .type = \ { \ - .atype = atype_sequence, \ + .atype = atype_sequence_nestable, \ .u = \ { \ - .sequence = \ + .sequence_nestable = \ { \ - .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \ - .elem_type = __type_integer(_type, _byte_order, _elem_type_base, _encoding), \ + .length_name = "_" #_item "_length", \ + .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \ + __type_integer(_type, _byte_order, _elem_type_base, _encoding)), \ + .alignment = 0, \ }, \ }, \ }, \ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef _ctf_string @@ -298,10 +332,15 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) .atype = atype_string, \ .u = \ { \ - .basic = { .string = { .encoding = lttng_encode_UTF8 } } \ + .string = { .encoding = lttng_encode_UTF8 } \ }, \ }, \ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef _ctf_enum @@ -309,24 +348,21 @@ void __event_template_proto___##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args) { \ .name = #_item, \ .type = { \ - .atype = atype_enum, \ + .atype = atype_enum_nestable, \ .u = { \ - .basic = { \ - .enumeration = { \ - .desc = &__enum_##_provider##_##_name, \ - .container_type = { \ - .size = sizeof(_type) * CHAR_BIT, \ - .alignment = lttng_alignof(_type) * CHAR_BIT, \ - .signedness = lttng_is_signed_type(_type), \ - .reverse_byte_order = 0, \ - .base = 10, \ - .encoding = lttng_encode_none, \ - }, \ - }, \ - }, \ + .enum_nestable = { \ + .desc = &__enum_##_provider##_##_name, \ + .container_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \ + __type_integer(_type, BYTE_ORDER, 10, none)), \ + }, \ }, \ }, \ .nowrite = _nowrite, \ + .u = { \ + .ext = { \ + .nofilter = 0, \ + }, \ + }, \ }, #undef TP_FIELDS diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 814ccde1..d7991f19 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -55,6 +55,11 @@ static int serialize_one_field(struct lttng_session *session, struct ustctl_field *fields, size_t *iter_output, const struct lttng_event_field *lf); +static +int serialize_fields(struct lttng_session *session, + struct ustctl_field *ustctl_fields, + size_t *iter_output, size_t nr_lttng_fields, + const struct lttng_event_field *lttng_fields); /* * Human readable error message. @@ -773,8 +778,18 @@ ssize_t count_one_type(const struct lttng_type *lt) case atype_sequence: return 1; case atype_struct: - //TODO: implement non-empty struct. - return 1; + return count_fields_recursive(lt->u.legacy._struct.nr_fields, + lt->u.legacy._struct.fields); + case atype_enum_nestable: + return count_one_type(lt->u.enum_nestable.container_type) + 1; + case atype_array_nestable: + return count_one_type(lt->u.array_nestable.elem_type) + 1; + case atype_sequence_nestable: + return count_one_type(lt->u.sequence_nestable.elem_type) + 1; + case atype_struct_nestable: + return count_fields_recursive(lt->u.struct_nestable.nr_fields, + lt->u.struct_nestable.fields); + case atype_dynamic: { const struct lttng_event_field *choices; @@ -791,6 +806,7 @@ ssize_t count_one_type(const struct lttng_type *lt) */ return count_fields_recursive(nr_choices, choices) + 2; } + default: return -EINVAL; } @@ -939,7 +955,10 @@ int serialize_basic_type(struct lttng_session *session, break; } case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: + case atype_enum_nestable: default: return -EINVAL; } @@ -949,7 +968,7 @@ int serialize_basic_type(struct lttng_session *session, static int serialize_dynamic_type(struct lttng_session *session, struct ustctl_field *fields, size_t *iter_output, - const struct lttng_event_field *lf) + const char *field_name) { const struct lttng_event_field *choices; char tag_field_name[LTTNG_UST_SYM_NAME_LEN]; @@ -967,7 +986,7 @@ int serialize_dynamic_type(struct lttng_session *session, tag_type = &tag_field_generic->type; /* Serialize enum field. */ - strncpy(tag_field_name, lf->name, LTTNG_UST_SYM_NAME_LEN); + strncpy(tag_field_name, field_name, LTTNG_UST_SYM_NAME_LEN); tag_field_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; strncat(tag_field_name, "_tag", @@ -984,14 +1003,15 @@ int serialize_dynamic_type(struct lttng_session *session, if (ret) return ret; - strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN); + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; uf->type.atype = ustctl_atype_variant; - uf->type.u.variant.nr_choices = nr_choices; - strncpy(uf->type.u.variant.tag_name, + uf->type.u.variant_nestable.nr_choices = nr_choices; + strncpy(uf->type.u.variant_nestable.tag_name, tag_field_name, LTTNG_UST_SYM_NAME_LEN); - uf->type.u.variant.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + uf->type.u.variant_nestable.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + uf->type.u.variant_nestable.alignment = 0; (*iter_output)++; /* Serialize choice fields after variant. */ @@ -1005,16 +1025,16 @@ int serialize_dynamic_type(struct lttng_session *session, } static -int serialize_one_field(struct lttng_session *session, +int serialize_one_type(struct lttng_session *session, struct ustctl_field *fields, size_t *iter_output, - const struct lttng_event_field *lf) + const char *field_name, const struct lttng_type *lt) { - const struct lttng_type *lt = &lf->type; int ret; - /* skip 'nowrite' fields */ - if (lf->nowrite) - return 0; + /* + * Serializing a type (rather than a field) generates a ustctl_field + * entry with 0-length name. + */ switch (lt->atype) { case atype_integer: @@ -1026,10 +1046,14 @@ int serialize_one_field(struct lttng_session *session, struct ustctl_type *ut = &uf->type; enum ustctl_abstract_types atype; - strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN); - uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } ret = serialize_basic_type(session, &atype, lt->atype, - &ut->u.basic, <->u.basic); + &ut->u.legacy.basic, <->u.legacy.basic); if (ret) return ret; ut->atype = atype; @@ -1044,21 +1068,46 @@ int serialize_one_field(struct lttng_session *session, const struct lttng_basic_type *lbt; enum ustctl_abstract_types atype; - strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN); - uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; - uf->type.atype = ustctl_atype_array; - ubt = &ut->u.array.elem_type; - lbt = <->u.array.elem_type; - ut->u.array.length = lt->u.array.length; + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } + ut->atype = ustctl_atype_array; + ubt = &ut->u.legacy.array.elem_type; + lbt = <->u.legacy.array.elem_type; + ut->u.legacy.array.length = lt->u.legacy.array.length; ret = serialize_basic_type(session, &atype, lbt->atype, &ubt->u.basic, &lbt->u.basic); if (ret) return -EINVAL; ubt->atype = atype; - ut->atype = ustctl_atype_array; (*iter_output)++; break; } + case atype_array_nestable: + { + struct ustctl_field *uf = &fields[*iter_output]; + struct ustctl_type *ut = &uf->type; + + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } + ut->atype = ustctl_atype_array_nestable; + ut->u.array_nestable.length = lt->u.array_nestable.length; + ut->u.array_nestable.alignment = lt->u.array_nestable.alignment; + (*iter_output)++; + + ret = serialize_one_type(session, fields, iter_output, NULL, + lt->u.array_nestable.elem_type); + if (ret) + return -EINVAL; + break; + } case atype_sequence: { struct ustctl_field *uf = &fields[*iter_output]; @@ -1066,32 +1115,60 @@ int serialize_one_field(struct lttng_session *session, struct ustctl_basic_type *ubt; const struct lttng_basic_type *lbt; enum ustctl_abstract_types atype; - int ret; - strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN); - uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } uf->type.atype = ustctl_atype_sequence; - ubt = &ut->u.sequence.length_type; - lbt = <->u.sequence.length_type; + ubt = &ut->u.legacy.sequence.length_type; + lbt = <->u.legacy.sequence.length_type; ret = serialize_basic_type(session, &atype, lbt->atype, &ubt->u.basic, &lbt->u.basic); if (ret) return -EINVAL; ubt->atype = atype; - ubt = &ut->u.sequence.elem_type; - lbt = <->u.sequence.elem_type; + ubt = &ut->u.legacy.sequence.elem_type; + lbt = <->u.legacy.sequence.elem_type; ret = serialize_basic_type(session, &atype, lbt->atype, &ubt->u.basic, &lbt->u.basic); if (ret) return -EINVAL; ubt->atype = atype; - ut->atype = ustctl_atype_sequence; (*iter_output)++; break; } + case atype_sequence_nestable: + { + struct ustctl_field *uf = &fields[*iter_output]; + struct ustctl_type *ut = &uf->type; + + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } + ut->atype = ustctl_atype_sequence_nestable; + strncpy(ut->u.sequence_nestable.length_name, + lt->u.sequence_nestable.length_name, + LTTNG_UST_SYM_NAME_LEN); + ut->u.sequence_nestable.length_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + ut->u.sequence_nestable.alignment = lt->u.sequence_nestable.alignment; + (*iter_output)++; + + ret = serialize_one_type(session, fields, iter_output, NULL, + lt->u.sequence_nestable.elem_type); + if (ret) + return -EINVAL; + break; + } case atype_dynamic: { - ret = serialize_dynamic_type(session, fields, iter_output, lf); + ret = serialize_dynamic_type(session, fields, iter_output, + field_name); if (ret) return -EINVAL; break; @@ -1100,17 +1177,76 @@ int serialize_one_field(struct lttng_session *session, { struct ustctl_field *uf = &fields[*iter_output]; - /* - * TODO: add support for non-empty struct. - */ - if (lf->type.u._struct.nr_fields != 0) { - return -EINVAL; + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; } - strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN); - uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; uf->type.atype = ustctl_atype_struct; - uf->type.u._struct.nr_fields = 0; + uf->type.u.legacy._struct.nr_fields = lt->u.legacy._struct.nr_fields; (*iter_output)++; + + ret = serialize_fields(session, fields, iter_output, + lt->u.legacy._struct.nr_fields, + lt->u.legacy._struct.fields); + if (ret) + return -EINVAL; + break; + } + case atype_struct_nestable: + { + struct ustctl_field *uf = &fields[*iter_output]; + + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } + uf->type.atype = ustctl_atype_struct_nestable; + uf->type.u.struct_nestable.nr_fields = lt->u.struct_nestable.nr_fields; + uf->type.u.struct_nestable.alignment = lt->u.struct_nestable.alignment; + (*iter_output)++; + + ret = serialize_fields(session, fields, iter_output, + lt->u.struct_nestable.nr_fields, + lt->u.struct_nestable.fields); + if (ret) + return -EINVAL; + break; + } + case atype_enum_nestable: + { + struct ustctl_field *uf = &fields[*iter_output]; + struct ustctl_type *ut = &uf->type; + + if (field_name) { + strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN); + uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + } else { + uf->name[0] = '\0'; + } + strncpy(ut->u.enum_nestable.name, lt->u.enum_nestable.desc->name, + LTTNG_UST_SYM_NAME_LEN); + ut->u.enum_nestable.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + ut->atype = ustctl_atype_enum_nestable; + (*iter_output)++; + + ret = serialize_one_type(session, fields, iter_output, NULL, + lt->u.enum_nestable.container_type); + if (ret) + return -EINVAL; + if (session) { + const struct lttng_enum *_enum; + + _enum = lttng_ust_enum_get_from_desc(session, lt->u.enum_nestable.desc); + if (!_enum) + return -EINVAL; + ut->u.enum_nestable.id = _enum->id; + } else { + ut->u.enum_nestable.id = -1ULL; + } break; } default: @@ -1119,8 +1255,38 @@ int serialize_one_field(struct lttng_session *session, return 0; } +static +int serialize_one_field(struct lttng_session *session, + struct ustctl_field *fields, size_t *iter_output, + const struct lttng_event_field *lf) +{ + /* skip 'nowrite' fields */ + if (lf->nowrite) + return 0; + + return serialize_one_type(session, fields, iter_output, lf->name, &lf->type); +} + static int serialize_fields(struct lttng_session *session, + struct ustctl_field *ustctl_fields, + size_t *iter_output, size_t nr_lttng_fields, + const struct lttng_event_field *lttng_fields) +{ + int ret; + size_t i; + + for (i = 0; i < nr_lttng_fields; i++) { + ret = serialize_one_field(session, ustctl_fields, + iter_output, <tng_fields[i]); + if (ret) + return ret; + } + return 0; +} + +static +int alloc_serialize_fields(struct lttng_session *session, size_t *_nr_write_fields, struct ustctl_field **ustctl_fields, size_t nr_fields, @@ -1128,7 +1294,7 @@ int serialize_fields(struct lttng_session *session, { struct ustctl_field *fields; int ret; - size_t i, iter_output = 0; + size_t iter_output = 0; ssize_t nr_write_fields; nr_write_fields = count_fields_recursive(nr_fields, lttng_fields); @@ -1140,12 +1306,10 @@ int serialize_fields(struct lttng_session *session, if (!fields) return -ENOMEM; - for (i = 0; i < nr_fields; i++) { - ret = serialize_one_field(session, fields, &iter_output, - <tng_fields[i]); - if (ret) - goto error_type; - } + ret = serialize_fields(session, fields, &iter_output, nr_fields, + lttng_fields); + if (ret) + goto error_type; *_nr_write_fields = nr_write_fields; *ustctl_fields = fields; @@ -1270,7 +1434,7 @@ int ustcomm_register_event(int sock, /* Calculate fields len, serialize fields. */ if (nr_fields > 0) { - ret = serialize_fields(session, &nr_write_fields, &fields, + ret = alloc_serialize_fields(session, &nr_write_fields, &fields, nr_fields, lttng_fields); if (ret) return ret; diff --git a/liblttng-ust/lttng-context-cgroup-ns.c b/liblttng-ust/lttng-context-cgroup-ns.c index a6aca3ab..9aa0b754 100644 --- a/liblttng-ust/lttng-context-cgroup-ns.c +++ b/liblttng-ust/lttng-context-cgroup-ns.c @@ -143,12 +143,12 @@ int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "cgroup_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = cgroup_ns_get_size; field->record = cgroup_ns_record; field->get_value = cgroup_ns_get_value; diff --git a/liblttng-ust/lttng-context-cpu-id.c b/liblttng-ust/lttng-context-cpu-id.c index c94ef714..7a9dd5fd 100644 --- a/liblttng-ust/lttng-context-cpu-id.c +++ b/liblttng-ust/lttng-context-cpu-id.c @@ -78,12 +78,12 @@ int lttng_add_cpu_id_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "cpu_id"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(int) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(int); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(int) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(int) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(int); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = cpu_id_get_size; field->record = cpu_id_record; field->get_value = cpu_id_get_value; diff --git a/liblttng-ust/lttng-context-ip.c b/liblttng-ust/lttng-context-ip.c index 47f5af03..3e7885e1 100644 --- a/liblttng-ust/lttng-context-ip.c +++ b/liblttng-ust/lttng-context-ip.c @@ -63,12 +63,12 @@ int lttng_add_ip_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "ip"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(void *) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(void *) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(void *); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 16; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(void *) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(void *) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(void *); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 16; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = ip_get_size; field->record = ip_record; lttng_context_update(*ctx); diff --git a/liblttng-ust/lttng-context-ipc-ns.c b/liblttng-ust/lttng-context-ipc-ns.c index 029ba087..a3535759 100644 --- a/liblttng-ust/lttng-context-ipc-ns.c +++ b/liblttng-ust/lttng-context-ipc-ns.c @@ -142,12 +142,12 @@ int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "ipc_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = ipc_ns_get_size; field->record = ipc_ns_record; field->get_value = ipc_ns_get_value; diff --git a/liblttng-ust/lttng-context-mnt-ns.c b/liblttng-ust/lttng-context-mnt-ns.c index fb3e7beb..4bbf48c3 100644 --- a/liblttng-ust/lttng-context-mnt-ns.c +++ b/liblttng-ust/lttng-context-mnt-ns.c @@ -126,12 +126,12 @@ int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "mnt_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = mnt_ns_get_size; field->record = mnt_ns_record; field->get_value = mnt_ns_get_value; diff --git a/liblttng-ust/lttng-context-net-ns.c b/liblttng-ust/lttng-context-net-ns.c index 3ce139f6..c97f6c29 100644 --- a/liblttng-ust/lttng-context-net-ns.c +++ b/liblttng-ust/lttng-context-net-ns.c @@ -142,12 +142,12 @@ int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "net_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = net_ns_get_size; field->record = net_ns_record; field->get_value = net_ns_get_value; diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 12d4ab3b..12839305 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -568,15 +568,15 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->event_field.name = name_alloc; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = + field->event_field.type.u.integer.size = sizeof(uint64_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = + field->event_field.type.u.integer.alignment = lttng_alignof(uint64_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = + field->event_field.type.u.integer.signedness = lttng_is_signed_type(uint64_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = perf_counter_get_size; field->record = perf_counter_record; field->get_value = perf_counter_get_value; diff --git a/liblttng-ust/lttng-context-pid-ns.c b/liblttng-ust/lttng-context-pid-ns.c index 71b42bd6..4a690b7d 100644 --- a/liblttng-ust/lttng-context-pid-ns.c +++ b/liblttng-ust/lttng-context-pid-ns.c @@ -129,12 +129,12 @@ int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "pid_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = pid_ns_get_size; field->record = pid_ns_record; field->get_value = pid_ns_get_value; diff --git a/liblttng-ust/lttng-context-procname.c b/liblttng-ust/lttng-context-procname.c index 73f38878..c6660e3c 100644 --- a/liblttng-ust/lttng-context-procname.c +++ b/liblttng-ust/lttng-context-procname.c @@ -100,6 +100,9 @@ void procname_get_value(struct lttng_ctx_field *field, value->u.str = wrapper_getprocname(); } +static const struct lttng_type procname_array_elem_type = + __type_integer(char, BYTE_ORDER, 10, UTF8); + int lttng_add_procname_to_ctx(struct lttng_ctx **ctx) { struct lttng_ctx_field *field; @@ -112,15 +115,10 @@ int lttng_add_procname_to_ctx(struct lttng_ctx **ctx) return -EEXIST; } field->event_field.name = "procname"; - field->event_field.type.atype = atype_array; - field->event_field.type.u.array.elem_type.atype = atype_integer; - field->event_field.type.u.array.elem_type.u.basic.integer.size = sizeof(char) * CHAR_BIT; - field->event_field.type.u.array.elem_type.u.basic.integer.alignment = lttng_alignof(char) * CHAR_BIT; - field->event_field.type.u.array.elem_type.u.basic.integer.signedness = lttng_is_signed_type(char); - field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.array.elem_type.u.basic.integer.base = 10; - field->event_field.type.u.array.elem_type.u.basic.integer.encoding = lttng_encode_UTF8; - field->event_field.type.u.array.length = LTTNG_UST_PROCNAME_LEN; + field->event_field.type.atype = atype_array_nestable; + field->event_field.type.u.array_nestable.elem_type = + &procname_array_elem_type; + field->event_field.type.u.array_nestable.length = LTTNG_UST_PROCNAME_LEN; field->get_size = procname_get_size; field->record = procname_record; field->get_value = procname_get_value; diff --git a/liblttng-ust/lttng-context-pthread-id.c b/liblttng-ust/lttng-context-pthread-id.c index d3328259..49a72ee1 100644 --- a/liblttng-ust/lttng-context-pthread-id.c +++ b/liblttng-ust/lttng-context-pthread-id.c @@ -69,12 +69,12 @@ int lttng_add_pthread_id_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "pthread_id"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned long); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(unsigned long) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(unsigned long); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = pthread_id_get_size; field->record = pthread_id_record; field->get_value = pthread_id_get_value; diff --git a/liblttng-ust/lttng-context-user-ns.c b/liblttng-ust/lttng-context-user-ns.c index d3e5192e..71188a84 100644 --- a/liblttng-ust/lttng-context-user-ns.c +++ b/liblttng-ust/lttng-context-user-ns.c @@ -126,12 +126,12 @@ int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "user_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = user_ns_get_size; field->record = user_ns_record; field->get_value = user_ns_get_value; diff --git a/liblttng-ust/lttng-context-uts-ns.c b/liblttng-ust/lttng-context-uts-ns.c index 13b7a469..8f7360da 100644 --- a/liblttng-ust/lttng-context-uts-ns.c +++ b/liblttng-ust/lttng-context-uts-ns.c @@ -143,12 +143,12 @@ int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "uts_ns"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = uts_ns_get_size; field->record = uts_ns_record; field->get_value = uts_ns_get_value; diff --git a/liblttng-ust/lttng-context-vegid.c b/liblttng-ust/lttng-context-vegid.c index 12d095f7..48c72368 100644 --- a/liblttng-ust/lttng-context-vegid.c +++ b/liblttng-ust/lttng-context-vegid.c @@ -114,12 +114,12 @@ int lttng_add_vegid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vegid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vegid_get_size; field->record = vegid_record; field->get_value = vegid_get_value; diff --git a/liblttng-ust/lttng-context-veuid.c b/liblttng-ust/lttng-context-veuid.c index 2576aaf0..4c747e66 100644 --- a/liblttng-ust/lttng-context-veuid.c +++ b/liblttng-ust/lttng-context-veuid.c @@ -114,12 +114,12 @@ int lttng_add_veuid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "veuid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = veuid_get_size; field->record = veuid_record; field->get_value = veuid_get_value; diff --git a/liblttng-ust/lttng-context-vgid.c b/liblttng-ust/lttng-context-vgid.c index db0c82d8..7eb8c807 100644 --- a/liblttng-ust/lttng-context-vgid.c +++ b/liblttng-ust/lttng-context-vgid.c @@ -114,12 +114,12 @@ int lttng_add_vgid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vgid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vgid_get_size; field->record = vgid_record; field->get_value = vgid_get_value; diff --git a/liblttng-ust/lttng-context-vpid.c b/liblttng-ust/lttng-context-vpid.c index aa2586ef..54aa8d2a 100644 --- a/liblttng-ust/lttng-context-vpid.c +++ b/liblttng-ust/lttng-context-vpid.c @@ -97,12 +97,12 @@ int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vpid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(pid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(pid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vpid_get_size; field->record = vpid_record; field->get_value = vpid_get_value; diff --git a/liblttng-ust/lttng-context-vsgid.c b/liblttng-ust/lttng-context-vsgid.c index 7613bdd6..45fd2860 100644 --- a/liblttng-ust/lttng-context-vsgid.c +++ b/liblttng-ust/lttng-context-vsgid.c @@ -119,12 +119,12 @@ int lttng_add_vsgid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vsgid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vsgid_get_size; field->record = vsgid_record; field->get_value = vsgid_get_value; diff --git a/liblttng-ust/lttng-context-vsuid.c b/liblttng-ust/lttng-context-vsuid.c index 9c8fd585..f728a31d 100644 --- a/liblttng-ust/lttng-context-vsuid.c +++ b/liblttng-ust/lttng-context-vsuid.c @@ -119,12 +119,12 @@ int lttng_add_vsuid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vsuid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vsuid_get_size; field->record = vsuid_record; field->get_value = vsuid_get_value; diff --git a/liblttng-ust/lttng-context-vtid.c b/liblttng-ust/lttng-context-vtid.c index 0a29021d..cbd3bd26 100644 --- a/liblttng-ust/lttng-context-vtid.c +++ b/liblttng-ust/lttng-context-vtid.c @@ -101,12 +101,12 @@ int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vtid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(pid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(pid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vtid_get_size; field->record = vtid_record; field->get_value = vtid_get_value; diff --git a/liblttng-ust/lttng-context-vuid.c b/liblttng-ust/lttng-context-vuid.c index ad4a07c5..6baad886 100644 --- a/liblttng-ust/lttng-context-vuid.c +++ b/liblttng-ust/lttng-context-vuid.c @@ -114,12 +114,12 @@ int lttng_add_vuid_to_ctx(struct lttng_ctx **ctx) } field->event_field.name = "vuid"; field->event_field.type.atype = atype_integer; - field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; - field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t); - field->event_field.type.u.basic.integer.reverse_byte_order = 0; - field->event_field.type.u.basic.integer.base = 10; - field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; field->get_size = vuid_get_size; field->record = vuid_record; field->get_value = vuid_get_value; diff --git a/liblttng-ust/lttng-context.c b/liblttng-ust/lttng-context.c index bb6a9c9d..5637028b 100644 --- a/liblttng-ust/lttng-context.c +++ b/liblttng-ust/lttng-context.c @@ -180,13 +180,13 @@ void lttng_context_update(struct lttng_ctx *ctx) type = &ctx->fields[i].event_field.type; switch (type->atype) { case atype_integer: - field_align = type->u.basic.integer.alignment; + field_align = type->u.integer.alignment; break; case atype_array: { struct lttng_basic_type *btype; - btype = &type->u.array.elem_type; + btype = &type->u.legacy.array.elem_type; switch (btype->atype) { case atype_integer: field_align = btype->u.basic.integer.alignment; @@ -195,18 +195,44 @@ void lttng_context_update(struct lttng_ctx *ctx) break; case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: default: WARN_ON_ONCE(1); break; } break; } + case atype_array_nestable: + { + const struct lttng_type *nested_type; + + nested_type = type->u.array_nestable.elem_type; + switch (nested_type->atype) { + case atype_integer: + field_align = nested_type->u.integer.alignment; + break; + case atype_string: + break; + + case atype_array: + case atype_array_nestable: + case atype_sequence: + case atype_sequence_nestable: + default: + WARN_ON_ONCE(1); + break; + } + field_align = max_t(size_t, field_align, + type->u.array_nestable.alignment); + break; + } case atype_sequence: { struct lttng_basic_type *btype; - btype = &type->u.sequence.length_type; + btype = &type->u.legacy.sequence.length_type; switch (btype->atype) { case atype_integer: field_align = btype->u.basic.integer.alignment; @@ -214,13 +240,15 @@ void lttng_context_update(struct lttng_ctx *ctx) case atype_string: case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: default: WARN_ON_ONCE(1); break; } - btype = &type->u.sequence.elem_type; + btype = &type->u.legacy.sequence.elem_type; switch (btype->atype) { case atype_integer: field_align = max_t(size_t, @@ -232,11 +260,38 @@ void lttng_context_update(struct lttng_ctx *ctx) break; case atype_array: + case atype_array_nestable: + case atype_sequence: + case atype_sequence_nestable: + default: + WARN_ON_ONCE(1); + break; + } + break; + } + case atype_sequence_nestable: + { + const struct lttng_type *nested_type; + + nested_type = type->u.sequence_nestable.elem_type; + switch (nested_type->atype) { + case atype_integer: + field_align = nested_type->u.integer.alignment; + break; + + case atype_string: + break; + + case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: default: WARN_ON_ONCE(1); break; } + field_align = max_t(size_t, field_align, + type->u.sequence_nestable.alignment); break; } case atype_string: @@ -244,6 +299,7 @@ void lttng_context_update(struct lttng_ctx *ctx) case atype_dynamic: break; case atype_enum: + case atype_enum_nestable: default: WARN_ON_ONCE(1); break; diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index 9b2d3c64..825cd60e 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -318,7 +318,20 @@ int lttng_create_enum_check(const struct lttng_type *type, const struct lttng_enum_desc *enum_desc; int ret; - enum_desc = type->u.basic.enumeration.desc; + enum_desc = type->u.legacy.basic.enumeration.desc; + ret = lttng_enum_create(enum_desc, session); + if (ret && ret != -EEXIST) { + DBG("Unable to create enum error: (%d)", ret); + return ret; + } + break; + } + case atype_enum_nestable: + { + const struct lttng_enum_desc *enum_desc; + int ret; + + enum_desc = type->u.enum_nestable.desc; ret = lttng_enum_create(enum_desc, session); if (ret && ret != -EEXIST) { DBG("Unable to create enum error: (%d)", ret); @@ -333,7 +346,7 @@ int lttng_create_enum_check(const struct lttng_type *type, int ret; tag_field_generic = lttng_ust_dynamic_type_tag_field(); - enum_desc = tag_field_generic->type.u.basic.enumeration.desc; + enum_desc = tag_field_generic->type.u.enum_nestable.desc; ret = lttng_enum_create(enum_desc, session); if (ret && ret != -EEXIST) { DBG("Unable to create enum error: (%d)", ret); @@ -872,11 +885,16 @@ void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_de struct lttng_enum *curr_enum; field = &(event->desc->fields[j]); - if (field->type.atype != atype_enum) { + switch (field->type.atype) { + case atype_enum: + enum_desc = field->type.u.legacy.basic.enumeration.desc; + break; + case atype_enum_nestable: + enum_desc = field->type.u.enum_nestable.desc; + break; + default: continue; } - - enum_desc = field->type.u.basic.enumeration.desc; curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc); if (curr_enum) { _lttng_enum_destroy(curr_enum); diff --git a/liblttng-ust/lttng-filter-interpreter.c b/liblttng-ust/lttng-filter-interpreter.c index 7efa883f..06fab85f 100644 --- a/liblttng-ust/lttng-filter-interpreter.c +++ b/liblttng-ust/lttng-filter-interpreter.c @@ -238,7 +238,7 @@ static int context_get_index(struct lttng_ctx *ctx, switch (field->type.atype) { case atype_integer: ctx_field->get_value(ctx_field, &v); - if (field->type.u.basic.integer.signedness) { + if (field->type.u.integer.signedness) { ptr->object_type = OBJECT_TYPE_S64; ptr->u.s64 = v.u.s64; ptr->ptr = &ptr->u.s64; @@ -248,11 +248,16 @@ static int context_get_index(struct lttng_ctx *ctx, ptr->ptr = &ptr->u.u64; } break; - case atype_enum: + case atype_enum: /* Fall-through */ + case atype_enum_nestable: { - const struct lttng_integer_type *itype = - &field->type.u.basic.enumeration.container_type; + const struct lttng_integer_type *itype; + if (field->type.atype == atype_enum) { + itype = &field->type.u.legacy.basic.enumeration.container_type; + } else { + itype = &field->type.u.enum_nestable.container_type->u.integer; + } ctx_field->get_value(ctx_field, &v); if (itype->signedness) { ptr->object_type = OBJECT_TYPE_S64; @@ -266,11 +271,24 @@ static int context_get_index(struct lttng_ctx *ctx, break; } case atype_array: - if (field->type.u.array.elem_type.atype != atype_integer) { + if (field->type.u.legacy.array.elem_type.atype != atype_integer) { + ERR("Array nesting only supports integer types."); + return -EINVAL; + } + if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) { + ERR("Only string arrays are supported for contexts."); + return -EINVAL; + } + ptr->object_type = OBJECT_TYPE_STRING; + ctx_field->get_value(ctx_field, &v); + ptr->ptr = v.u.str; + break; + case atype_array_nestable: + if (field->type.u.array_nestable.elem_type->atype != atype_integer) { ERR("Array nesting only supports integer types."); return -EINVAL; } - if (field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) { + if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) { ERR("Only string arrays are supported for contexts."); return -EINVAL; } @@ -279,11 +297,24 @@ static int context_get_index(struct lttng_ctx *ctx, ptr->ptr = v.u.str; break; case atype_sequence: - if (field->type.u.sequence.elem_type.atype != atype_integer) { + if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) { + ERR("Sequence nesting only supports integer types."); + return -EINVAL; + } + if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) { + ERR("Only string sequences are supported for contexts."); + return -EINVAL; + } + ptr->object_type = OBJECT_TYPE_STRING; + ctx_field->get_value(ctx_field, &v); + ptr->ptr = v.u.str; + break; + case atype_sequence_nestable: + if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) { ERR("Sequence nesting only supports integer types."); return -EINVAL; } - if (field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) { + if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) { ERR("Only string sequences are supported for contexts."); return -EINVAL; } diff --git a/liblttng-ust/lttng-filter-specialize.c b/liblttng-ust/lttng-filter-specialize.c index 39730f8c..ef45904f 100644 --- a/liblttng-ust/lttng-filter-specialize.c +++ b/liblttng-ust/lttng-filter-specialize.c @@ -259,14 +259,31 @@ static int specialize_get_index(struct bytecode_runtime *runtime, switch (stack_top->load.object_type) { case OBJECT_TYPE_ARRAY: { + const struct lttng_integer_type *integer_type; const struct lttng_event_field *field; uint32_t elem_len, num_elems; int signedness; field = stack_top->load.field; - elem_len = field->type.u.array.elem_type.u.basic.integer.size; - signedness = field->type.u.array.elem_type.u.basic.integer.signedness; - num_elems = field->type.u.array.length; + switch (field->type.atype) { + case atype_array: + integer_type = &field->type.u.legacy.array.elem_type.u.basic.integer; + num_elems = field->type.u.legacy.array.length; + break; + case atype_array_nestable: + if (field->type.u.array_nestable.elem_type->atype != atype_integer) { + ret = -EINVAL; + goto end; + } + integer_type = &field->type.u.array_nestable.elem_type->u.integer; + num_elems = field->type.u.array_nestable.length; + break; + default: + ret = -EINVAL; + goto end; + } + elem_len = integer_type->size; + signedness = integer_type->signedness; if (index >= num_elems) { ret = -EINVAL; goto end; @@ -279,20 +296,36 @@ static int specialize_get_index(struct bytecode_runtime *runtime, gid.array_len = num_elems * (elem_len / CHAR_BIT); gid.elem.type = stack_top->load.object_type; gid.elem.len = elem_len; - if (field->type.u.array.elem_type.u.basic.integer.reverse_byte_order) + if (integer_type->reverse_byte_order) gid.elem.rev_bo = true; stack_top->load.rev_bo = gid.elem.rev_bo; break; } case OBJECT_TYPE_SEQUENCE: { + const struct lttng_integer_type *integer_type; const struct lttng_event_field *field; uint32_t elem_len; int signedness; field = stack_top->load.field; - elem_len = field->type.u.sequence.elem_type.u.basic.integer.size; - signedness = field->type.u.sequence.elem_type.u.basic.integer.signedness; + switch (field->type.atype) { + case atype_sequence: + integer_type = &field->type.u.legacy.sequence.elem_type.u.basic.integer; + break; + case atype_sequence_nestable: + if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) { + ret = -EINVAL; + goto end; + } + integer_type = &field->type.u.sequence_nestable.elem_type->u.integer; + break; + default: + ret = -EINVAL; + goto end; + } + elem_len = integer_type->size; + signedness = integer_type->signedness; ret = specialize_get_index_object_type(&stack_top->load.object_type, signedness, elem_len); if (ret) @@ -300,7 +333,7 @@ static int specialize_get_index(struct bytecode_runtime *runtime, gid.offset = index * (elem_len / CHAR_BIT); gid.elem.type = stack_top->load.object_type; gid.elem.len = elem_len; - if (field->type.u.sequence.elem_type.u.basic.integer.reverse_byte_order) + if (integer_type->reverse_byte_order) gid.elem.rev_bo = true; stack_top->load.rev_bo = gid.elem.rev_bo; break; @@ -367,17 +400,22 @@ static int specialize_load_object(const struct lttng_event_field *field, */ switch (field->type.atype) { case atype_integer: - if (field->type.u.basic.integer.signedness) + if (field->type.u.integer.signedness) load->object_type = OBJECT_TYPE_S64; else load->object_type = OBJECT_TYPE_U64; load->rev_bo = false; break; case atype_enum: + case atype_enum_nestable: { - const struct lttng_integer_type *itype = - &field->type.u.basic.enumeration.container_type; + const struct lttng_integer_type *itype; + if (field->type.atype == atype_enum) { + itype = &field->type.u.legacy.basic.enumeration.container_type; + } else { + itype = &field->type.u.enum_nestable.container_type->u.integer; + } if (itype->signedness) load->object_type = OBJECT_TYPE_S64; else @@ -386,14 +424,30 @@ static int specialize_load_object(const struct lttng_event_field *field, break; } case atype_array: - if (field->type.u.array.elem_type.atype != atype_integer) { + if (field->type.u.legacy.array.elem_type.atype != atype_integer) { + ERR("Array nesting only supports integer types."); + return -EINVAL; + } + if (is_context) { + load->object_type = OBJECT_TYPE_STRING; + } else { + if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) { + load->object_type = OBJECT_TYPE_ARRAY; + load->field = field; + } else { + load->object_type = OBJECT_TYPE_STRING_SEQUENCE; + } + } + break; + case atype_array_nestable: + if (field->type.u.array_nestable.elem_type->atype != atype_integer) { ERR("Array nesting only supports integer types."); return -EINVAL; } if (is_context) { load->object_type = OBJECT_TYPE_STRING; } else { - if (field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) { + if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) { load->object_type = OBJECT_TYPE_ARRAY; load->field = field; } else { @@ -402,14 +456,30 @@ static int specialize_load_object(const struct lttng_event_field *field, } break; case atype_sequence: - if (field->type.u.sequence.elem_type.atype != atype_integer) { + if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) { + ERR("Sequence nesting only supports integer types."); + return -EINVAL; + } + if (is_context) { + load->object_type = OBJECT_TYPE_STRING; + } else { + if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) { + load->object_type = OBJECT_TYPE_SEQUENCE; + load->field = field; + } else { + load->object_type = OBJECT_TYPE_STRING_SEQUENCE; + } + } + break; + case atype_sequence_nestable: + if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) { ERR("Sequence nesting only supports integer types."); return -EINVAL; } if (is_context) { load->object_type = OBJECT_TYPE_STRING; } else { - if (field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) { + if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) { load->object_type = OBJECT_TYPE_SEQUENCE; load->field = field; } else { @@ -417,6 +487,7 @@ static int specialize_load_object(const struct lttng_event_field *field, } } break; + case atype_string: load->object_type = OBJECT_TYPE_STRING; break; @@ -549,6 +620,9 @@ static int specialize_event_payload_lookup(struct lttng_event *event, name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset; for (i = 0; i < nr_fields; i++) { field = &desc->fields[i]; + if (field->u.ext.nofilter) { + continue; + } if (!strcmp(field->name, name)) { found = true; break; @@ -557,10 +631,13 @@ static int specialize_event_payload_lookup(struct lttng_event *event, switch (field->type.atype) { case atype_integer: case atype_enum: + case atype_enum_nestable: field_offset += sizeof(int64_t); break; case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: field_offset += sizeof(unsigned long); field_offset += sizeof(void *); break; diff --git a/liblttng-ust/lttng-filter.c b/liblttng-ust/lttng-filter.c index ed41a0ef..1967d540 100644 --- a/liblttng-ust/lttng-filter.c +++ b/liblttng-ust/lttng-filter.c @@ -211,6 +211,9 @@ int apply_field_reloc(struct lttng_event *event, return -EINVAL; nr_fields = desc->nr_fields; for (i = 0; i < nr_fields; i++) { + if (fields[i].u.ext.nofilter) { + continue; + } if (!strcmp(fields[i].name, field_name)) { field = &fields[i]; break; @@ -219,10 +222,13 @@ int apply_field_reloc(struct lttng_event *event, switch (fields[i].type.atype) { case atype_integer: case atype_enum: + case atype_enum_nestable: field_offset += sizeof(int64_t); break; case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: field_offset += sizeof(unsigned long); field_offset += sizeof(void *); break; @@ -255,10 +261,13 @@ int apply_field_reloc(struct lttng_event *event, switch (field->type.atype) { case atype_integer: case atype_enum: + case atype_enum_nestable: op->op = FILTER_OP_LOAD_FIELD_REF_S64; break; case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE; break; case atype_string: @@ -330,12 +339,15 @@ int apply_context_reloc(struct lttng_event *event, switch (ctx_field->event_field.type.atype) { case atype_integer: case atype_enum: + case atype_enum_nestable: op->op = FILTER_OP_GET_CONTEXT_REF_S64; break; /* Sequence and array supported as string */ case atype_string: case atype_array: + case atype_array_nestable: case atype_sequence: + case atype_sequence_nestable: op->op = FILTER_OP_GET_CONTEXT_REF_STRING; break; case atype_float: diff --git a/liblttng-ust/lttng-probes.c b/liblttng-ust/lttng-probes.c index 862b19e7..9b3bacc4 100644 --- a/liblttng-ust/lttng-probes.c +++ b/liblttng-ust/lttng-probes.c @@ -385,15 +385,29 @@ int lttng_probes_get_field_list(struct lttng_ust_field_list *list) list_entry->field.type = LTTNG_UST_FIELD_STRING; break; case atype_array: - if (event_field->type.u.array.elem_type.atype != atype_integer - || event_field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) + if (event_field->type.u.legacy.array.elem_type.atype != atype_integer + || event_field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) + list_entry->field.type = LTTNG_UST_FIELD_OTHER; + else + list_entry->field.type = LTTNG_UST_FIELD_STRING; + break; + case atype_array_nestable: + if (event_field->type.u.array_nestable.elem_type->atype != atype_integer + || event_field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) list_entry->field.type = LTTNG_UST_FIELD_OTHER; else list_entry->field.type = LTTNG_UST_FIELD_STRING; break; case atype_sequence: - if (event_field->type.u.sequence.elem_type.atype != atype_integer - || event_field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) + if (event_field->type.u.legacy.sequence.elem_type.atype != atype_integer + || event_field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) + list_entry->field.type = LTTNG_UST_FIELD_OTHER; + else + list_entry->field.type = LTTNG_UST_FIELD_STRING; + break; + case atype_sequence_nestable: + if (event_field->type.u.sequence_nestable.elem_type->atype != atype_integer + || event_field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) list_entry->field.type = LTTNG_UST_FIELD_OTHER; else list_entry->field.type = LTTNG_UST_FIELD_STRING; @@ -401,7 +415,8 @@ int lttng_probes_get_field_list(struct lttng_ust_field_list *list) case atype_float: list_entry->field.type = LTTNG_UST_FIELD_FLOAT; break; - case atype_enum: + case atype_enum: /* Fall-through */ + case atype_enum_nestable: list_entry->field.type = LTTNG_UST_FIELD_ENUM; break; default: diff --git a/liblttng-ust/lttng-ust-dynamic-type.c b/liblttng-ust/lttng-ust-dynamic-type.c index d569e307..9c72e71f 100644 --- a/liblttng-ust/lttng-ust-dynamic-type.c +++ b/liblttng-ust/lttng-ust-dynamic-type.c @@ -70,8 +70,9 @@ const struct lttng_event_field dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { [LTTNG_UST_DYNAMIC_TYPE_NONE] = { .name = "none", .type = { - .atype = atype_struct, - .u._struct.nr_fields = 0, /* empty struct. */ + .atype = atype_struct_nestable, + .u.struct_nestable.nr_fields = 0, /* empty struct. */ + .u.struct_nestable.alignment = 0, }, .nowrite = 0, }, @@ -129,7 +130,7 @@ const struct lttng_event_field dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { .name = "string", .type = { .atype = atype_string, - .u.basic.string.encoding = lttng_encode_UTF8, + .u.string.encoding = lttng_encode_UTF8, }, .nowrite = 0, }, @@ -137,16 +138,11 @@ const struct lttng_event_field dt_var_fields[_NR_LTTNG_UST_DYNAMIC_TYPES] = { static const struct lttng_event_field dt_enum_field = { .name = NULL, - .type.atype = atype_enum, - .type.u.basic.enumeration.desc = &dt_enum_desc, - .type.u.basic.enumeration.container_type = { - .size = sizeof(char) * CHAR_BIT, - .alignment = lttng_alignof(char) * CHAR_BIT, - .signedness = lttng_is_signed_type(char), - .reverse_byte_order = 0, - .base = 10, - .encoding = lttng_encode_none, - }, + .type.atype = atype_enum_nestable, + .type.u.enum_nestable.desc = &dt_enum_desc, + .type.u.enum_nestable.container_type = + __LTTNG_COMPOUND_LITERAL(struct lttng_type, + __type_integer(char, BYTE_ORDER, 10, none)), .nowrite = 0, }; diff --git a/tests/ust-variant/ust-variant.c b/tests/ust-variant/ust-variant.c index 9079c26f..9a449fd4 100644 --- a/tests/ust-variant/ust-variant.c +++ b/tests/ust-variant/ust-variant.c @@ -128,23 +128,18 @@ static void __event_probe__myprobe___myevent(void * __tp_data) static const struct lttng_event_field myfields[] = { [0] = { .name = "mytag", - .type.atype = atype_enum, - .type.u.basic.enumeration.desc = &myenum_desc, - .type.u.basic.enumeration.container_type = { - .size = sizeof(char) * CHAR_BIT, - .alignment = lttng_alignof(char) * CHAR_BIT, - .signedness = lttng_is_signed_type(char), - .reverse_byte_order = 0, - .base = 10, - .encoding = lttng_encode_none, - }, + .type.atype = atype_enum_nestable, + .type.u.enum_nestable.desc = &myenum_desc, + .type.u.enum_nestable.container_type = + __LTTNG_COMPOUND_LITERAL(struct lttng_type, + __type_integer(char, BYTE_ORDER, 10, none)), .nowrite = 0, }, [1] = { .name = "myfield", .type = { - .atype = atype_variant, - .u.variant = &myvariant, + .atype = atype_variant_nestable, + .u.variant_nestable = &myvariant, }, .nowrite = 0, },