return ret;
}
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_enum_statedump(struct lttng_session *session,
+ const struct lttng_event_field *field,
+ size_t nesting)
+{
+ const struct lttng_enum_desc *enum_desc;
+ const struct lttng_integer_type *container_type;
+ int ret;
+ unsigned int i, nr_entries;
+
+ enum_desc = field->type.u.basic.enumeration.desc;
+ container_type = &field->type.u.basic.enumeration.container_type;
+ nr_entries = enum_desc->nr_entries;
+
+ ret = print_tabs(session, nesting);
+ if (ret)
+ goto end;
+ ret = lttng_metadata_printf(session,
+ "enum : integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u; } {\n",
+ container_type->size,
+ container_type->alignment,
+ container_type->signedness,
+ (container_type->encoding == lttng_encode_none)
+ ? "none"
+ : (container_type->encoding == lttng_encode_UTF8)
+ ? "UTF8"
+ : "ASCII",
+ container_type->base);
+ if (ret)
+ goto end;
+ /* Dump all entries */
+ for (i = 0; i < nr_entries; i++) {
+ const struct lttng_enum_entry *entry = &enum_desc->entries[i];
+ int j, len;
+
+ ret = print_tabs(session, nesting + 1);
+ if (ret)
+ goto end;
+ ret = lttng_metadata_printf(session,
+ "\"");
+ if (ret)
+ goto end;
+ len = strlen(entry->string);
+ /* Escape the character '"' */
+ for (j = 0; j < len; j++) {
+ char c = entry->string[j];
+
+ switch (c) {
+ case '"':
+ ret = lttng_metadata_printf(session,
+ "\\\"");
+ break;
+ case '\\':
+ ret = lttng_metadata_printf(session,
+ "\\\\");
+ break;
+ default:
+ ret = lttng_metadata_printf(session,
+ "%c", c);
+ break;
+ }
+ if (ret)
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "\" = ");
+ if (ret)
+ goto end;
+ if (entry->start.signedness)
+ ret = lttng_metadata_printf(session,
+ "%lld", (long long) entry->start.value);
+ else
+ ret = lttng_metadata_printf(session,
+ "%llu", entry->start.value);
+ if (ret)
+ goto end;
+ if (entry->start.signedness == entry->end.signedness &&
+ entry->start.value == entry->end.value) {
+ ret = lttng_metadata_printf(session,
+ ",\n");
+ } else {
+ if (entry->end.signedness) {
+ ret = lttng_metadata_printf(session,
+ " ... %lld,\n", (long long) entry->end.value);
+ } else {
+ ret = lttng_metadata_printf(session,
+ " ... %llu,\n", entry->end.value);
+ }
+ }
+ if (ret)
+ goto end;
+ }
+ ret = print_tabs(session, nesting);
+ if (ret)
+ goto end;
+ ret = lttng_metadata_printf(session, "} _%s;\n",
+ field->name);
+end:
+ return ret;
+}
+
/*
* Must be called with sessions_mutex held.
*/
field->name);
break;
case atype_enum:
- ret = print_tabs(session, nesting);
- if (ret)
- return ret;
- ret = lttng_metadata_printf(session,
- "%s _%s;\n",
- field->type.u.basic.enumeration.name,
- field->name);
+ ret = _lttng_enum_statedump(session, field, nesting);
break;
case atype_array:
{
METADATA_CHANNEL,
};
+struct lttng_enum_value {
+ unsigned long long value;
+ unsigned int signedness:1;
+};
+
struct lttng_enum_entry {
- unsigned long long start, end; /* start and end are inclusive */
+ struct lttng_enum_value start, end; /* start and end are inclusive */
const char *string;
};
union _lttng_basic_type {
struct lttng_integer_type integer;
struct {
- const char *name;
+ const struct lttng_enum_desc *desc; /* Enumeration mapping */
+ struct lttng_integer_type container_type;
} enumeration;
struct {
enum lttng_string_encodings encoding;
} u;
};
-struct lttng_enum {
+struct lttng_enum_desc {
const char *name;
- struct lttng_type container_type;
const struct lttng_enum_entry *entries;
- unsigned int len;
+ unsigned int nr_entries;
};
/* Event field description */
LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
+/* Enumerations only defined at first inclusion. */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
+ LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
#undef TRACE_SYSTEM
#define TRACE_SYSTEM syscall_entry_integers
#define TRACE_INCLUDE_FILE syscalls_integers
#include <instrumentation/syscalls/headers/syscalls_pointers.h>
#undef TRACE_INCLUDE_FILE
#undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
#undef SC_LTTNG_TRACEPOINT_EVENT
#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
compat_syscall_entry_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
#define TRACE_SYSTEM compat_syscall_entry_integers
#define TRACE_INCLUDE_FILE compat_syscalls_integers
#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
#undef TRACE_INCLUDE_FILE
#undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
#undef SC_LTTNG_TRACEPOINT_EVENT
#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
syscall_exit_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
#define TRACE_SYSTEM syscall_exit_integers
#define TRACE_INCLUDE_FILE syscalls_integers
#include <instrumentation/syscalls/headers/syscalls_integers.h>
#include <instrumentation/syscalls/headers/syscalls_pointers.h>
#undef TRACE_INCLUDE_FILE
#undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
#undef SC_LTTNG_TRACEPOINT_EVENT
#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
compat_syscall_exit_##_name)
+/* Enumerations only defined at inital inclusion (not here). */
+#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
#define TRACE_SYSTEM compat_syscall_exit_integers
#define TRACE_INCLUDE_FILE compat_syscalls_integers
#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
#undef TRACE_INCLUDE_FILE
#undef TRACE_SYSTEM
+#undef SC_LTTNG_TRACEPOINT_ENUM
#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
#undef SC_LTTNG_TRACEPOINT_EVENT
#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
#define ctf_string_nowrite(_item, _user_src) \
_ctf_string(_item, _user_src, 0, 1)
+#undef ctf_enum_nowrite
+#define ctf_enum_nowrite(_name, _type, _item, _src) \
+ _ctf_enum(_name, _type, _item, _src, 0, 1)
+
/* user src */
#undef ctf_user_integer_nowrite
#define ctf_user_integer_nowrite(_type, _item, _user_src) \
#undef ctf_user_string_nowrite
#define ctf_user_string_nowrite(_item, _user_src) \
_ctf_string(_item, _user_src, 1, 1)
+
+#undef ctf_user_enum_nowrite
+#define ctf_user_enum_nowrite(_name, _type, _item, _src) \
+ _ctf_enum(_name, _type, _item, _src, 1, 1)
#undef LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS
#define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map)
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)
+
#undef TP_PROTO
#define TP_PROTO(args...)
#undef _ctf_string
#define _ctf_string(_item, _src, _user, _nowrite)
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _nowrite)
+
/* "write" */
#undef ctf_integer
#define ctf_integer(_type, _item, _src)
#undef ctf_string
#define ctf_string(_item, _src)
+#undef ctf_enum
+#define ctf_enum(_name, _type, _item, _src)
+
#undef ctf_custom_field
#define ctf_custom_field(_type, _item, _code)
#undef ctf_string_nowrite
#define ctf_string_nowrite(_item, _src)
+#undef ctf_enum_nowrite
+#define ctf_enum_nowrite(_name, _type, _item, _src)
+
/* "user" - "write" */
#undef ctf_user_integer
#define ctf_user_integer(_type, _item, _user_src)
#undef ctf_user_string
#define ctf_user_string(_item, _user_src)
+#undef ctf_user_enum
+#define ctf_user_enum(_name, _type, _item, _src)
+
/* "user" - "nowrite" */
#undef ctf_user_integer_nowrite
#define ctf_user_integer_nowrite(_type, _item, _user_src)
#undef ctf_user_string_nowrite
#define ctf_user_string_nowrite(_item, _user_src)
+
+#undef ctf_user_enum_nowrite
+#define ctf_user_enum_nowrite(_name, _type, _item, _src)
#define ctf_string(_item, _src) \
_ctf_string(_item, _src, 0, 0)
+#undef ctf_enum
+#define ctf_enum(_name, _type, _item, _src) \
+ _ctf_enum(_name, _type, _item, _src, 0, 0)
+
/* user src */
#undef ctf_user_integer
#define ctf_user_integer(_type, _item, _src) \
#define ctf_user_string(_item, _src) \
_ctf_string(_item, _src, 1, 0)
+#undef ctf_user_enum
+#define ctf_user_enum(_name, _type, _item, _src) \
+ _ctf_enum(_name, _type, _item, _src, 1, 0)
+
/* types */
#undef ctf_integer_type
#define ctf_integer_type(_type, _src) \
#define ctf_string_type(_src) \
ctf_string(unused, _src)
+#undef ctf_enum_type
+#define ctf_enum_type(_name, _type, _src) \
+ ctf_enum(_name, _type, unused, _src)
+
/* user src types */
#undef ctf_user_integer_type
#define ctf_user_integer_type(_type, _src) \
#undef ctf_user_string_type
#define ctf_user_string_type(_src) \
ctf_user_string(unused, _src)
+
+#undef ctf_user_enum_type
+#define ctf_user_enum_type(_name, _type, _src) \
+ ctf_user_enum(_name, _type, unused, _src)
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+/*
+ * Stage 1.2 of tracepoint event generation
+ *
+ * Unfolding the enums
+ */
+#include <probes/lttng-events-reset.h> /* Reset all macros within TRACE_EVENT */
+
+/* Enumeration entry (single value) */
+#undef ctf_enum_value
+#define ctf_enum_value(_string, _value) \
+ { \
+ .start = { \
+ .signedness = lttng_is_signed_type(__typeof__(_value)), \
+ .value = lttng_is_signed_type(__typeof__(_value)) ? \
+ (long long) (_value) : (_value), \
+ }, \
+ .end = { \
+ .signedness = lttng_is_signed_type(__typeof__(_value)), \
+ .value = lttng_is_signed_type(__typeof__(_value)) ? \
+ (long long) (_value) : (_value), \
+ }, \
+ .string = (_string), \
+ },
+
+/* Enumeration entry (range) */
+#undef ctf_enum_range
+#define ctf_enum_range(_string, _range_start, _range_end) \
+ { \
+ .start = { \
+ .signedness = lttng_is_signed_type(__typeof__(_range_start)), \
+ .value = lttng_is_signed_type(__typeof__(_range_start)) ? \
+ (long long) (_range_start) : (_range_start), \
+ }, \
+ .end = { \
+ .signedness = lttng_is_signed_type(__typeof__(_range_end)), \
+ .value = lttng_is_signed_type(__typeof__(_range_end)) ? \
+ (long long) (_range_end) : (_range_end), \
+ }, \
+ .string = (_string), \
+ },
+
+#undef TP_ENUM_VALUES
+#define TP_ENUM_VALUES(...) \
+ __VA_ARGS__
+
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values) \
+ const struct lttng_enum_entry __enum_values__##_name[] = { \
+ _values \
+ };
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
/*
* Stage 2 of the trace events.
*
.user = _user, \
},
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
+ { \
+ .name = #_item, \
+ .type = { \
+ .atype = atype_enum, \
+ .u = { \
+ .basic = { \
+ .enumeration = { \
+ .desc = &__enum_##_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, \
+ }, \
+ }, \
+ }, \
+ }, \
+ }, \
+ .nowrite = _nowrite, \
+ .user = _user, \
+ },
#undef ctf_custom_field
#define ctf_custom_field(_type, _item, _code) \
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, PARAMS(_fields), _code_post)
+#undef LTTNG_TRACEPOINT_ENUM
+#define LTTNG_TRACEPOINT_ENUM(_name, _values) \
+ static const struct lttng_enum_desc __enum_##_name = { \
+ .name = #_name, \
+ .entries = __enum_values__##_name, \
+ .nr_entries = ARRAY_SIZE(__enum_values__##_name), \
+ };
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
/*
strlen(_src) + 1; \
}
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
+ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
#undef ctf_align
#define ctf_align(_type) \
__event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type));
__stack_data += sizeof(void *); \
}
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
+ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
#undef TP_PROTO
#define TP_PROTO(...) __VA_ARGS__
#undef _ctf_string
#define _ctf_string(_item, _src, _user, _nowrite)
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
+ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
+
#undef ctf_align
#define ctf_align(_type) \
__event_align = max_t(size_t, __event_align, lttng_alignof(_type));
__get_dynamic_len(dest)); \
}
+#undef _ctf_enum
+#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
+ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, _user, _nowrite)
#undef ctf_align
#define ctf_align(_type) \
#define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map) \
_LTTNG_INSTRUMENTATION(DECLARE_TRACE_NOARGS(name))
+#define LTTNG_TRACEPOINT_ENUM(_name, _values)
+
#endif /* LTTNG_TRACEPOINT_EVENT_H */