/*
- * ust-metadata.c
- *
- * LTTng-UST metadata generation
- *
* Copyright (C) 2010-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _LGPL_SOURCE
static
int _lttng_field_statedump(struct ust_registry_session *session,
- const struct ustctl_field *fields, size_t nr_fields,
+ const struct lttng_ust_ctl_field *fields, size_t nr_fields,
size_t *iter_field, size_t nesting);
-static inline
-int fls(unsigned int x)
-{
- int r = 32;
-
- if (!x)
- return 0;
- if (!(x & 0xFFFF0000U)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xFF000000U)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xF0000000U)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xC0000000U)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000U)) {
- r -= 1;
- }
- return r;
-}
-
static inline
int get_count_order(unsigned int count)
{
int order;
- order = fls(count) - 1;
+ order = lttng_fls(count) - 1;
if (count & (count - 1)) {
order++;
}
{
size_t i;
- for (i = 0; i < LTTNG_UST_SYM_NAME_LEN; i++) {
+ for (i = 0; i < LTTNG_UST_ABI_SYM_NAME_LEN; i++) {
switch (in[i]) {
case '.':
case '$':
int ust_metadata_enum_statedump(struct ust_registry_session *session,
const char *enum_name,
uint64_t enum_id,
- const struct ustctl_integer_type *container_type,
+ const struct lttng_ust_ctl_integer_type *container_type,
const char *field_name, size_t *iter_field, size_t nesting)
{
struct ust_registry_enum *reg_enum;
- const struct ustctl_enum_entry *entries;
+ const struct lttng_ust_ctl_enum_entry *entries;
size_t nr_entries;
int ret = 0;
size_t i;
- char identifier[LTTNG_UST_SYM_NAME_LEN];
+ char identifier[LTTNG_UST_ABI_SYM_NAME_LEN];
rcu_read_lock();
reg_enum = ust_registry_lookup_enum_by_id(session, enum_name, enum_id);
container_type->size,
container_type->alignment,
container_type->signedness,
- (container_type->encoding == ustctl_encode_none)
+ (container_type->encoding == lttng_ust_ctl_encode_none)
? "none"
- : (container_type->encoding == ustctl_encode_UTF8)
+ : (container_type->encoding == lttng_ust_ctl_encode_UTF8)
? "UTF8"
: "ASCII",
container_type->base);
nesting++;
/* Dump all entries */
for (i = 0; i < nr_entries; i++) {
- const struct ustctl_enum_entry *entry = &entries[i];
+ const struct lttng_ust_ctl_enum_entry *entry = &entries[i];
int j, len;
ret = print_tabs(session, nesting);
}
if (entry->u.extra.options &
- USTCTL_UST_ENUM_ENTRY_OPTION_IS_AUTO) {
+ LTTNG_UST_CTL_UST_ENUM_ENTRY_OPTION_IS_AUTO) {
ret = lttng_metadata_printf(session, ",\n");
if (ret) {
goto end;
static
int _lttng_variant_statedump(struct ust_registry_session *session,
- const struct ustctl_field *fields, size_t nr_fields,
+ uint32_t nr_choices, const char *tag_name,
+ uint32_t alignment,
+ const struct lttng_ust_ctl_field *fields, size_t nr_fields,
size_t *iter_field, size_t nesting)
{
- const struct ustctl_field *variant = &fields[*iter_field];
- uint32_t nr_choices, i;
+ const struct lttng_ust_ctl_field *variant = &fields[*iter_field];
+ uint32_t i;
int ret;
- char identifier[LTTNG_UST_SYM_NAME_LEN];
+ char identifier[LTTNG_UST_ABI_SYM_NAME_LEN];
- if (variant->type.atype != ustctl_atype_variant) {
+ if (variant->type.atype != lttng_ust_ctl_atype_variant) {
ret = -EINVAL;
goto end;
}
- nr_choices = variant->type.u.variant.nr_choices;
(*iter_field)++;
- sanitize_ctf_identifier(identifier, variant->type.u.variant.tag_name);
+ sanitize_ctf_identifier(identifier, tag_name);
+ if (alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ alignment * CHAR_BIT,
+ variant->name);
+ if (ret) {
+ goto end;
+ }
+ }
ret = print_tabs(session, nesting);
if (ret) {
goto end;
static
int _lttng_field_statedump(struct ust_registry_session *session,
- const struct ustctl_field *fields, size_t nr_fields,
+ const struct lttng_ust_ctl_field *fields, size_t nr_fields,
size_t *iter_field, size_t nesting)
{
int ret = 0;
const char *bo_le = " byte_order = le;";
const char *bo_native = "";
const char *bo_reverse;
- const struct ustctl_field *field;
+ const struct lttng_ust_ctl_field *field;
if (*iter_field >= nr_fields) {
ret = -EOVERFLOW;
}
switch (field->type.atype) {
- case ustctl_atype_integer:
+ case lttng_ust_ctl_atype_integer:
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
- field->type.u.basic.integer.size,
- field->type.u.basic.integer.alignment,
- field->type.u.basic.integer.signedness,
- (field->type.u.basic.integer.encoding == ustctl_encode_none)
+ field->type.u.integer.size,
+ field->type.u.integer.alignment,
+ field->type.u.integer.signedness,
+ (field->type.u.integer.encoding == lttng_ust_ctl_encode_none)
? "none"
- : (field->type.u.basic.integer.encoding == ustctl_encode_UTF8)
+ : (field->type.u.integer.encoding == lttng_ust_ctl_encode_UTF8)
? "UTF8"
: "ASCII",
- field->type.u.basic.integer.base,
- field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->type.u.integer.base,
+ field->type.u.integer.reverse_byte_order ? bo_reverse : bo_native,
field->name);
(*iter_field)++;
break;
- case ustctl_atype_enum:
+ case lttng_ust_ctl_atype_enum:
ret = ust_metadata_enum_statedump(session,
- field->type.u.basic.enumeration.name,
- field->type.u.basic.enumeration.id,
- &field->type.u.basic.enumeration.container_type,
+ field->type.u.legacy.basic.enumeration.name,
+ field->type.u.legacy.basic.enumeration.id,
+ &field->type.u.legacy.basic.enumeration.container_type,
field->name, iter_field, nesting);
break;
- case ustctl_atype_float:
+ case lttng_ust_ctl_atype_float:
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
ret = lttng_metadata_printf(session,
"floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n",
- field->type.u.basic._float.exp_dig,
- field->type.u.basic._float.mant_dig,
- field->type.u.basic._float.alignment,
- field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->type.u._float.exp_dig,
+ field->type.u._float.mant_dig,
+ field->type.u._float.alignment,
+ field->type.u._float.reverse_byte_order ? bo_reverse : bo_native,
field->name);
(*iter_field)++;
break;
- case ustctl_atype_array:
+ case lttng_ust_ctl_atype_array:
{
- const struct ustctl_basic_type *elem_type;
+ const struct lttng_ust_ctl_basic_type *elem_type;
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
- elem_type = &field->type.u.array.elem_type;
+ elem_type = &field->type.u.legacy.array.elem_type;
+ /* Only integers are currently supported in arrays. */
+ if (elem_type->atype != lttng_ust_ctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
elem_type->u.basic.integer.size,
elem_type->u.basic.integer.alignment,
elem_type->u.basic.integer.signedness,
- (elem_type->u.basic.integer.encoding == ustctl_encode_none)
+ (elem_type->u.basic.integer.encoding == lttng_ust_ctl_encode_none)
? "none"
- : (elem_type->u.basic.integer.encoding == ustctl_encode_UTF8)
+ : (elem_type->u.basic.integer.encoding == lttng_ust_ctl_encode_UTF8)
? "UTF8"
: "ASCII",
elem_type->u.basic.integer.base,
elem_type->u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
- field->name, field->type.u.array.length);
+ field->name, field->type.u.legacy.array.length);
(*iter_field)++;
break;
}
- case ustctl_atype_sequence:
+ case lttng_ust_ctl_atype_array_nestable:
{
- const struct ustctl_basic_type *elem_type;
- const struct ustctl_basic_type *length_type;
+ uint32_t array_length;
+ const struct lttng_ust_ctl_field *array_nestable;
+ const struct lttng_ust_ctl_type *elem_type;
+
+ array_length = field->type.u.array_nestable.length;
+ (*iter_field)++;
+
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ array_nestable = &fields[*iter_field];
+ elem_type = &array_nestable->type;
+
+ /* Only integers are currently supported in arrays. */
+ if (elem_type->atype != lttng_ust_ctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (field->type.u.array_nestable.alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ field->type.u.array_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ }
- elem_type = &field->type.u.sequence.elem_type;
- length_type = &field->type.u.sequence.length_type;
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
+ ret = lttng_metadata_printf(session,
+ "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
+ elem_type->u.integer.size,
+ elem_type->u.integer.alignment,
+ elem_type->u.integer.signedness,
+ (elem_type->u.integer.encoding == lttng_ust_ctl_encode_none)
+ ? "none"
+ : (elem_type->u.integer.encoding == lttng_ust_ctl_encode_UTF8)
+ ? "UTF8"
+ : "ASCII",
+ elem_type->u.integer.base,
+ elem_type->u.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->name, array_length);
+ (*iter_field)++;
+ break;
+ }
+ case lttng_ust_ctl_atype_sequence:
+ {
+ const struct lttng_ust_ctl_basic_type *elem_type;
+ const struct lttng_ust_ctl_basic_type *length_type;
+
+ elem_type = &field->type.u.legacy.sequence.elem_type;
+ length_type = &field->type.u.legacy.sequence.length_type;
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+
+ /* Only integers are currently supported in sequences. */
+ if (elem_type->atype != lttng_ust_ctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
length_type->u.basic.integer.size,
(unsigned int) length_type->u.basic.integer.alignment,
length_type->u.basic.integer.signedness,
- (length_type->u.basic.integer.encoding == ustctl_encode_none)
+ (length_type->u.basic.integer.encoding == lttng_ust_ctl_encode_none)
? "none"
- : ((length_type->u.basic.integer.encoding == ustctl_encode_UTF8)
+ : ((length_type->u.basic.integer.encoding == lttng_ust_ctl_encode_UTF8)
? "UTF8"
: "ASCII"),
length_type->u.basic.integer.base,
elem_type->u.basic.integer.size,
(unsigned int) elem_type->u.basic.integer.alignment,
elem_type->u.basic.integer.signedness,
- (elem_type->u.basic.integer.encoding == ustctl_encode_none)
+ (elem_type->u.basic.integer.encoding == lttng_ust_ctl_encode_none)
? "none"
- : ((elem_type->u.basic.integer.encoding == ustctl_encode_UTF8)
+ : ((elem_type->u.basic.integer.encoding == lttng_ust_ctl_encode_UTF8)
? "UTF8"
: "ASCII"),
elem_type->u.basic.integer.base,
(*iter_field)++;
break;
}
+ case lttng_ust_ctl_atype_sequence_nestable:
+ {
+ const struct lttng_ust_ctl_field *sequence_nestable;
+ const struct lttng_ust_ctl_type *elem_type;
- case ustctl_atype_string:
+ (*iter_field)++;
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ sequence_nestable = &fields[*iter_field];
+ elem_type = &sequence_nestable->type;
+
+ /* Only integers are currently supported in sequences. */
+ if (elem_type->atype != lttng_ust_ctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (field->type.u.sequence_nestable.alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ field->type.u.sequence_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ _%s ];\n",
+ elem_type->u.integer.size,
+ (unsigned int) elem_type->u.integer.alignment,
+ elem_type->u.integer.signedness,
+ (elem_type->u.integer.encoding == lttng_ust_ctl_encode_none)
+ ? "none"
+ : ((elem_type->u.integer.encoding == lttng_ust_ctl_encode_UTF8)
+ ? "UTF8"
+ : "ASCII"),
+ elem_type->u.integer.base,
+ elem_type->u.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->name,
+ field->type.u.sequence_nestable.length_name);
+ (*iter_field)++;
+ break;
+ }
+ case lttng_ust_ctl_atype_string:
/* Default encoding is UTF8 */
ret = print_tabs(session, nesting);
if (ret) {
}
ret = lttng_metadata_printf(session,
"string%s _%s;\n",
- field->type.u.basic.string.encoding == ustctl_encode_ASCII ?
+ field->type.u.string.encoding == lttng_ust_ctl_encode_ASCII ?
" { encoding = ASCII; }" : "",
field->name);
(*iter_field)++;
break;
- case ustctl_atype_variant:
- ret = _lttng_variant_statedump(session, fields, nr_fields, iter_field, nesting);
+ case lttng_ust_ctl_atype_variant:
+ ret = _lttng_variant_statedump(session,
+ field->type.u.legacy.variant.nr_choices,
+ field->type.u.legacy.variant.tag_name,
+ 0,
+ fields, nr_fields, iter_field, nesting);
if (ret) {
goto end;
}
break;
- case ustctl_atype_struct:
+ case lttng_ust_ctl_atype_variant_nestable:
+ ret = _lttng_variant_statedump(session,
+ field->type.u.variant_nestable.nr_choices,
+ field->type.u.variant_nestable.tag_name,
+ field->type.u.variant_nestable.alignment,
+ fields, nr_fields, iter_field, nesting);
+ if (ret) {
+ goto end;
+ }
+ break;
+ case lttng_ust_ctl_atype_struct:
+ if (field->type.u.legacy._struct.nr_fields != 0) {
+ /* Currently only 0-length structures are supported. */
+ ret = -EINVAL;
+ goto end;
+ }
ret = print_tabs(session, nesting);
if (ret) {
goto end;
field->name);
(*iter_field)++;
break;
+ case lttng_ust_ctl_atype_struct_nestable:
+ if (field->type.u.struct_nestable.nr_fields != 0) {
+ /* Currently only 0-length structures are supported. */
+ ret = -EINVAL;
+ goto end;
+ }
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ if (field->type.u.struct_nestable.alignment) {
+ ret = lttng_metadata_printf(session,
+ "struct {} align(%u) _%s;\n",
+ field->type.u.struct_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ } else {
+ ret = lttng_metadata_printf(session,
+ "struct {} _%s;\n",
+ field->name);
+ }
+ (*iter_field)++;
+ break;
+ case lttng_ust_ctl_atype_enum_nestable:
+ {
+ const struct lttng_ust_ctl_field *container_field;
+ const struct lttng_ust_ctl_type *container_type;
+
+ (*iter_field)++;
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ container_field = &fields[*iter_field];
+ container_type = &container_field->type;
+
+ /* Only integers are supported as container types. */
+ if (container_type->atype != lttng_ust_ctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+ ret = ust_metadata_enum_statedump(session,
+ field->type.u.enum_nestable.name,
+ field->type.u.enum_nestable.id,
+ &container_type->u.integer,
+ field->name, iter_field, nesting);
+ break;
+ }
default:
ret = -EINVAL;
}
static
int _lttng_context_metadata_statedump(struct ust_registry_session *session,
size_t nr_ctx_fields,
- struct ustctl_field *ctx)
+ struct lttng_ust_ctl_field *ctx)
{
int ret = 0;
size_t i = 0;
event->name,
event->id,
chan->chan_id);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
" loglevel = %d;\n",
event->loglevel_value);
- if (ret)
+ if (ret) {
goto end;
+ }
if (event->model_emf_uri) {
ret = lttng_metadata_printf(session,
" model.emf.uri = \"%s\";\n",
event->model_emf_uri);
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
" fields := struct {\n"
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_fields_metadata_statedump(session, event);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
" };\n"
"};\n\n");
- if (ret)
+ if (ret) {
goto end;
+ }
event->metadata_dumped = 1;
end:
" event.header := %s;\n"
" packet.context := struct packet_context;\n",
chan->chan_id,
- chan->header_type == USTCTL_CHANNEL_HEADER_COMPACT ?
+ chan->header_type == LTTNG_UST_CTL_CHANNEL_HEADER_COMPACT ?
"struct event_header_compact" :
"struct event_header_large");
- if (ret)
+ if (ret) {
goto end;
+ }
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" event.context := struct {\n");
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = _lttng_context_metadata_statedump(session,
chan->nr_ctx_fields,
chan->ctx_fields);
- if (ret)
+ if (ret) {
goto end;
+ }
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" };\n");
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
uuid_s,
session->byte_order == BIG_ENDIAN ? "be" : "le"
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
"env {\n"
ret = lttng_metadata_printf(session,
"};\n\n"
);
- if (ret)
+ if (ret) {
goto end;
-
+ }
ret = lttng_metadata_printf(session,
"clock {\n"
" name = \"%s\";\n",
trace_clock_name()
);
- if (ret)
+ if (ret) {
goto end;
+ }
if (!trace_clock_uuid(clock_uuid_s)) {
ret = lttng_metadata_printf(session,
" uuid = \"%s\";\n",
clock_uuid_s
);
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
trace_clock_freq(),
measure_clock_offset()
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
"typealias integer {\n"
session->uint64_t_alignment,
trace_clock_name()
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_stream_packet_context_declare(session);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_event_header_declare(session);
- if (ret)
+ if (ret) {
goto end;
+ }
end:
return ret;