Add sequence and string support
[lttng-modules.git] / probes / lttng-types.c
1 /*
2 * probes/lttng-types.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng types.
7 */
8
9 #include <linux/module.h>
10 #include <linux/types.h>
11 #include <linux/seq_file.h>
12 #include <linux/jbd.h> /* tid_t */
13 #include <linux/debugfs.h>
14 #include "lttng-types.h"
15
16 struct dentry *lttng_types_dentry;
17
18 #undef ENTRY
19 #define ENTRY(name) [atype_##name] = #name
20
21 const char * const astract_types[NR_ABSTRACT_TYPES] = {
22 ENTRY(integer),
23 ENTRY(enum),
24 ENTRY(array),
25 ENTRY(sequence),
26 ENTRY(string),
27 };
28
29 #undef ENTRY
30 #define ENTRY(name) [lttng_encode_##name] = #name
31
32 const char * const string_encodings[NR_STRING_ENCODINGS] = {
33 ENTRY(UTF8),
34 ENTRY(ASCII),
35 };
36
37 #define STAGE_EXPORT_ENUMS
38 #include "lttng-types.h"
39 #include "lttng-type-list.h"
40 #undef STAGE_EXPORT_ENUMS
41
42 struct lttng_type lttng_types[] = {
43 #define STAGE_EXPORT_TYPES
44 #include "lttng-types.h"
45 #include "lttng-type-list.h"
46 #undef STAGE_EXPORT_TYPES
47 };
48
49 static void print_enum(struct seq_file *m, const struct lttng_enum *lttng_enum)
50 {
51 int i;
52
53 for (i = 0; i < lttng_enum->len; i++) {
54 if (lttng_enum->entries[i].start == lttng_enum->entries[i].end)
55 seq_printf(m, "\t\t{ %llu, %s },\n",
56 lttng_enum->entries[i].start,
57 lttng_enum->entries[i].string);
58 else
59 seq_printf(m, "\t\t{ { %llu, %llu }, %s },\n",
60 lttng_enum->entries[i].start,
61 lttng_enum->entries[i].end,
62 lttng_enum->entries[i].string);
63 }
64 }
65
66 static void print_event_type(struct seq_file *m, const struct lttng_type *type)
67 {
68 switch(type->atype) {
69 case atype_integer:
70 seq_printf(m, "type %s {\n"
71 "\tparent = %s;\n"
72 "\tsize = %u;\n"
73 "\tsigned = %u;\n"
74 "\talign = %u;\n",
75 type->name,
76 astract_types[type->atype],
77 type->u.integer.size,
78 type->u.integer.signedness,
79 type->u.integer.alignment);
80 if (type->u.integer.reverse_byte_order)
81 seq_printf(m, "\tbyte_order = %s;\n",
82 (__BYTE_ORDER == __LITTLE_ENDIAN) ?
83 "be" : "le");
84 seq_printf(m, "};\n");
85 break;
86 case atype_enum:
87 seq_printf(m, "type %s {\n"
88 "\tparent = %s;\n"
89 "\tparent.parent = %s;\n"
90 "\tmap = {\n",
91 type->name,
92 astract_types[type->atype],
93 type->u.enumeration.parent_type);
94 print_enum(m, &type->u.enumeration.def);
95 seq_printf(m, "\t};\n"
96 "};\n");
97 break;
98 case atype_array:
99 seq_printf(m, "type %s {\n"
100 "\tparent = %s;\n"
101 "\telem_type = %s;\n"
102 "\tlength = %u;\n"
103 "};\n", type->name,
104 astract_types[type->atype],
105 type->u.array.elem_type,
106 type->u.array.length);
107 break;
108 case atype_sequence:
109 seq_printf(m, "type %s {\n"
110 "\tparent = %s;\n"
111 "\telem_type = %s;\n"
112 "\tlength_type = %s;\n"
113 "};\n", type->name,
114 astract_types[type->atype],
115 type->u.sequence.elem_type,
116 type->u.sequence.length_type);
117 break;
118 case atype_string:
119 seq_printf(m, "type %s {\n"
120 "\tparent = %s;\n"
121 "\tencoding = %s;\n"
122 "};\n", type->name,
123 astract_types[type->atype],
124 string_encodings[type->u.string.encoding]);
125 break;
126 default:
127 seq_printf(m, "<<< unknown abstract type %s for type %s >>>\n",
128 astract_types[type->atype],
129 type->name);
130 }
131 }
132
133 static void *lttng_seq_start(struct seq_file *m, loff_t *pos)
134 {
135 struct lttng_type *type = &lttng_types[*pos];
136
137 if (type > &lttng_types[ARRAY_SIZE(lttng_types) - 1])
138 return NULL;
139 return type;
140 }
141
142 static void *lttng_seq_next(struct seq_file *m, void *v, loff_t *ppos)
143 {
144 struct lttng_type *type = &lttng_types[++(*ppos)];
145
146 if (type > &lttng_types[ARRAY_SIZE(lttng_types) - 1])
147 return NULL;
148 return type;
149 }
150
151 static void lttng_seq_stop(struct seq_file *m, void *v)
152 {
153 }
154
155 static int lttng_seq_show(struct seq_file *m, void *v)
156 {
157 struct lttng_type *type = v;
158
159 print_event_type(m, type);
160 return 0;
161 }
162
163 static const struct seq_operations lttng_types_seq_ops = {
164 .start = lttng_seq_start,
165 .next = lttng_seq_next,
166 .stop = lttng_seq_stop,
167 .show = lttng_seq_show,
168 };
169
170 static int
171 lttng_types_open(struct inode *inode, struct file *file)
172 {
173 return seq_open(file, &lttng_types_seq_ops);
174 }
175
176 static const struct file_operations lttng_types_fops = {
177 .open = lttng_types_open,
178 .read = seq_read,
179 .llseek = seq_lseek,
180 .release = seq_release_private,
181 };
182
183 static int lttng_types_init(void)
184 {
185 int ret = 0;
186
187 lttng_types_dentry = debugfs_create_file("lttng-types", S_IWUSR,
188 NULL, NULL, &lttng_types_fops);
189 if (IS_ERR(lttng_types_dentry) || !lttng_types_dentry) {
190 printk(KERN_ERR "Error creating LTTng type export file\n");
191 ret = -ENOMEM;
192 goto error;
193 }
194 error:
195 return ret;
196 }
197
198 module_init(lttng_types_init);
199
200 static void lttng_types_exit(void)
201 {
202 debugfs_remove(lttng_types_dentry);
203 }
204
205 module_exit(lttng_types_exit);
206
207 MODULE_LICENSE("GPL and additional rights");
208 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
209 MODULE_DESCRIPTION("LTTng types");
This page took 0.042373 seconds and 5 git commands to generate.