diff options
Diffstat (limited to 'parse-events.c')
-rw-r--r-- | parse-events.c | 453 |
1 files changed, 258 insertions, 195 deletions
diff --git a/parse-events.c b/parse-events.c index 8a59433..fe683c9 100644 --- a/parse-events.c +++ b/parse-events.c | |||
@@ -30,27 +30,10 @@ | |||
30 | 30 | ||
31 | #include "parse-events.h" | 31 | #include "parse-events.h" |
32 | 32 | ||
33 | int header_page_ts_offset; | ||
34 | int header_page_ts_size; | ||
35 | int header_page_size_offset; | ||
36 | int header_page_size_size; | ||
37 | int header_page_data_offset; | ||
38 | int header_page_data_size; | ||
39 | |||
40 | int file_bigendian; | ||
41 | int host_bigendian; | ||
42 | |||
43 | int latency_format; | ||
44 | |||
45 | int old_format; | ||
46 | |||
47 | static char *input_buf; | 33 | static char *input_buf; |
48 | static unsigned long long input_buf_ptr; | 34 | static unsigned long long input_buf_ptr; |
49 | static unsigned long long input_buf_siz; | 35 | static unsigned long long input_buf_siz; |
50 | 36 | ||
51 | static int cpus; | ||
52 | static int long_size; | ||
53 | |||
54 | static void init_input_buf(char *buf, unsigned long long size) | 37 | static void init_input_buf(char *buf, unsigned long long size) |
55 | { | 38 | { |
56 | input_buf = buf; | 39 | input_buf = buf; |
@@ -69,9 +52,6 @@ struct cmdline { | |||
69 | int pid; | 52 | int pid; |
70 | }; | 53 | }; |
71 | 54 | ||
72 | static struct cmdline *cmdlines; | ||
73 | static int cmdline_count; | ||
74 | |||
75 | static int cmdline_cmp(const void *a, const void *b) | 55 | static int cmdline_cmp(const void *a, const void *b) |
76 | { | 56 | { |
77 | const struct cmdline *ca = a; | 57 | const struct cmdline *ca = a; |
@@ -85,18 +65,20 @@ static int cmdline_cmp(const void *a, const void *b) | |||
85 | return 0; | 65 | return 0; |
86 | } | 66 | } |
87 | 67 | ||
88 | static struct cmdline_list { | 68 | struct cmdline_list { |
89 | struct cmdline_list *next; | 69 | struct cmdline_list *next; |
90 | char *comm; | 70 | char *comm; |
91 | int pid; | 71 | int pid; |
92 | } *cmdlist; | 72 | }; |
93 | 73 | ||
94 | static int cmdline_init(void) | 74 | static int cmdline_init(struct pevent *pevent) |
95 | { | 75 | { |
76 | struct cmdline_list *cmdlist = pevent->cmdlist; | ||
96 | struct cmdline_list *item; | 77 | struct cmdline_list *item; |
78 | struct cmdline *cmdlines; | ||
97 | int i; | 79 | int i; |
98 | 80 | ||
99 | cmdlines = malloc_or_die(sizeof(*cmdlines) * cmdline_count); | 81 | cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count); |
100 | 82 | ||
101 | i = 0; | 83 | i = 0; |
102 | while (cmdlist) { | 84 | while (cmdlist) { |
@@ -108,12 +90,15 @@ static int cmdline_init(void) | |||
108 | free(item); | 90 | free(item); |
109 | } | 91 | } |
110 | 92 | ||
111 | qsort(cmdlines, cmdline_count, sizeof(*cmdlines), cmdline_cmp); | 93 | qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); |
94 | |||
95 | pevent->cmdlines = cmdlines; | ||
96 | pevent->cmdlist = NULL; | ||
112 | 97 | ||
113 | return 0; | 98 | return 0; |
114 | } | 99 | } |
115 | 100 | ||
116 | static char *find_cmdline(int pid) | 101 | static char *find_cmdline(struct pevent *pevent, int pid) |
117 | { | 102 | { |
118 | const struct cmdline *comm; | 103 | const struct cmdline *comm; |
119 | struct cmdline key; | 104 | struct cmdline key; |
@@ -121,47 +106,46 @@ static char *find_cmdline(int pid) | |||
121 | if (!pid) | 106 | if (!pid) |
122 | return "<idle>"; | 107 | return "<idle>"; |
123 | 108 | ||
124 | if (!cmdlines) | 109 | if (!pevent->cmdlines) |
125 | cmdline_init(); | 110 | cmdline_init(pevent); |
126 | 111 | ||
127 | key.pid = pid; | 112 | key.pid = pid; |
128 | 113 | ||
129 | comm = bsearch(&key, cmdlines, cmdline_count, sizeof(*cmdlines), | 114 | comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, |
130 | cmdline_cmp); | 115 | sizeof(*pevent->cmdlines), cmdline_cmp); |
131 | 116 | ||
132 | if (comm) | 117 | if (comm) |
133 | return comm->comm; | 118 | return comm->comm; |
134 | return "<...>"; | 119 | return "<...>"; |
135 | } | 120 | } |
136 | 121 | ||
137 | int pevent_register_comm(char *comm, int pid) | 122 | int pevent_register_comm(struct pevent *pevent, char *comm, int pid) |
138 | { | 123 | { |
139 | struct cmdline_list *item; | 124 | struct cmdline_list *item; |
140 | 125 | ||
141 | item = malloc_or_die(sizeof(*item)); | 126 | item = malloc_or_die(sizeof(*item)); |
142 | item->comm = comm; | 127 | item->comm = comm; |
143 | item->pid = pid; | 128 | item->pid = pid; |
144 | item->next = cmdlist; | 129 | item->next = pevent->cmdlist; |
145 | 130 | ||
146 | cmdlist = item; | 131 | pevent->cmdlist = item; |
147 | cmdline_count++; | 132 | pevent->cmdline_count++; |
148 | 133 | ||
149 | return 0; | 134 | return 0; |
150 | } | 135 | } |
151 | 136 | ||
152 | static struct func_map { | 137 | struct func_map { |
153 | unsigned long long addr; | 138 | unsigned long long addr; |
154 | char *func; | 139 | char *func; |
155 | char *mod; | 140 | char *mod; |
156 | } *func_map; | 141 | }; |
157 | static unsigned int func_count; | ||
158 | 142 | ||
159 | static struct func_list { | 143 | struct func_list { |
160 | struct func_list *next; | 144 | struct func_list *next; |
161 | unsigned long long addr; | 145 | unsigned long long addr; |
162 | char *func; | 146 | char *func; |
163 | char *mod; | 147 | char *mod; |
164 | } *funclist; | 148 | }; |
165 | 149 | ||
166 | static int func_cmp(const void *a, const void *b) | 150 | static int func_cmp(const void *a, const void *b) |
167 | { | 151 | { |
@@ -197,12 +181,15 @@ static int func_bcmp(const void *a, const void *b) | |||
197 | return 1; | 181 | return 1; |
198 | } | 182 | } |
199 | 183 | ||
200 | static int func_map_init(void) | 184 | static int func_map_init(struct pevent *pevent) |
201 | { | 185 | { |
186 | struct func_list *funclist; | ||
202 | struct func_list *item; | 187 | struct func_list *item; |
188 | struct func_map *func_map; | ||
203 | int i; | 189 | int i; |
204 | 190 | ||
205 | func_map = malloc_or_die(sizeof(*func_map) * func_count + 1); | 191 | func_map = malloc_or_die(sizeof(*func_map) * pevent->func_count + 1); |
192 | funclist = pevent->funclist; | ||
206 | 193 | ||
207 | i = 0; | 194 | i = 0; |
208 | while (funclist) { | 195 | while (funclist) { |
@@ -215,90 +202,96 @@ static int func_map_init(void) | |||
215 | free(item); | 202 | free(item); |
216 | } | 203 | } |
217 | 204 | ||
218 | qsort(func_map, func_count, sizeof(*func_map), func_cmp); | 205 | qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp); |
219 | 206 | ||
220 | /* | 207 | /* |
221 | * Add a special record at the end. | 208 | * Add a special record at the end. |
222 | */ | 209 | */ |
223 | func_map[func_count].func = NULL; | 210 | func_map[pevent->func_count].func = NULL; |
224 | func_map[func_count].addr = 0; | 211 | func_map[pevent->func_count].addr = 0; |
225 | func_map[func_count].mod = NULL; | 212 | func_map[pevent->func_count].mod = NULL; |
213 | |||
214 | pevent->func_map = func_map; | ||
215 | pevent->funclist = NULL; | ||
226 | 216 | ||
227 | return 0; | 217 | return 0; |
228 | } | 218 | } |
229 | 219 | ||
230 | static struct func_map *find_func(unsigned long long addr) | 220 | static struct func_map * |
221 | find_func(struct pevent *pevent, unsigned long long addr) | ||
231 | { | 222 | { |
232 | struct func_map *func; | 223 | struct func_map *func; |
233 | struct func_map key; | 224 | struct func_map key; |
234 | 225 | ||
235 | if (!func_map) | 226 | if (!pevent->func_map) |
236 | func_map_init(); | 227 | func_map_init(pevent); |
237 | 228 | ||
238 | key.addr = addr; | 229 | key.addr = addr; |
239 | 230 | ||
240 | func = bsearch(&key, func_map, func_count, sizeof(*func_map), | 231 | func = bsearch(&key, pevent->func_map, pevent->func_count, |
241 | func_bcmp); | 232 | sizeof(*pevent->func_map), func_bcmp); |
242 | 233 | ||
243 | return func; | 234 | return func; |
244 | } | 235 | } |
245 | 236 | ||
246 | const char *pevent_find_function(unsigned long long addr) | 237 | const char *pevent_find_function(struct pevent *pevent, unsigned long long addr) |
247 | { | 238 | { |
248 | struct func_map *map; | 239 | struct func_map *map; |
249 | 240 | ||
250 | map = find_func(addr); | 241 | map = find_func(pevent, addr); |
251 | if (!map) | 242 | if (!map) |
252 | return NULL; | 243 | return NULL; |
253 | 244 | ||
254 | return map->func; | 245 | return map->func; |
255 | } | 246 | } |
256 | 247 | ||
257 | int pevent_register_function(char *func, unsigned long long addr, | 248 | int pevent_register_function(struct pevent *pevent, char *func, |
258 | char *mod) | 249 | unsigned long long addr, char *mod) |
259 | { | 250 | { |
260 | struct func_list *item; | 251 | struct func_list *item; |
261 | 252 | ||
262 | item = malloc_or_die(sizeof(*item)); | 253 | item = malloc_or_die(sizeof(*item)); |
263 | 254 | ||
264 | item->next = funclist; | 255 | item->next = pevent->funclist; |
265 | item->func = func; | 256 | item->func = func; |
266 | item->mod = mod; | 257 | item->mod = mod; |
267 | item->addr = addr; | 258 | item->addr = addr; |
268 | 259 | ||
269 | funclist = item; | 260 | pevent->funclist = item; |
270 | 261 | ||
271 | func_count++; | 262 | pevent->func_count++; |
272 | 263 | ||
273 | return 0; | 264 | return 0; |
274 | } | 265 | } |
275 | 266 | ||
276 | void pevent_print_funcs(void) | 267 | void pevent_print_funcs(struct pevent *pevent) |
277 | { | 268 | { |
278 | int i; | 269 | int i; |
279 | 270 | ||
280 | for (i = 0; i < (int)func_count; i++) { | 271 | if (!pevent->func_map) |
272 | func_map_init(pevent); | ||
273 | |||
274 | for (i = 0; i < (int)pevent->func_count; i++) { | ||
281 | printf("%016llx %s", | 275 | printf("%016llx %s", |
282 | func_map[i].addr, | 276 | pevent->func_map[i].addr, |
283 | func_map[i].func); | 277 | pevent->func_map[i].func); |
284 | if (func_map[i].mod) | 278 | if (pevent->func_map[i].mod) |
285 | printf(" [%s]\n", func_map[i].mod); | 279 | printf(" [%s]\n", pevent->func_map[i].mod); |
286 | else | 280 | else |
287 | printf("\n"); | 281 | printf("\n"); |
288 | } | 282 | } |
289 | } | 283 | } |
290 | 284 | ||
291 | static struct printk_map { | 285 | struct printk_map { |
292 | unsigned long long addr; | 286 | unsigned long long addr; |
293 | char *printk; | 287 | char *printk; |
294 | } *printk_map; | 288 | }; |
295 | static unsigned int printk_count; | ||
296 | 289 | ||
297 | static struct printk_list { | 290 | struct printk_list { |
298 | struct printk_list *next; | 291 | struct printk_list *next; |
299 | unsigned long long addr; | 292 | unsigned long long addr; |
300 | char *printk; | 293 | char *printk; |
301 | } *printklist; | 294 | }; |
302 | 295 | ||
303 | static int printk_cmp(const void *a, const void *b) | 296 | static int printk_cmp(const void *a, const void *b) |
304 | { | 297 | { |
@@ -313,12 +306,16 @@ static int printk_cmp(const void *a, const void *b) | |||
313 | return 0; | 306 | return 0; |
314 | } | 307 | } |
315 | 308 | ||
316 | static void printk_map_init(void) | 309 | static void printk_map_init(struct pevent *pevent) |
317 | { | 310 | { |
311 | struct printk_list *printklist; | ||
318 | struct printk_list *item; | 312 | struct printk_list *item; |
313 | struct printk_map *printk_map; | ||
319 | int i; | 314 | int i; |
320 | 315 | ||
321 | printk_map = malloc_or_die(sizeof(*printk_map) * printk_count + 1); | 316 | printk_map = malloc_or_die(sizeof(*printk_map) * pevent->printk_count + 1); |
317 | |||
318 | printklist = pevent->printklist; | ||
322 | 319 | ||
323 | i = 0; | 320 | i = 0; |
324 | while (printklist) { | 321 | while (printklist) { |
@@ -330,49 +327,57 @@ static void printk_map_init(void) | |||
330 | free(item); | 327 | free(item); |
331 | } | 328 | } |
332 | 329 | ||
333 | qsort(printk_map, printk_count, sizeof(*printk_map), printk_cmp); | 330 | qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp); |
331 | |||
332 | pevent->printk_map = printk_map; | ||
333 | pevent->printklist = NULL; | ||
334 | } | 334 | } |
335 | 335 | ||
336 | static struct printk_map *find_printk(unsigned long long addr) | 336 | static struct printk_map * |
337 | find_printk(struct pevent *pevent, unsigned long long addr) | ||
337 | { | 338 | { |
338 | struct printk_map *printk; | 339 | struct printk_map *printk; |
339 | struct printk_map key; | 340 | struct printk_map key; |
340 | 341 | ||
341 | if (!printk_map) | 342 | if (!pevent->printk_map) |
342 | printk_map_init(); | 343 | printk_map_init(pevent); |
343 | 344 | ||
344 | key.addr = addr; | 345 | key.addr = addr; |
345 | 346 | ||
346 | printk = bsearch(&key, printk_map, printk_count, sizeof(*printk_map), | 347 | printk = bsearch(&key, pevent->printk_map, pevent->printk_count, |
347 | printk_cmp); | 348 | sizeof(*pevent->printk_map), printk_cmp); |
348 | 349 | ||
349 | return printk; | 350 | return printk; |
350 | } | 351 | } |
351 | 352 | ||
352 | int pevent_register_print_string(char *fmt, unsigned long long addr) | 353 | int pevent_register_print_string(struct pevent *pevent, char *fmt, |
354 | unsigned long long addr) | ||
353 | { | 355 | { |
354 | struct printk_list *item; | 356 | struct printk_list *item; |
355 | 357 | ||
356 | item = malloc_or_die(sizeof(*item)); | 358 | item = malloc_or_die(sizeof(*item)); |
357 | 359 | ||
358 | item->next = printklist; | 360 | item->next = pevent->printklist; |
359 | printklist = item; | 361 | pevent->printklist = item; |
360 | item->printk = fmt; | 362 | item->printk = fmt; |
361 | item->addr = addr; | 363 | item->addr = addr; |
362 | 364 | ||
363 | printk_count++; | 365 | pevent->printk_count++; |
364 | 366 | ||
365 | return 0; | 367 | return 0; |
366 | } | 368 | } |
367 | 369 | ||
368 | void pevent_print_printk(void) | 370 | void pevent_print_printk(struct pevent *pevent) |
369 | { | 371 | { |
370 | int i; | 372 | int i; |
371 | 373 | ||
372 | for (i = 0; i < (int)printk_count; i++) { | 374 | if (!pevent->printk_map) |
375 | printk_map_init(pevent); | ||
376 | |||
377 | for (i = 0; i < (int)pevent->printk_count; i++) { | ||
373 | printf("%016llx %s\n", | 378 | printf("%016llx %s\n", |
374 | printk_map[i].addr, | 379 | pevent->printk_map[i].addr, |
375 | printk_map[i].printk); | 380 | pevent->printk_map[i].printk); |
376 | } | 381 | } |
377 | } | 382 | } |
378 | 383 | ||
@@ -398,14 +403,13 @@ enum event_type { | |||
398 | EVENT_SQUOTE, | 403 | EVENT_SQUOTE, |
399 | }; | 404 | }; |
400 | 405 | ||
401 | static struct event *event_list; | 406 | static void add_event(struct pevent *pevent, struct event *event) |
402 | static int nr_events; | ||
403 | |||
404 | static void add_event(struct event *event) | ||
405 | { | 407 | { |
406 | event->next = event_list; | 408 | event->next = pevent->event_list; |
407 | event_list = event; | 409 | pevent->event_list = event; |
408 | nr_events++; | 410 | pevent->nr_events++; |
411 | |||
412 | event->pevent = pevent; | ||
409 | } | 413 | } |
410 | 414 | ||
411 | static int event_item_type(enum event_type type) | 415 | static int event_item_type(enum event_type type) |
@@ -835,6 +839,7 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
835 | 839 | ||
836 | field = malloc_or_die(sizeof(*field)); | 840 | field = malloc_or_die(sizeof(*field)); |
837 | memset(field, 0, sizeof(*field)); | 841 | memset(field, 0, sizeof(*field)); |
842 | field->event = event; | ||
838 | 843 | ||
839 | /* read the rest of the type */ | 844 | /* read the rest of the type */ |
840 | for (;;) { | 845 | for (;;) { |
@@ -2080,17 +2085,18 @@ pevent_find_any_field(struct event *event, const char *name) | |||
2080 | return pevent_find_field(event, name); | 2085 | return pevent_find_field(event, name); |
2081 | } | 2086 | } |
2082 | 2087 | ||
2083 | unsigned long long pevent_read_number(const void *ptr, int size) | 2088 | unsigned long long pevent_read_number(struct pevent *pevent, |
2089 | const void *ptr, int size) | ||
2084 | { | 2090 | { |
2085 | switch (size) { | 2091 | switch (size) { |
2086 | case 1: | 2092 | case 1: |
2087 | return *(unsigned char *)ptr; | 2093 | return *(unsigned char *)ptr; |
2088 | case 2: | 2094 | case 2: |
2089 | return data2host2(ptr); | 2095 | return data2host2(pevent, ptr); |
2090 | case 4: | 2096 | case 4: |
2091 | return data2host4(ptr); | 2097 | return data2host4(pevent, ptr); |
2092 | case 8: | 2098 | case 8: |
2093 | return data2host8(ptr); | 2099 | return data2host8(pevent, ptr); |
2094 | default: | 2100 | default: |
2095 | /* BUG! */ | 2101 | /* BUG! */ |
2096 | return 0; | 2102 | return 0; |
@@ -2105,14 +2111,16 @@ int pevent_read_number_field(struct format_field *field, const void *data, | |||
2105 | case 2: | 2111 | case 2: |
2106 | case 4: | 2112 | case 4: |
2107 | case 8: | 2113 | case 8: |
2108 | *value = pevent_read_number(data + field->offset, field->size); | 2114 | *value = pevent_read_number(field->event->pevent, |
2115 | data + field->offset, field->size); | ||
2109 | return 0; | 2116 | return 0; |
2110 | default: | 2117 | default: |
2111 | return -1; | 2118 | return -1; |
2112 | } | 2119 | } |
2113 | } | 2120 | } |
2114 | 2121 | ||
2115 | static int get_common_info(const char *type, int *offset, int *size) | 2122 | static int get_common_info(struct pevent *pevent, |
2123 | const char *type, int *offset, int *size) | ||
2116 | { | 2124 | { |
2117 | struct event *event; | 2125 | struct event *event; |
2118 | struct format_field *field; | 2126 | struct format_field *field; |
@@ -2121,10 +2129,10 @@ static int get_common_info(const char *type, int *offset, int *size) | |||
2121 | * All events should have the same common elements. | 2129 | * All events should have the same common elements. |
2122 | * Pick any event to find where the type is; | 2130 | * Pick any event to find where the type is; |
2123 | */ | 2131 | */ |
2124 | if (!event_list) | 2132 | if (!pevent->event_list) |
2125 | die("no event_list!"); | 2133 | die("no event_list!"); |
2126 | 2134 | ||
2127 | event = event_list; | 2135 | event = pevent->event_list; |
2128 | field = pevent_find_common_field(event, type); | 2136 | field = pevent_find_common_field(event, type); |
2129 | if (!field) | 2137 | if (!field) |
2130 | die("field '%s' not found", type); | 2138 | die("field '%s' not found", type); |
@@ -2135,62 +2143,53 @@ static int get_common_info(const char *type, int *offset, int *size) | |||
2135 | return 0; | 2143 | return 0; |
2136 | } | 2144 | } |
2137 | 2145 | ||
2138 | static int __parse_common(void *data, int *size, int *offset, | 2146 | static int __parse_common(struct pevent *pevent, void *data, |
2139 | const char *name) | 2147 | int *size, int *offset, const char *name) |
2140 | { | 2148 | { |
2141 | int ret; | 2149 | int ret; |
2142 | 2150 | ||
2143 | if (!*size) { | 2151 | if (!*size) { |
2144 | ret = get_common_info(name, offset, size); | 2152 | ret = get_common_info(pevent, name, offset, size); |
2145 | if (ret < 0) | 2153 | if (ret < 0) |
2146 | return ret; | 2154 | return ret; |
2147 | } | 2155 | } |
2148 | return pevent_read_number(data + *offset, *size); | 2156 | return pevent_read_number(pevent, data + *offset, *size); |
2149 | } | 2157 | } |
2150 | 2158 | ||
2151 | static int trace_parse_common_type(void *data) | 2159 | static int trace_parse_common_type(struct pevent *pevent, void *data) |
2152 | { | 2160 | { |
2153 | static int type_offset; | 2161 | return __parse_common(pevent, data, |
2154 | static int type_size; | 2162 | &pevent->type_size, &pevent->type_offset, |
2155 | |||
2156 | return __parse_common(data, &type_size, &type_offset, | ||
2157 | "common_type"); | 2163 | "common_type"); |
2158 | } | 2164 | } |
2159 | 2165 | ||
2160 | static int parse_common_pid(void *data) | 2166 | static int parse_common_pid(struct pevent *pevent, void *data) |
2161 | { | 2167 | { |
2162 | static int pid_offset; | 2168 | return __parse_common(pevent, data, |
2163 | static int pid_size; | 2169 | &pevent->pid_size, &pevent->pid_offset, |
2164 | |||
2165 | return __parse_common(data, &pid_size, &pid_offset, | ||
2166 | "common_pid"); | 2170 | "common_pid"); |
2167 | } | 2171 | } |
2168 | 2172 | ||
2169 | static int parse_common_pc(void *data) | 2173 | static int parse_common_pc(struct pevent *pevent, void *data) |
2170 | { | 2174 | { |
2171 | static int pc_offset; | 2175 | return __parse_common(pevent, data, |
2172 | static int pc_size; | 2176 | &pevent->pc_size, &pevent->pc_offset, |
2173 | |||
2174 | return __parse_common(data, &pc_size, &pc_offset, | ||
2175 | "common_preempt_count"); | 2177 | "common_preempt_count"); |
2176 | } | 2178 | } |
2177 | 2179 | ||
2178 | static int parse_common_flags(void *data) | 2180 | static int parse_common_flags(struct pevent *pevent, void *data) |
2179 | { | 2181 | { |
2180 | static int flags_offset; | 2182 | return __parse_common(pevent, data, |
2181 | static int flags_size; | 2183 | &pevent->flags_size, &pevent->flags_offset, |
2182 | |||
2183 | return __parse_common(data, &flags_size, &flags_offset, | ||
2184 | "common_flags"); | 2184 | "common_flags"); |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | static int parse_common_lock_depth(void *data) | 2187 | static int parse_common_lock_depth(struct pevent *pevent, void *data) |
2188 | { | 2188 | { |
2189 | static int ld_offset; | ||
2190 | static int ld_size; | ||
2191 | int ret; | 2189 | int ret; |
2192 | 2190 | ||
2193 | ret = __parse_common(data, &ld_size, &ld_offset, | 2191 | ret = __parse_common(pevent, data, |
2192 | &pevent->ld_size, &pevent->ld_offset, | ||
2194 | "common_lock_depth"); | 2193 | "common_lock_depth"); |
2195 | if (ret < 0) | 2194 | if (ret < 0) |
2196 | return -1; | 2195 | return -1; |
@@ -2198,11 +2197,11 @@ static int parse_common_lock_depth(void *data) | |||
2198 | return ret; | 2197 | return ret; |
2199 | } | 2198 | } |
2200 | 2199 | ||
2201 | struct event *pevent_find_event(int id) | 2200 | struct event *pevent_find_event(struct pevent *pevent, int id) |
2202 | { | 2201 | { |
2203 | struct event *event; | 2202 | struct event *event; |
2204 | 2203 | ||
2205 | for (event = event_list; event; event = event->next) { | 2204 | for (event = pevent->event_list; event; event = event->next) { |
2206 | if (event->id == id) | 2205 | if (event->id == id) |
2207 | break; | 2206 | break; |
2208 | } | 2207 | } |
@@ -2210,11 +2209,12 @@ struct event *pevent_find_event(int id) | |||
2210 | } | 2209 | } |
2211 | 2210 | ||
2212 | struct event * | 2211 | struct event * |
2213 | pevent_find_event_by_name(const char *sys, const char *name) | 2212 | pevent_find_event_by_name(struct pevent *pevent, |
2213 | const char *sys, const char *name) | ||
2214 | { | 2214 | { |
2215 | struct event *event; | 2215 | struct event *event; |
2216 | 2216 | ||
2217 | for (event = event_list; event; event = event->next) { | 2217 | for (event = pevent->event_list; event; event = event->next) { |
2218 | if (strcmp(event->name, name) == 0) { | 2218 | if (strcmp(event->name, name) == 0) { |
2219 | if (!sys) | 2219 | if (!sys) |
2220 | break; | 2220 | break; |
@@ -2225,9 +2225,10 @@ pevent_find_event_by_name(const char *sys, const char *name) | |||
2225 | return event; | 2225 | return event; |
2226 | } | 2226 | } |
2227 | 2227 | ||
2228 | static unsigned long long eval_num_arg(void *data, int size, | 2228 | static unsigned long long |
2229 | struct event *event, struct print_arg *arg) | 2229 | eval_num_arg(void *data, int size, struct event *event, struct print_arg *arg) |
2230 | { | 2230 | { |
2231 | struct pevent *pevent = event->pevent; | ||
2231 | unsigned long long val = 0; | 2232 | unsigned long long val = 0; |
2232 | unsigned long long left, right; | 2233 | unsigned long long left, right; |
2233 | struct print_arg *typearg = NULL; | 2234 | struct print_arg *typearg = NULL; |
@@ -2247,7 +2248,7 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2247 | die("field %s not found", arg->field.name); | 2248 | die("field %s not found", arg->field.name); |
2248 | } | 2249 | } |
2249 | /* must be a number */ | 2250 | /* must be a number */ |
2250 | val = pevent_read_number(data + arg->field.field->offset, | 2251 | val = pevent_read_number(pevent, data + arg->field.field->offset, |
2251 | arg->field.field->size); | 2252 | arg->field.field->size); |
2252 | break; | 2253 | break; |
2253 | case PRINT_FLAGS: | 2254 | case PRINT_FLAGS: |
@@ -2277,7 +2278,8 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2277 | 2278 | ||
2278 | switch (larg->type) { | 2279 | switch (larg->type) { |
2279 | case PRINT_DYNAMIC_ARRAY: | 2280 | case PRINT_DYNAMIC_ARRAY: |
2280 | offset = pevent_read_number(data + larg->dynarray.field->offset, | 2281 | offset = pevent_read_number(pevent, |
2282 | data + larg->dynarray.field->offset, | ||
2281 | larg->dynarray.field->size); | 2283 | larg->dynarray.field->size); |
2282 | /* | 2284 | /* |
2283 | * The actual length of the dynamic array is stored | 2285 | * The actual length of the dynamic array is stored |
@@ -2295,12 +2297,13 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2295 | die("field %s not found", larg->field.name); | 2297 | die("field %s not found", larg->field.name); |
2296 | } | 2298 | } |
2297 | offset = larg->field.field->offset + | 2299 | offset = larg->field.field->offset + |
2298 | right * long_size; | 2300 | right * pevent->long_size; |
2299 | break; | 2301 | break; |
2300 | default: | 2302 | default: |
2301 | goto default_op; /* oops, all bets off */ | 2303 | goto default_op; /* oops, all bets off */ |
2302 | } | 2304 | } |
2303 | val = pevent_read_number(data + offset, long_size); | 2305 | val = pevent_read_number(pevent, |
2306 | data + offset, pevent->long_size); | ||
2304 | if (typearg) | 2307 | if (typearg) |
2305 | val = eval_type(val, typearg, 1); | 2308 | val = eval_type(val, typearg, 1); |
2306 | break; | 2309 | break; |
@@ -2415,6 +2418,7 @@ static unsigned long long eval_flag(const char *flag) | |||
2415 | static void print_str_arg(struct trace_seq *s, void *data, int size, | 2418 | static void print_str_arg(struct trace_seq *s, void *data, int size, |
2416 | struct event *event, struct print_arg *arg) | 2419 | struct event *event, struct print_arg *arg) |
2417 | { | 2420 | { |
2421 | struct pevent *pevent = event->pevent; | ||
2418 | struct print_flag_sym *flag; | 2422 | struct print_flag_sym *flag; |
2419 | unsigned long long val, fval; | 2423 | unsigned long long val, fval; |
2420 | unsigned long addr; | 2424 | unsigned long addr; |
@@ -2444,7 +2448,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
2444 | * is a pointer. | 2448 | * is a pointer. |
2445 | */ | 2449 | */ |
2446 | if (!(arg->field.field->flags & FIELD_IS_ARRAY) && | 2450 | if (!(arg->field.field->flags & FIELD_IS_ARRAY) && |
2447 | len == long_size) { | 2451 | len == pevent->long_size) { |
2448 | addr = *(unsigned long *)(data + arg->field.field->offset); | 2452 | addr = *(unsigned long *)(data + arg->field.field->offset); |
2449 | trace_seq_printf(s, "%lx", addr); | 2453 | trace_seq_printf(s, "%lx", addr); |
2450 | break; | 2454 | break; |
@@ -2520,12 +2524,16 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
2520 | 2524 | ||
2521 | static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event *event) | 2525 | static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event *event) |
2522 | { | 2526 | { |
2523 | static struct format_field *field, *ip_field; | 2527 | struct pevent *pevent = event->pevent; |
2528 | struct format_field *field, *ip_field; | ||
2524 | struct print_arg *args, *arg, **next; | 2529 | struct print_arg *args, *arg, **next; |
2525 | unsigned long long ip, val; | 2530 | unsigned long long ip, val; |
2526 | char *ptr; | 2531 | char *ptr; |
2527 | void *bptr; | 2532 | void *bptr; |
2528 | 2533 | ||
2534 | field = pevent->bprint_buf_field; | ||
2535 | ip_field = pevent->bprint_ip_field; | ||
2536 | |||
2529 | if (!field) { | 2537 | if (!field) { |
2530 | field = pevent_find_field(event, "buf"); | 2538 | field = pevent_find_field(event, "buf"); |
2531 | if (!field) | 2539 | if (!field) |
@@ -2533,9 +2541,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
2533 | ip_field = pevent_find_field(event, "ip"); | 2541 | ip_field = pevent_find_field(event, "ip"); |
2534 | if (!ip_field) | 2542 | if (!ip_field) |
2535 | die("can't find ip field for binary printk"); | 2543 | die("can't find ip field for binary printk"); |
2544 | pevent->bprint_buf_field = field; | ||
2545 | pevent->bprint_ip_field = ip_field; | ||
2536 | } | 2546 | } |
2537 | 2547 | ||
2538 | ip = pevent_read_number(data + ip_field->offset, ip_field->size); | 2548 | ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size); |
2539 | 2549 | ||
2540 | /* | 2550 | /* |
2541 | * The first arg is the IP pointer. | 2551 | * The first arg is the IP pointer. |
@@ -2581,14 +2591,14 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
2581 | switch (ls) { | 2591 | switch (ls) { |
2582 | case 0: | 2592 | case 0: |
2583 | case 1: | 2593 | case 1: |
2584 | ls = long_size; | 2594 | ls = pevent->long_size; |
2585 | break; | 2595 | break; |
2586 | case 2: | 2596 | case 2: |
2587 | ls = 8; | 2597 | ls = 8; |
2588 | default: | 2598 | default: |
2589 | break; | 2599 | break; |
2590 | } | 2600 | } |
2591 | val = pevent_read_number(bptr, ls); | 2601 | val = pevent_read_number(pevent, bptr, ls); |
2592 | bptr += ls; | 2602 | bptr += ls; |
2593 | arg = malloc_or_die(sizeof(*arg)); | 2603 | arg = malloc_or_die(sizeof(*arg)); |
2594 | arg->next = NULL; | 2604 | arg->next = NULL; |
@@ -2634,22 +2644,26 @@ static void free_args(struct print_arg *args) | |||
2634 | static char * | 2644 | static char * |
2635 | get_bprint_format(void *data, int size __unused, struct event *event) | 2645 | get_bprint_format(void *data, int size __unused, struct event *event) |
2636 | { | 2646 | { |
2647 | struct pevent *pevent = event->pevent; | ||
2637 | unsigned long long addr; | 2648 | unsigned long long addr; |
2638 | static struct format_field *field; | 2649 | struct format_field *field; |
2639 | struct printk_map *printk; | 2650 | struct printk_map *printk; |
2640 | char *format; | 2651 | char *format; |
2641 | char *p; | 2652 | char *p; |
2642 | 2653 | ||
2654 | field = pevent->bprint_fmt_field; | ||
2655 | |||
2643 | if (!field) { | 2656 | if (!field) { |
2644 | field = pevent_find_field(event, "fmt"); | 2657 | field = pevent_find_field(event, "fmt"); |
2645 | if (!field) | 2658 | if (!field) |
2646 | die("can't find format field for binary printk"); | 2659 | die("can't find format field for binary printk"); |
2647 | printf("field->offset = %d size=%d\n", field->offset, field->size); | 2660 | printf("field->offset = %d size=%d\n", field->offset, field->size); |
2661 | pevent->bprint_fmt_field = field; | ||
2648 | } | 2662 | } |
2649 | 2663 | ||
2650 | addr = pevent_read_number(data + field->offset, field->size); | 2664 | addr = pevent_read_number(pevent, data + field->offset, field->size); |
2651 | 2665 | ||
2652 | printk = find_printk(addr); | 2666 | printk = find_printk(pevent, addr); |
2653 | if (!printk) { | 2667 | if (!printk) { |
2654 | format = malloc_or_die(45); | 2668 | format = malloc_or_die(45); |
2655 | sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", | 2669 | sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", |
@@ -2677,6 +2691,7 @@ get_bprint_format(void *data, int size __unused, struct event *event) | |||
2677 | 2691 | ||
2678 | static void pretty_print(struct trace_seq *s, void *data, int size, struct event *event) | 2692 | static void pretty_print(struct trace_seq *s, void *data, int size, struct event *event) |
2679 | { | 2693 | { |
2694 | struct pevent *pevent = event->pevent; | ||
2680 | struct print_fmt *print_fmt = &event->print_fmt; | 2695 | struct print_fmt *print_fmt = &event->print_fmt; |
2681 | struct print_arg *arg = print_fmt->args; | 2696 | struct print_arg *arg = print_fmt->args; |
2682 | struct print_arg *args = NULL; | 2697 | struct print_arg *args = NULL; |
@@ -2749,7 +2764,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
2749 | case '0' ... '9': | 2764 | case '0' ... '9': |
2750 | goto cont_process; | 2765 | goto cont_process; |
2751 | case 'p': | 2766 | case 'p': |
2752 | if (long_size == 4) | 2767 | if (pevent->long_size == 4) |
2753 | ls = 1; | 2768 | ls = 1; |
2754 | else | 2769 | else |
2755 | ls = 2; | 2770 | ls = 2; |
@@ -2802,7 +2817,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
2802 | arg = arg->next; | 2817 | arg = arg->next; |
2803 | 2818 | ||
2804 | if (show_func) { | 2819 | if (show_func) { |
2805 | func = find_func(val); | 2820 | func = find_func(pevent, val); |
2806 | if (func) { | 2821 | if (func) { |
2807 | trace_seq_puts(s, func->func); | 2822 | trace_seq_puts(s, func->func); |
2808 | if (show_func == 'F') | 2823 | if (show_func == 'F') |
@@ -2847,7 +2862,8 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
2847 | } | 2862 | } |
2848 | } | 2863 | } |
2849 | 2864 | ||
2850 | void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused) | 2865 | void pevent_data_lat_fmt(struct pevent *pevent, |
2866 | struct trace_seq *s, void *data, int size __unused) | ||
2851 | { | 2867 | { |
2852 | unsigned int lat_flags; | 2868 | unsigned int lat_flags; |
2853 | unsigned int pc; | 2869 | unsigned int pc; |
@@ -2855,9 +2871,9 @@ void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused) | |||
2855 | int hardirq; | 2871 | int hardirq; |
2856 | int softirq; | 2872 | int softirq; |
2857 | 2873 | ||
2858 | lat_flags = parse_common_flags(data); | 2874 | lat_flags = parse_common_flags(pevent, data); |
2859 | pc = parse_common_pc(data); | 2875 | pc = parse_common_pc(pevent, data); |
2860 | lock_depth = parse_common_lock_depth(data); | 2876 | lock_depth = parse_common_lock_depth(pevent, data); |
2861 | 2877 | ||
2862 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | 2878 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; |
2863 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | 2879 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; |
@@ -2884,26 +2900,26 @@ void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused) | |||
2884 | trace_seq_terminate(s); | 2900 | trace_seq_terminate(s); |
2885 | } | 2901 | } |
2886 | 2902 | ||
2887 | int pevent_data_type(void *data) | 2903 | int pevent_data_type(struct pevent *pevent, void *data) |
2888 | { | 2904 | { |
2889 | return trace_parse_common_type(data); | 2905 | return trace_parse_common_type(pevent, data); |
2890 | } | 2906 | } |
2891 | 2907 | ||
2892 | struct event *pevent_data_event_from_type(int type) | 2908 | struct event *pevent_data_event_from_type(struct pevent *pevent, int type) |
2893 | { | 2909 | { |
2894 | return pevent_find_event(type); | 2910 | return pevent_find_event(pevent, type); |
2895 | } | 2911 | } |
2896 | 2912 | ||
2897 | int pevent_data_pid(void *data) | 2913 | int pevent_data_pid(struct pevent *pevent, void *data) |
2898 | { | 2914 | { |
2899 | return parse_common_pid(data); | 2915 | return parse_common_pid(pevent, data); |
2900 | } | 2916 | } |
2901 | 2917 | ||
2902 | const char *pevent_data_comm_from_pid(int pid) | 2918 | const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) |
2903 | { | 2919 | { |
2904 | const char *comm; | 2920 | const char *comm; |
2905 | 2921 | ||
2906 | comm = find_cmdline(pid); | 2922 | comm = find_cmdline(pevent, pid); |
2907 | return comm; | 2923 | return comm; |
2908 | } | 2924 | } |
2909 | 2925 | ||
@@ -2918,7 +2934,7 @@ void pevent_event_info(struct trace_seq *s, struct event *event, | |||
2918 | trace_seq_terminate(s); | 2934 | trace_seq_terminate(s); |
2919 | } | 2935 | } |
2920 | 2936 | ||
2921 | void pevent_print_event(struct trace_seq *s, | 2937 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, |
2922 | int cpu, void *data, int size, unsigned long long nsecs) | 2938 | int cpu, void *data, int size, unsigned long long nsecs) |
2923 | { | 2939 | { |
2924 | static char *spaces = " "; /* 20 spaces */ | 2940 | static char *spaces = " "; /* 20 spaces */ |
@@ -2934,21 +2950,21 @@ void pevent_print_event(struct trace_seq *s, | |||
2934 | usecs = nsecs - secs * NSECS_PER_SEC; | 2950 | usecs = nsecs - secs * NSECS_PER_SEC; |
2935 | usecs = usecs / NSECS_PER_USEC; | 2951 | usecs = usecs / NSECS_PER_USEC; |
2936 | 2952 | ||
2937 | type = trace_parse_common_type(data); | 2953 | type = trace_parse_common_type(pevent, data); |
2938 | 2954 | ||
2939 | event = pevent_find_event(type); | 2955 | event = pevent_find_event(pevent, type); |
2940 | if (!event) { | 2956 | if (!event) { |
2941 | warning("ug! no event found for type %d", type); | 2957 | warning("ug! no event found for type %d", type); |
2942 | return; | 2958 | return; |
2943 | } | 2959 | } |
2944 | 2960 | ||
2945 | pid = parse_common_pid(data); | 2961 | pid = parse_common_pid(pevent, data); |
2946 | comm = find_cmdline(pid); | 2962 | comm = find_cmdline(pevent, pid); |
2947 | 2963 | ||
2948 | if (latency_format) { | 2964 | if (pevent->latency_format) { |
2949 | trace_seq_printf(s, "%8.8s-%-5d %3d", | 2965 | trace_seq_printf(s, "%8.8s-%-5d %3d", |
2950 | comm, pid, cpu); | 2966 | comm, pid, cpu); |
2951 | pevent_data_lat_fmt(s, data, size); | 2967 | pevent_data_lat_fmt(pevent, s, data, size); |
2952 | } else | 2968 | } else |
2953 | trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, cpu); | 2969 | trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, cpu); |
2954 | 2970 | ||
@@ -3015,24 +3031,25 @@ static int events_system_cmp(const void *a, const void *b) | |||
3015 | return events_id_cmp(a, b); | 3031 | return events_id_cmp(a, b); |
3016 | } | 3032 | } |
3017 | 3033 | ||
3018 | struct event **pevent_list_events(enum event_sort_type sort_type) | 3034 | struct event **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type) |
3019 | { | 3035 | { |
3020 | static struct event **events; | 3036 | struct event **events; |
3021 | static enum event_sort_type last_type; | ||
3022 | struct event *event; | 3037 | struct event *event; |
3023 | int (*sort)(const void *a, const void *b); | 3038 | int (*sort)(const void *a, const void *b); |
3024 | int i = 0; | 3039 | int i = 0; |
3025 | 3040 | ||
3026 | if (events && last_type == sort_type) | 3041 | events = pevent->events; |
3042 | |||
3043 | if (events && pevent->last_type == sort_type) | ||
3027 | return events; | 3044 | return events; |
3028 | 3045 | ||
3029 | if (!events) { | 3046 | if (!events) { |
3030 | events = malloc(sizeof(*events) * (nr_events + 1)); | 3047 | events = malloc(sizeof(*events) * (pevent->nr_events + 1)); |
3031 | if (!events) | 3048 | if (!events) |
3032 | return NULL; | 3049 | return NULL; |
3033 | 3050 | ||
3034 | for (event = event_list; event; event = event->next) { | 3051 | for (event = pevent->event_list; event; event = event->next) { |
3035 | if (i == nr_events) { | 3052 | if (i == pevent->nr_events) { |
3036 | warning("Wrong event count"); | 3053 | warning("Wrong event count"); |
3037 | free(events); | 3054 | free(events); |
3038 | return NULL; | 3055 | return NULL; |
@@ -3040,6 +3057,8 @@ struct event **pevent_list_events(enum event_sort_type sort_type) | |||
3040 | events[i++] = event; | 3057 | events[i++] = event; |
3041 | } | 3058 | } |
3042 | events[i] = NULL; | 3059 | events[i] = NULL; |
3060 | |||
3061 | pevent->events = events; | ||
3043 | } | 3062 | } |
3044 | 3063 | ||
3045 | switch (sort_type) { | 3064 | switch (sort_type) { |
@@ -3056,8 +3075,8 @@ struct event **pevent_list_events(enum event_sort_type sort_type) | |||
3056 | return events; | 3075 | return events; |
3057 | } | 3076 | } |
3058 | 3077 | ||
3059 | qsort(events, nr_events, sizeof(*events), sort); | 3078 | qsort(events, pevent->nr_events, sizeof(*events), sort); |
3060 | last_type = sort_type; | 3079 | pevent->last_type = sort_type; |
3061 | 3080 | ||
3062 | return events; | 3081 | return events; |
3063 | } | 3082 | } |
@@ -3201,32 +3220,33 @@ static void parse_header_field(const char *field, | |||
3201 | free_token(token); | 3220 | free_token(token); |
3202 | } | 3221 | } |
3203 | 3222 | ||
3204 | int pevent_parse_header_page(char *buf, unsigned long size) | 3223 | int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size) |
3205 | { | 3224 | { |
3206 | if (!size) { | 3225 | if (!size) { |
3207 | /* | 3226 | /* |
3208 | * Old kernels did not have header page info. | 3227 | * Old kernels did not have header page info. |
3209 | * Sorry but we just use what we find here in user space. | 3228 | * Sorry but we just use what we find here in user space. |
3210 | */ | 3229 | */ |
3211 | header_page_ts_size = sizeof(long long); | 3230 | pevent->header_page_ts_size = sizeof(long long); |
3212 | header_page_size_size = sizeof(long); | 3231 | pevent->header_page_size_size = sizeof(long); |
3213 | header_page_data_offset = sizeof(long long) + sizeof(long); | 3232 | pevent->header_page_data_offset = sizeof(long long) + sizeof(long); |
3214 | old_format = 1; | 3233 | pevent->old_format = 1; |
3215 | return 0; | 3234 | return 0; |
3216 | } | 3235 | } |
3217 | init_input_buf(buf, size); | 3236 | init_input_buf(buf, size); |
3218 | 3237 | ||
3219 | parse_header_field("timestamp", &header_page_ts_offset, | 3238 | parse_header_field("timestamp", &pevent->header_page_ts_offset, |
3220 | &header_page_ts_size); | 3239 | &pevent->header_page_ts_size); |
3221 | parse_header_field("commit", &header_page_size_offset, | 3240 | parse_header_field("commit", &pevent->header_page_size_offset, |
3222 | &header_page_size_size); | 3241 | &pevent->header_page_size_size); |
3223 | parse_header_field("data", &header_page_data_offset, | 3242 | parse_header_field("data", &pevent->header_page_data_offset, |
3224 | &header_page_data_size); | 3243 | &pevent->header_page_data_size); |
3225 | 3244 | ||
3226 | return 0; | 3245 | return 0; |
3227 | } | 3246 | } |
3228 | 3247 | ||
3229 | int pevent_parse_event(char *buf, unsigned long size, char *sys) | 3248 | int pevent_parse_event(struct pevent *pevent, |
3249 | char *buf, unsigned long size, char *sys) | ||
3230 | { | 3250 | { |
3231 | struct event *event; | 3251 | struct event *event; |
3232 | int ret; | 3252 | int ret; |
@@ -3267,7 +3287,7 @@ int pevent_parse_event(char *buf, unsigned long size, char *sys) | |||
3267 | goto event_failed; | 3287 | goto event_failed; |
3268 | } | 3288 | } |
3269 | 3289 | ||
3270 | add_event(event); | 3290 | add_event(pevent, event); |
3271 | 3291 | ||
3272 | if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { | 3292 | if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { |
3273 | struct format_field *field; | 3293 | struct format_field *field; |
@@ -3297,18 +3317,19 @@ int pevent_parse_event(char *buf, unsigned long size, char *sys) | |||
3297 | event_failed: | 3317 | event_failed: |
3298 | event->flags |= EVENT_FL_FAILED; | 3318 | event->flags |= EVENT_FL_FAILED; |
3299 | /* still add it even if it failed */ | 3319 | /* still add it even if it failed */ |
3300 | add_event(event); | 3320 | add_event(pevent, event); |
3301 | return -1; | 3321 | return -1; |
3302 | } | 3322 | } |
3303 | 3323 | ||
3304 | int pevent_register_event_handler(int id, char *sys_name, char *event_name, | 3324 | int pevent_register_event_handler(struct pevent *pevent, |
3325 | int id, char *sys_name, char *event_name, | ||
3305 | pevent_event_handler_func func) | 3326 | pevent_event_handler_func func) |
3306 | { | 3327 | { |
3307 | struct event *event; | 3328 | struct event *event; |
3308 | 3329 | ||
3309 | if (id >= 0) { | 3330 | if (id >= 0) { |
3310 | /* search by id */ | 3331 | /* search by id */ |
3311 | event = pevent_find_event(id); | 3332 | event = pevent_find_event(pevent, id); |
3312 | if (!event) | 3333 | if (!event) |
3313 | return -1; | 3334 | return -1; |
3314 | if (event_name && (strcmp(event_name, event->name) != 0)) | 3335 | if (event_name && (strcmp(event_name, event->name) != 0)) |
@@ -3316,7 +3337,7 @@ int pevent_register_event_handler(int id, char *sys_name, char *event_name, | |||
3316 | if (sys_name && (strcmp(sys_name, event->system) != 0)) | 3337 | if (sys_name && (strcmp(sys_name, event->system) != 0)) |
3317 | return -1; | 3338 | return -1; |
3318 | } else { | 3339 | } else { |
3319 | event = pevent_find_event_by_name(sys_name, event_name); | 3340 | event = pevent_find_event_by_name(pevent, sys_name, event_name); |
3320 | if (!event) | 3341 | if (!event) |
3321 | return -1; | 3342 | return -1; |
3322 | } | 3343 | } |
@@ -3328,8 +3349,50 @@ int pevent_register_event_handler(int id, char *sys_name, char *event_name, | |||
3328 | return 0; | 3349 | return 0; |
3329 | } | 3350 | } |
3330 | 3351 | ||
3331 | void parse_set_info(int nr_cpus, int long_sz) | 3352 | struct pevent *pevent_alloc(void) |
3353 | { | ||
3354 | struct pevent *pevent; | ||
3355 | |||
3356 | pevent = malloc(sizeof(*pevent)); | ||
3357 | if (!pevent) | ||
3358 | return NULL; | ||
3359 | memset(pevent, 0, sizeof(*pevent)); | ||
3360 | |||
3361 | return pevent; | ||
3362 | } | ||
3363 | |||
3364 | static void free_formats(struct format *format) | ||
3365 | { | ||
3366 | /* IMPLEMENT ME */ | ||
3367 | } | ||
3368 | |||
3369 | static void free_event(struct event *event) | ||
3370 | { | ||
3371 | free(event->name); | ||
3372 | free(event->system); | ||
3373 | |||
3374 | free_formats(&event->format); | ||
3375 | |||
3376 | free(event->print_fmt.format); | ||
3377 | free_args(event->print_fmt.args); | ||
3378 | } | ||
3379 | |||
3380 | void pevent_free(struct pevent *pevent) | ||
3332 | { | 3381 | { |
3333 | cpus = nr_cpus; | 3382 | struct event *event, *next_event; |
3334 | long_size = long_sz; | 3383 | |
3384 | free(pevent->cmdlines); | ||
3385 | free(pevent->cmdlist); | ||
3386 | free(pevent->func_map); | ||
3387 | free(pevent->funclist); | ||
3388 | free(pevent->printk_map); | ||
3389 | free(pevent->printklist); | ||
3390 | |||
3391 | free(pevent->events); | ||
3392 | |||
3393 | for (event = pevent->event_list; event; event = next_event) { | ||
3394 | next_event = event->next; | ||
3395 | |||
3396 | free_event(event); | ||
3397 | } | ||
3335 | } | 3398 | } |