/* based used for pretty-printing output, default: decimal. */
base = decimal OR dec OR OR d OR i OR u OR 10 OR hexadecimal OR hex OR x OR X OR p OR 16
OR octal OR oct OR o OR 8 OR binary OR b OR 2;
+ /* character encoding, default: none */
+ encoding = none or UTF8 or ASCII;
}
Example of type inheritance (creation of a uint32_t named type):
align = 1;
} := int5_t;
+The character encoding field can be used to specify that the integer
+must be printed as a text character when read. e.g.:
+
+typealias integer {
+ size = 8;
+ align = 8;
+ signed = false;
+ encoding = UTF8;
+} := utf_char;
+
+
4.1.6 GNU/C bitfields
The GNU/C bitfields follow closely the integer representation, with a
TSDL meta-data representation:
- unit_type name:size:
+ unit_type name:size;
As an example, the following structure declared in C compiled by GCC:
always be defined within the scope of a structure or within fields
contained within a structure (defined recursively). A "tag" enumeration
field must appear in either the same lexical scope, prior to the variant
-field (in field declaration order), in an uppermost lexical scope (see
-Section 7.3.1), or in an uppermost dynamic scope (see Section 7.3.2).
-The type selection is indicated by the mapping from the enumeration
-value to the string used as variant type selector. The field to use as
-tag is specified by the "tag_field", specified between "< >" after the
+field (in field declaration order), in an upper lexical scope (see
+Section 7.3.1), or in an upper dynamic scope (see Section 7.3.2). The
+type selection is indicated by the mapping from the enumeration value to
+the string used as variant type selector. The field to use as tag is
+specified by the "tag_field", specified between "< >" after the
"variant" keyword for unnamed variants, and after "variant name" for
named variants.
struct {
enum : uint2_t { a, b, c } choice;
- variant example <choice> v[unsigned int];
+ unsigned int seqlen;
+ variant example <choice> v[seqlen];
}
Example of an unnamed variant:
4.2.4 Sequences
-Sequences are dynamically-sized arrays. They start with an integer that specify
-the length of the sequence, followed by an array of "inner type" elements.
-The length is the number of elements in the sequence.
+Sequences are dynamically-sized arrays. They refer to a a "length"
+unsigned integer field, which must appear in either the same lexical scope,
+prior to the sequence field (in field declaration order), in an upper
+lexical scope (see Section 7.3.1), or in an upper dynamic scope (see
+Section 7.3.2). This length field represents the number of elements in
+the sequence. The sequence per se is an array of "inner type" elements.
+
+TSDL meta-data representation for a sequence type definition:
+
+struct {
+ unsigned int length_field;
+ typedef elem_type typename[length_field];
+ typename seq_field_name;
+}
+
+A sequence can also be declared as a field type, e.g.:
+
+struct {
+ unsigned int length_field;
+ long seq_field_name[length_field];
+}
-TSDL meta-data representation for a named sequence:
+Multiple sequences can refer to the same length field, and these length
+fields can be in a different upper dynamic scope:
-typedef elem_type name[length_type];
+e.g., assuming the stream.event.header defines:
-A nameless sequence can be declared as a field type, e.g.:
+stream {
+ ...
+ id = 1;
+ event.header := struct {
+ uint16_t seq_len;
+ };
+};
-long field_name[int];
+event {
+ ...
+ stream_id = 1;
+ fields := struct {
+ long seq_a[stream.event.header.seq_len];
+ char seq_b[stream.event.header.seq_len];
+ };
+};
-The length type follows the integer types specifications, and the sequence
-elements follow the "array" specifications.
+The sequence elements follow the "array" specifications.
4.2.5 Strings
struct event_packet_header {
uint32_t magic;
- uint8_t trace_uuid[16];
+ uint8_t uuid[16];
uint32_t stream_id;
};
If the magic number is not present, tools such as "file" will have no
mean to discover the file type.
-If the trace_uuid is not present, no validation that the meta-data
-actually corresponds to the stream is performed.
+If the uuid is not present, no validation that the meta-data actually
+corresponds to the stream is performed.
If the stream_id packet header field is missing, the trace can only
contain a single stream. Its "id" field can be left out, and its events
uint64_t timestamp; /* 64-bit timestamps */
} extended;
} v;
-};
+} align(32); /* or align(8) */
6.1.2 Type 2 - Many event IDs
uint64_t timestamp; /* 64-bit timestamps */
} extended;
} v;
-};
+} align(16); /* or align(8) */
6.2 Event Context
endianness of the architecture by trying to read the CTF magic number
and its counterpart in reversed endianness. The events within the
meta-data stream have no event header nor event context. Each event only
-contains a "string" payload. Each meta-data packet start with a special
-packet header, specific to the meta-data stream, which contains,
-exactly:
+contains a "sequence" payload, which is a sequence of bits using the
+"trace.packet.header.content_size" field as a placeholder for its
+length. The formatting of this sequence of bits is a plain-text
+representation of the TSDL description. Each meta-data packet start with
+a special packet header, specific to the meta-data stream, which
+contains, exactly:
struct metadata_packet_header {
uint32_t magic; /* 0x75D11D57 */
- uint8_t trace_uuid[16]; /* Unique Universal Identifier */
+ uint8_t uuid[16]; /* Unique Universal Identifier */
uint32_t checksum; /* 0 if unused */
uint32_t content_size; /* in bits */
uint32_t packet_size; /* in bits */
TSDL uses two different types of scoping: a lexical scope is used for
declarations and type definitions, and a dynamic scope is used for
-variants references to tag fields.
+variants references to tag fields and for sequence references to length
+fields.
7.3.1 Lexical Scope
A dynamic scope consists in the lexical scope augmented with the
implicit event structure definition hierarchy presented at Section 6.
-The dynamic scope is only used for variant tag definitions. It is used
-at definition time to look up the location of the tag field associated
-with a variant.
-
-Therefore, variants in lower levels in the dynamic scope (e.g. event
-context) can refer to a tag field located in upper levels (e.g. in the
-event header) by specifying, in this case, the associated tag with
-<header.field_name>. This allows, for instance, the event context to
-define a variant referring to the "id" field of the event header as
-selector.
+The dynamic scope is used for variant tag and sequence length
+definitions. It is used at definition time to look up the location of
+the tag field associated with a variant, and to lookup up the location
+of the length field associated with a sequence.
+
+Therefore, variants (or sequences) in lower levels in the dynamic scope
+(e.g. event context) can refer to a tag (or length) field located in
+upper levels (e.g. in the event header) by specifying, in this case, the
+associated tag with <header.field_name>. This allows, for instance, the
+event context to define a variant referring to the "id" field of the
+event header as selector.
The target dynamic scope must be specified explicitly when referring to
a field outside of the local static scope. The dynamic scope prefixes
byte_order = be OR le; /* Endianness (required) */
packet.header := struct {
uint32_t magic;
- uint8_t trace_uuid[16];
+ uint8_t uuid[16];
uint32_t stream_id;
};
};
type-assignment-operator:
:=
-constant-expression:
- unary-expression
-
constant-expression-range:
- constant-expression ... constant-expression
+ unary-expression ... unary-expression
2.2) Declarations:
ctf-type-specifier
align-attribute:
- align ( constant-expression )
+ align ( unary-expression )
struct-specifier:
struct identifier-opt { struct-or-variant-declaration-list-opt } align-attribute-opt
struct-or-variant-declaration:
specifier-qualifier-list struct-or-variant-declarator-list ;
- declaration-specifiers storage-class-specifier declaration-specifiers declarator-list ;
- typealias declaration-specifiers abstract-declarator-list := declaration-specifiers abstract-declarator-list ;
- typealias declaration-specifiers abstract-declarator-list := declarator-list ;
+ declaration-specifiers-opt storage-class-specifier declaration-specifiers-opt declarator-list ;
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declaration-specifiers abstract-declarator-list ;
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declarator-list ;
specifier-qualifier-list:
type-specifier specifier-qualifier-list-opt
struct-or-variant-declarator:
declarator
- declarator-opt : constant-expression
+ declarator-opt : unary-expression
variant-specifier:
variant identifier-opt variant-tag-opt { struct-or-variant-declaration-list }
enumerator:
enumeration-constant
- enumeration-constant = constant-expression
- enumeration-constant = constant-expression-range
+ enumeration-constant assignment-operator unary-expression
+ enumeration-constant assignment-operator constant-expression-range
type-qualifier:
const
direct-declarator:
identifier
( declarator )
- direct-declarator [ type-specifier ]
- direct-declarator [ constant-expression ]
+ direct-declarator [ unary-expression ]
abstract-declarator:
pointer-opt direct-abstract-declarator
direct-abstract-declarator:
identifier-opt
( abstract-declarator )
- direct-abstract-declarator [ type-specifier ]
- direct-abstract-declarator [ constant-expression ]
+ direct-abstract-declarator [ unary-expression ]
direct-abstract-declarator [ ]
pointer:
event { ctf-assignment-expression-list-opt }
stream { ctf-assignment-expression-list-opt }
trace { ctf-assignment-expression-list-opt }
- typealias declaration-specifiers abstract-declarator-list := declaration-specifiers abstract-declarator-list ;
- typealias declaration-specifiers abstract-declarator-list := declarator-list ;
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declaration-specifiers abstract-declarator-list ;
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declarator-list ;
ctf-type-specifier:
floating_point { ctf-assignment-expression-list-opt }
integer { ctf-assignment-expression-list-opt }
string { ctf-assignment-expression-list-opt }
+ string
ctf-assignment-expression-list:
- ctf-assignment-expression
- ctf-assignment-expression-list ; ctf-assignment-expression
+ ctf-assignment-expression ;
+ ctf-assignment-expression-list ctf-assignment-expression ;
ctf-assignment-expression:
unary-expression assignment-operator unary-expression
unary-expression type-assignment-operator type-specifier
- declaration-specifiers storage-class-specifier declaration-specifiers declarator-list
- typealias declaration-specifiers abstract-declarator-list := declaration-specifiers abstract-declarator-list
- typealias declaration-specifiers abstract-declarator-list := declarator-list
+ declaration-specifiers-opt storage-class-specifier declaration-specifiers-opt declarator-list
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declaration-specifiers abstract-declarator-list
+ typealias declaration-specifiers abstract-declarator-list type-assignment-operator declarator-list