diff options
-rw-r--r-- | parse-events.c | 453 | ||||
-rw-r--r-- | parse-events.h | 196 | ||||
-rw-r--r-- | plugin_hrtimer.c | 9 | ||||
-rw-r--r-- | plugin_mac80211.c | 6 | ||||
-rw-r--r-- | trace-cmd.h | 9 | ||||
-rw-r--r-- | trace-ftrace.c | 24 | ||||
-rw-r--r-- | trace-input.c | 127 | ||||
-rw-r--r-- | trace-read.c | 22 | ||||
-rw-r--r-- | trace-util.c | 19 |
9 files changed, 543 insertions, 322 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 | } |
diff --git a/parse-events.h b/parse-events.h index 4459b52..db7e259 100644 --- a/parse-events.h +++ b/parse-events.h | |||
@@ -49,6 +49,7 @@ extern int trace_seq_do_printf(struct trace_seq *s); | |||
49 | 49 | ||
50 | /* ----------------------- pevent ----------------------- */ | 50 | /* ----------------------- pevent ----------------------- */ |
51 | 51 | ||
52 | struct pevent; | ||
52 | struct event; | 53 | struct event; |
53 | 54 | ||
54 | typedef int (*pevent_event_handler_func)(struct trace_seq *s, | 55 | typedef int (*pevent_event_handler_func)(struct trace_seq *s, |
@@ -56,7 +57,7 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s, | |||
56 | struct event *event, int cpu, | 57 | struct event *event, int cpu, |
57 | unsigned long long nsecs); | 58 | unsigned long long nsecs); |
58 | 59 | ||
59 | typedef int (*pevent_plugin_load_func)(void); | 60 | typedef int (*pevent_plugin_load_func)(struct pevent *pevent); |
60 | 61 | ||
61 | #define PEVENT_PLUGIN_LOADER pevent_plugin_loader | 62 | #define PEVENT_PLUGIN_LOADER pevent_plugin_loader |
62 | #define MAKE_STR(x) #x | 63 | #define MAKE_STR(x) #x |
@@ -75,6 +76,7 @@ enum format_flags { | |||
75 | 76 | ||
76 | struct format_field { | 77 | struct format_field { |
77 | struct format_field *next; | 78 | struct format_field *next; |
79 | struct event *event; | ||
78 | char *type; | 80 | char *type; |
79 | char *name; | 81 | char *name; |
80 | int offset; | 82 | int offset; |
@@ -179,6 +181,7 @@ struct print_fmt { | |||
179 | 181 | ||
180 | struct event { | 182 | struct event { |
181 | struct event *next; | 183 | struct event *next; |
184 | struct pevent *pevent; | ||
182 | char *name; | 185 | char *name; |
183 | int id; | 186 | int id; |
184 | int flags; | 187 | int flags; |
@@ -204,24 +207,80 @@ enum event_sort_type { | |||
204 | EVENT_SORT_SYSTEM, | 207 | EVENT_SORT_SYSTEM, |
205 | }; | 208 | }; |
206 | 209 | ||
207 | extern int old_format; | 210 | struct cmdline; |
211 | struct cmdline_list; | ||
212 | struct func_map; | ||
213 | struct func_list; | ||
208 | 214 | ||
209 | void parse_set_info(int nr_cpus, int long_sz); | 215 | struct pevent { |
216 | int header_page_ts_offset; | ||
217 | int header_page_ts_size; | ||
218 | int header_page_size_offset; | ||
219 | int header_page_size_size; | ||
220 | int header_page_data_offset; | ||
221 | int header_page_data_size; | ||
222 | |||
223 | int file_bigendian; | ||
224 | int host_bigendian; | ||
225 | |||
226 | int latency_format; | ||
227 | |||
228 | int old_format; | ||
229 | |||
230 | int cpus; | ||
231 | int long_size; | ||
232 | |||
233 | struct cmdline *cmdlines; | ||
234 | struct cmdline_list *cmdlist; | ||
235 | int cmdline_count; | ||
236 | |||
237 | struct func_map *func_map; | ||
238 | struct func_list *funclist; | ||
239 | unsigned int func_count; | ||
240 | |||
241 | struct printk_map *printk_map; | ||
242 | struct printk_list *printklist; | ||
243 | unsigned int printk_count; | ||
244 | |||
245 | struct event *event_list; | ||
246 | int nr_events; | ||
247 | struct event **events; | ||
248 | enum event_sort_type last_type; | ||
249 | |||
250 | int type_offset; | ||
251 | int type_size; | ||
252 | |||
253 | int pid_offset; | ||
254 | int pid_size; | ||
255 | |||
256 | int pc_offset; | ||
257 | int pc_size; | ||
258 | |||
259 | int flags_offset; | ||
260 | int flags_size; | ||
261 | |||
262 | int ld_offset; | ||
263 | int ld_size; | ||
264 | |||
265 | struct format_field *bprint_ip_field; | ||
266 | struct format_field *bprint_fmt_field; | ||
267 | struct format_field *bprint_buf_field; | ||
268 | }; | ||
269 | |||
270 | void parse_set_info(struct pevent *pevent, int nr_cpus, int long_sz); | ||
210 | 271 | ||
211 | void die(char *fmt, ...); | 272 | void die(char *fmt, ...); |
212 | void *malloc_or_die(unsigned int size); | 273 | void *malloc_or_die(unsigned int size); |
213 | void warning(char *fmt, ...); | 274 | void warning(char *fmt, ...); |
214 | 275 | ||
215 | extern int file_bigendian; | ||
216 | extern int host_bigendian; | ||
217 | |||
218 | int bigendian(void); | 276 | int bigendian(void); |
219 | 277 | ||
220 | static inline unsigned short __data2host2(unsigned short data) | 278 | static inline unsigned short |
279 | __data2host2(struct pevent *pevent, unsigned short data) | ||
221 | { | 280 | { |
222 | unsigned short swap; | 281 | unsigned short swap; |
223 | 282 | ||
224 | if (host_bigendian == file_bigendian) | 283 | if (pevent->host_bigendian == pevent->file_bigendian) |
225 | return data; | 284 | return data; |
226 | 285 | ||
227 | swap = ((data & 0xffULL) << 8) | | 286 | swap = ((data & 0xffULL) << 8) | |
@@ -230,11 +289,12 @@ static inline unsigned short __data2host2(unsigned short data) | |||
230 | return swap; | 289 | return swap; |
231 | } | 290 | } |
232 | 291 | ||
233 | static inline unsigned int __data2host4(unsigned int data) | 292 | static inline unsigned int |
293 | __data2host4(struct pevent *pevent, unsigned int data) | ||
234 | { | 294 | { |
235 | unsigned int swap; | 295 | unsigned int swap; |
236 | 296 | ||
237 | if (host_bigendian == file_bigendian) | 297 | if (pevent->host_bigendian == pevent->file_bigendian) |
238 | return data; | 298 | return data; |
239 | 299 | ||
240 | swap = ((data & 0xffULL) << 24) | | 300 | swap = ((data & 0xffULL) << 24) | |
@@ -245,11 +305,12 @@ static inline unsigned int __data2host4(unsigned int data) | |||
245 | return swap; | 305 | return swap; |
246 | } | 306 | } |
247 | 307 | ||
248 | static inline unsigned long long __data2host8(unsigned long long data) | 308 | static inline unsigned long long |
309 | __data2host8(struct pevent *pevent, unsigned long long data) | ||
249 | { | 310 | { |
250 | unsigned long long swap; | 311 | unsigned long long swap; |
251 | 312 | ||
252 | if (host_bigendian == file_bigendian) | 313 | if (pevent->host_bigendian == pevent->file_bigendian) |
253 | return data; | 314 | return data; |
254 | 315 | ||
255 | swap = ((data & 0xffULL) << 56) | | 316 | swap = ((data & 0xffULL) << 56) | |
@@ -264,18 +325,9 @@ static inline unsigned long long __data2host8(unsigned long long data) | |||
264 | return swap; | 325 | return swap; |
265 | } | 326 | } |
266 | 327 | ||
267 | #define data2host2(ptr) __data2host2(*(unsigned short *)ptr) | 328 | #define data2host2(pevent, ptr) __data2host2(pevent, *(unsigned short *)ptr) |
268 | #define data2host4(ptr) __data2host4(*(unsigned int *)ptr) | 329 | #define data2host4(pevent, ptr) __data2host4(pevent, *(unsigned int *)ptr) |
269 | #define data2host8(ptr) __data2host8(*(unsigned long long *)ptr) | 330 | #define data2host8(pevent, ptr) __data2host8(pevent, *(unsigned long long *)ptr) |
270 | |||
271 | extern int header_page_ts_offset; | ||
272 | extern int header_page_ts_size; | ||
273 | extern int header_page_size_offset; | ||
274 | extern int header_page_size_size; | ||
275 | extern int header_page_data_offset; | ||
276 | extern int header_page_data_size; | ||
277 | |||
278 | extern int latency_format; | ||
279 | 331 | ||
280 | /* taken from kernel/trace/trace.h */ | 332 | /* taken from kernel/trace/trace.h */ |
281 | enum trace_flag_type { | 333 | enum trace_flag_type { |
@@ -286,47 +338,103 @@ enum trace_flag_type { | |||
286 | TRACE_FLAG_SOFTIRQ = 0x10, | 338 | TRACE_FLAG_SOFTIRQ = 0x10, |
287 | }; | 339 | }; |
288 | 340 | ||
289 | int pevent_register_comm(char *comm, int pid); | 341 | int pevent_register_comm(struct pevent *pevent, char *comm, int pid); |
290 | int pevent_register_function(char *name, unsigned long long addr, char *mod); | 342 | int pevent_register_function(struct pevent *pevetn, char *name, |
291 | int pevent_register_print_string(char *fmt, unsigned long long addr); | 343 | unsigned long long addr, char *mod); |
344 | int pevent_register_print_string(struct pevent *pevent, char *fmt, | ||
345 | unsigned long long addr); | ||
292 | 346 | ||
293 | void pevent_print_event(struct trace_seq *s, | 347 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, |
294 | int cpu, void *data, int size, unsigned long long nsecs); | 348 | int cpu, void *data, int size, unsigned long long nsecs); |
295 | 349 | ||
296 | int pevent_parse_header_page(char *buf, unsigned long size); | 350 | int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size); |
297 | 351 | ||
298 | int pevent_parse_event(char *buf, unsigned long size, char *sys); | 352 | int pevent_parse_event(struct pevent *pevent, char *buf, unsigned long size, char *sys); |
299 | 353 | ||
300 | int pevent_register_event_handler(int id, char *sys_name, char *event_name, | 354 | int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name, |
301 | pevent_event_handler_func func); | 355 | pevent_event_handler_func func); |
302 | 356 | ||
303 | struct format_field *pevent_find_common_field(struct event *event, const char *name); | 357 | struct format_field *pevent_find_common_field(struct event *event, const char *name); |
304 | struct format_field *pevent_find_field(struct event *event, const char *name); | 358 | struct format_field *pevent_find_field(struct event *event, const char *name); |
305 | struct format_field *pevent_find_any_field(struct event *event, const char *name); | 359 | struct format_field *pevent_find_any_field(struct event *event, const char *name); |
306 | 360 | ||
307 | const char *pevent_find_function(unsigned long long addr); | 361 | const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); |
308 | unsigned long long pevent_read_number(const void *ptr, int size); | 362 | unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); |
309 | int pevent_read_number_field(struct format_field *field, const void *data, | 363 | int pevent_read_number_field(struct format_field *field, const void *data, |
310 | unsigned long long *value); | 364 | unsigned long long *value); |
311 | 365 | ||
312 | struct event *pevent_find_event(int id); | 366 | struct event *pevent_find_event(struct pevent *pevent, int id); |
313 | 367 | ||
314 | struct event * | 368 | struct event * |
315 | pevent_find_event_by_name(const char *sys, const char *name); | 369 | pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name); |
316 | 370 | ||
317 | void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused); | 371 | void pevent_data_lat_fmt(struct pevent *pevent, |
318 | int pevent_data_type(void *data); | 372 | struct trace_seq *s, void *data, int size __unused); |
319 | struct event *pevent_data_event_from_type(int type); | 373 | int pevent_data_type(struct pevent *pevent, void *data); |
320 | int pevent_data_pid(void *data); | 374 | struct event *pevent_data_event_from_type(struct pevent *pevent, int type); |
321 | const char *pevent_data_comm_from_pid(int pid); | 375 | int pevent_data_pid(struct pevent *pevent, void *data); |
376 | const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); | ||
322 | void pevent_event_info(struct trace_seq *s, struct event *event, | 377 | void pevent_event_info(struct trace_seq *s, struct event *event, |
323 | int cpu, void *data, int size, unsigned long long nsecs); | 378 | int cpu, void *data, int size, unsigned long long nsecs); |
324 | 379 | ||
325 | struct event **pevent_list_events(enum event_sort_type); | 380 | struct event **pevent_list_events(struct pevent *pevent, enum event_sort_type); |
381 | |||
382 | static inline int pevent_get_cpus(struct pevent *pevent) | ||
383 | { | ||
384 | return pevent->cpus; | ||
385 | } | ||
386 | |||
387 | static inline void pevent_set_cpus(struct pevent *pevent, int cpus) | ||
388 | { | ||
389 | pevent->cpus = cpus; | ||
390 | } | ||
391 | |||
392 | static inline int pevent_get_long_size(struct pevent *pevent) | ||
393 | { | ||
394 | return pevent->long_size; | ||
395 | } | ||
396 | |||
397 | static inline void pevent_set_long_size(struct pevent *pevent, int long_size) | ||
398 | { | ||
399 | pevent->long_size = long_size; | ||
400 | } | ||
401 | |||
402 | static inline int pevent_is_file_bigendian(struct pevent *pevent) | ||
403 | { | ||
404 | return pevent->file_bigendian; | ||
405 | } | ||
406 | |||
407 | static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian) | ||
408 | { | ||
409 | pevent->file_bigendian = endian; | ||
410 | } | ||
411 | |||
412 | static inline int pevent_is_host_bigendian(struct pevent *pevent) | ||
413 | { | ||
414 | return pevent->host_bigendian; | ||
415 | } | ||
416 | |||
417 | static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian) | ||
418 | { | ||
419 | pevent->host_bigendian = endian; | ||
420 | } | ||
421 | |||
422 | static inline int pevent_is_latency_format(struct pevent *pevent) | ||
423 | { | ||
424 | return pevent->latency_format; | ||
425 | } | ||
426 | |||
427 | static inline void pevent_set_latency_format(struct pevent *pevent, int lat) | ||
428 | { | ||
429 | pevent->latency_format = lat; | ||
430 | } | ||
431 | |||
432 | struct pevent *pevent_alloc(void); | ||
433 | void pevent_free(struct pevent *pevent); | ||
326 | 434 | ||
327 | /* for debugging */ | 435 | /* for debugging */ |
328 | void pevent_print_funcs(void); | 436 | void pevent_print_funcs(struct pevent *pevent); |
329 | void pevent_print_printk(void); | 437 | void pevent_print_printk(struct pevent *pevent); |
330 | 438 | ||
331 | 439 | ||
332 | #endif /* _PARSE_EVENTS_H */ | 440 | #endif /* _PARSE_EVENTS_H */ |
diff --git a/plugin_hrtimer.c b/plugin_hrtimer.c index 76c9580..69529c6 100644 --- a/plugin_hrtimer.c +++ b/plugin_hrtimer.c | |||
@@ -50,6 +50,7 @@ static int timer_start_handler(struct trace_seq *s, void *data, int size, | |||
50 | struct event *event, int cpu, | 50 | struct event *event, int cpu, |
51 | unsigned long long nsecs) | 51 | unsigned long long nsecs) |
52 | { | 52 | { |
53 | struct pevent *pevent = event->pevent; | ||
53 | struct format_field *fn = pevent_find_field(event, "function"); | 54 | struct format_field *fn = pevent_find_field(event, "function"); |
54 | 55 | ||
55 | trace_seq_printf(s, "hrtimer="); | 56 | trace_seq_printf(s, "hrtimer="); |
@@ -66,7 +67,7 @@ static int timer_start_handler(struct trace_seq *s, void *data, int size, | |||
66 | if (pevent_read_number_field(fn, data, &function)) | 67 | if (pevent_read_number_field(fn, data, &function)) |
67 | trace_seq_printf(s, " function=INVALID"); | 68 | trace_seq_printf(s, " function=INVALID"); |
68 | 69 | ||
69 | func = pevent_find_function(function); | 70 | func = pevent_find_function(pevent, function); |
70 | 71 | ||
71 | trace_seq_printf(s, " function=%s", func); | 72 | trace_seq_printf(s, " function=%s", func); |
72 | } | 73 | } |
@@ -80,12 +81,12 @@ static int timer_start_handler(struct trace_seq *s, void *data, int size, | |||
80 | return 0; | 81 | return 0; |
81 | } | 82 | } |
82 | 83 | ||
83 | int PEVENT_PLUGIN_LOADER(void) | 84 | int PEVENT_PLUGIN_LOADER(struct pevent *pevent) |
84 | { | 85 | { |
85 | pevent_register_event_handler(-1, "timer", "hrtimer_expire_entry", | 86 | pevent_register_event_handler(pevent, -1, "timer", "hrtimer_expire_entry", |
86 | timer_expire_handler); | 87 | timer_expire_handler); |
87 | 88 | ||
88 | pevent_register_event_handler(-1, "timer", "hrtimer_start", | 89 | pevent_register_event_handler(pevent, -1, "timer", "hrtimer_start", |
89 | timer_start_handler); | 90 | timer_start_handler); |
90 | 91 | ||
91 | return 0; | 92 | return 0; |
diff --git a/plugin_mac80211.c b/plugin_mac80211.c index bf12bd0..7758b58 100644 --- a/plugin_mac80211.c +++ b/plugin_mac80211.c | |||
@@ -194,11 +194,11 @@ static int drv_config(struct trace_seq *s, void *data, | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | int PEVENT_PLUGIN_LOADER(void) | 197 | int PEVENT_PLUGIN_LOADER(struct pevent *pevent) |
198 | { | 198 | { |
199 | pevent_register_event_handler(-1, "mac80211", "drv_bss_info_changed", | 199 | pevent_register_event_handler(pevent, -1, "mac80211", "drv_bss_info_changed", |
200 | drv_bss_info_changed); | 200 | drv_bss_info_changed); |
201 | pevent_register_event_handler(-1, "mac80211", "drv_config", | 201 | pevent_register_event_handler(pevent, -1, "mac80211", "drv_config", |
202 | drv_config); | 202 | drv_config); |
203 | 203 | ||
204 | return 0; | 204 | return 0; |
diff --git a/trace-cmd.h b/trace-cmd.h index 0ebed96..cdd31e1 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
@@ -10,11 +10,11 @@ extern const char *input_file; | |||
10 | #define PAGE_MASK (page_size - 1) | 10 | #define PAGE_MASK (page_size - 1) |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | void parse_cmdlines(char *file, int size); | 13 | void parse_cmdlines(struct pevent *pevent, char *file, int size); |
14 | void parse_proc_kallsyms(char *file, unsigned int size); | 14 | void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); |
15 | void parse_ftrace_printk(char *file, unsigned int size); | 15 | void parse_ftrace_printk(char *file, unsigned int size); |
16 | 16 | ||
17 | int trace_load_plugins(void); | 17 | int trace_load_plugins(struct pevent *pevent); |
18 | 18 | ||
19 | enum { | 19 | enum { |
20 | RINGBUF_TYPE_PADDING = 29, | 20 | RINGBUF_TYPE_PADDING = 29, |
@@ -57,7 +57,8 @@ struct record * | |||
57 | tracecmd_translate_data(struct tracecmd_handle *handle, | 57 | tracecmd_translate_data(struct tracecmd_handle *handle, |
58 | void *ptr, int size); | 58 | void *ptr, int size); |
59 | 59 | ||
60 | int tracecmd_ftrace_overrides(void); | 60 | int tracecmd_ftrace_overrides(struct tracecmd_handle *handle); |
61 | struct pevent *tracecmd_get_pevent(struct tracecmd_handle *handle); | ||
61 | 62 | ||
62 | /* hack for function graph work around */ | 63 | /* hack for function graph work around */ |
63 | extern __thread struct tracecmd_handle *tracecmd_curr_thread_handle; | 64 | extern __thread struct tracecmd_handle *tracecmd_curr_thread_handle; |
diff --git a/trace-ftrace.c b/trace-ftrace.c index e6f7aa5..3e7ccde 100644 --- a/trace-ftrace.c +++ b/trace-ftrace.c | |||
@@ -31,13 +31,14 @@ static int function_handler(struct trace_seq *s, void *data, int size, | |||
31 | struct event *event, int cpu, | 31 | struct event *event, int cpu, |
32 | unsigned long long nsecs) | 32 | unsigned long long nsecs) |
33 | { | 33 | { |
34 | struct pevent *pevent = event->pevent; | ||
34 | unsigned long long function; | 35 | unsigned long long function; |
35 | const char *func; | 36 | const char *func; |
36 | 37 | ||
37 | if (get_field_val(s, data, event, "ip", &function)) | 38 | if (get_field_val(s, data, event, "ip", &function)) |
38 | return trace_seq_putc(s, '!'); | 39 | return trace_seq_putc(s, '!'); |
39 | 40 | ||
40 | func = pevent_find_function(function); | 41 | func = pevent_find_function(pevent, function); |
41 | if (func) | 42 | if (func) |
42 | trace_seq_printf(s, "%s <-- ", func); | 43 | trace_seq_printf(s, "%s <-- ", func); |
43 | else | 44 | else |
@@ -46,7 +47,7 @@ static int function_handler(struct trace_seq *s, void *data, int size, | |||
46 | if (get_field_val(s, data, event, "parent_ip", &function)) | 47 | if (get_field_val(s, data, event, "parent_ip", &function)) |
47 | return trace_seq_putc(s, '!'); | 48 | return trace_seq_putc(s, '!'); |
48 | 49 | ||
49 | func = pevent_find_function(function); | 50 | func = pevent_find_function(pevent, function); |
50 | if (func) | 51 | if (func) |
51 | trace_seq_printf(s, "%s", func); | 52 | trace_seq_printf(s, "%s", func); |
52 | else | 53 | else |
@@ -145,6 +146,7 @@ static int | |||
145 | print_graph_entry_leaf(struct trace_seq *s, | 146 | print_graph_entry_leaf(struct trace_seq *s, |
146 | struct event *event, void *data, struct record *ret_rec) | 147 | struct event *event, void *data, struct record *ret_rec) |
147 | { | 148 | { |
149 | struct pevent *pevent = event->pevent; | ||
148 | unsigned long long rettime, calltime; | 150 | unsigned long long rettime, calltime; |
149 | unsigned long long duration, depth; | 151 | unsigned long long duration, depth; |
150 | unsigned long long val; | 152 | unsigned long long val; |
@@ -175,7 +177,7 @@ print_graph_entry_leaf(struct trace_seq *s, | |||
175 | 177 | ||
176 | if (get_field_val(s, data, event, "func", &val)) | 178 | if (get_field_val(s, data, event, "func", &val)) |
177 | return trace_seq_putc(s, '!'); | 179 | return trace_seq_putc(s, '!'); |
178 | func = pevent_find_function(val); | 180 | func = pevent_find_function(pevent, val); |
179 | 181 | ||
180 | if (func) | 182 | if (func) |
181 | return trace_seq_printf(s, "%s();", func); | 183 | return trace_seq_printf(s, "%s();", func); |
@@ -186,6 +188,7 @@ print_graph_entry_leaf(struct trace_seq *s, | |||
186 | static int print_graph_nested(struct trace_seq *s, | 188 | static int print_graph_nested(struct trace_seq *s, |
187 | struct event *event, void *data) | 189 | struct event *event, void *data) |
188 | { | 190 | { |
191 | struct pevent *pevent = event->pevent; | ||
189 | unsigned long long depth; | 192 | unsigned long long depth; |
190 | unsigned long long val; | 193 | unsigned long long val; |
191 | const char *func; | 194 | const char *func; |
@@ -207,7 +210,7 @@ static int print_graph_nested(struct trace_seq *s, | |||
207 | if (get_field_val(s, data, event, "func", &val)) | 210 | if (get_field_val(s, data, event, "func", &val)) |
208 | return trace_seq_putc(s, '!'); | 211 | return trace_seq_putc(s, '!'); |
209 | 212 | ||
210 | func = pevent_find_function(val); | 213 | func = pevent_find_function(pevent, val); |
211 | 214 | ||
212 | if (func) | 215 | if (func) |
213 | return trace_seq_printf(s, "%s() {", func); | 216 | return trace_seq_printf(s, "%s() {", func); |
@@ -286,21 +289,24 @@ fgraph_ret_handler(struct trace_seq *s, void *data, int size, | |||
286 | return trace_seq_putc(s, '}'); | 289 | return trace_seq_putc(s, '}'); |
287 | } | 290 | } |
288 | 291 | ||
289 | int tracecmd_ftrace_overrides(void) | 292 | int tracecmd_ftrace_overrides(struct tracecmd_handle *handle) |
290 | { | 293 | { |
294 | struct pevent *pevent; | ||
291 | struct event *event; | 295 | struct event *event; |
292 | 296 | ||
293 | pevent_register_event_handler(-1, "ftrace", "function", | 297 | pevent = tracecmd_get_pevent(handle); |
298 | |||
299 | pevent_register_event_handler(pevent, -1, "ftrace", "function", | ||
294 | function_handler); | 300 | function_handler); |
295 | 301 | ||
296 | pevent_register_event_handler(-1, "ftrace", "funcgraph_entry", | 302 | pevent_register_event_handler(pevent, -1, "ftrace", "funcgraph_entry", |
297 | fgraph_ent_handler); | 303 | fgraph_ent_handler); |
298 | 304 | ||
299 | pevent_register_event_handler(-1, "ftrace", "funcgraph_exit", | 305 | pevent_register_event_handler(pevent, -1, "ftrace", "funcgraph_exit", |
300 | fgraph_ret_handler); | 306 | fgraph_ret_handler); |
301 | 307 | ||
302 | /* Store the func ret id and event for later use */ | 308 | /* Store the func ret id and event for later use */ |
303 | event = pevent_find_event_by_name("ftrace", "funcgraph_exit"); | 309 | event = pevent_find_event_by_name(pevent, "ftrace", "funcgraph_exit"); |
304 | if (!event) | 310 | if (!event) |
305 | return 0; | 311 | return 0; |
306 | 312 | ||
diff --git a/trace-input.c b/trace-input.c index ac177f0..6e35897 100644 --- a/trace-input.c +++ b/trace-input.c | |||
@@ -34,6 +34,7 @@ struct cpu_data { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct tracecmd_handle { | 36 | struct tracecmd_handle { |
37 | struct pevent *pevent; | ||
37 | int fd; | 38 | int fd; |
38 | int long_size; | 39 | int long_size; |
39 | int page_size; | 40 | int page_size; |
@@ -147,26 +148,29 @@ static char *read_string(struct tracecmd_handle *handle) | |||
147 | 148 | ||
148 | static unsigned int read4(struct tracecmd_handle *handle) | 149 | static unsigned int read4(struct tracecmd_handle *handle) |
149 | { | 150 | { |
151 | struct pevent *pevent = handle->pevent; | ||
150 | unsigned int data; | 152 | unsigned int data; |
151 | 153 | ||
152 | if (do_read_check(handle, &data, 4)) | 154 | if (do_read_check(handle, &data, 4)) |
153 | return -1; | 155 | return -1; |
154 | 156 | ||
155 | return __data2host4(data); | 157 | return __data2host4(pevent, data); |
156 | } | 158 | } |
157 | 159 | ||
158 | static unsigned long long read8(struct tracecmd_handle *handle) | 160 | static unsigned long long read8(struct tracecmd_handle *handle) |
159 | { | 161 | { |
162 | struct pevent *pevent = handle->pevent; | ||
160 | unsigned long long data; | 163 | unsigned long long data; |
161 | 164 | ||
162 | if (do_read_check(handle, &data, 8)) | 165 | if (do_read_check(handle, &data, 8)) |
163 | return -1; | 166 | return -1; |
164 | 167 | ||
165 | return __data2host8(data); | 168 | return __data2host8(pevent, data); |
166 | } | 169 | } |
167 | 170 | ||
168 | static int read_header_files(struct tracecmd_handle *handle) | 171 | static int read_header_files(struct tracecmd_handle *handle) |
169 | { | 172 | { |
173 | struct pevent *pevent = handle->pevent; | ||
170 | long long size; | 174 | long long size; |
171 | char *header; | 175 | char *header; |
172 | char buf[BUFSIZ]; | 176 | char buf[BUFSIZ]; |
@@ -188,14 +192,14 @@ static int read_header_files(struct tracecmd_handle *handle) | |||
188 | if (do_read_check(handle, header, size)) | 192 | if (do_read_check(handle, header, size)) |
189 | goto failed_read; | 193 | goto failed_read; |
190 | 194 | ||
191 | pevent_parse_header_page(header, size); | 195 | pevent_parse_header_page(pevent, header, size); |
192 | free(header); | 196 | free(header); |
193 | 197 | ||
194 | /* | 198 | /* |
195 | * The size field in the page is of type long, | 199 | * The size field in the page is of type long, |
196 | * use that instead, since it represents the kernel. | 200 | * use that instead, since it represents the kernel. |
197 | */ | 201 | */ |
198 | handle->long_size = header_page_size_size; | 202 | handle->long_size = pevent->header_page_size_size; |
199 | 203 | ||
200 | if (do_read_check(handle, buf, 13)) | 204 | if (do_read_check(handle, buf, 13)) |
201 | return -1; | 205 | return -1; |
@@ -226,6 +230,7 @@ static int read_header_files(struct tracecmd_handle *handle) | |||
226 | static int read_ftrace_file(struct tracecmd_handle *handle, | 230 | static int read_ftrace_file(struct tracecmd_handle *handle, |
227 | unsigned long long size) | 231 | unsigned long long size) |
228 | { | 232 | { |
233 | struct pevent *pevent = handle->pevent; | ||
229 | char *buf; | 234 | char *buf; |
230 | 235 | ||
231 | buf = malloc(size); | 236 | buf = malloc(size); |
@@ -236,7 +241,7 @@ static int read_ftrace_file(struct tracecmd_handle *handle, | |||
236 | return -1; | 241 | return -1; |
237 | } | 242 | } |
238 | 243 | ||
239 | pevent_parse_event(buf, size, "ftrace"); | 244 | pevent_parse_event(pevent, buf, size, "ftrace"); |
240 | free(buf); | 245 | free(buf); |
241 | 246 | ||
242 | return 0; | 247 | return 0; |
@@ -245,6 +250,7 @@ static int read_ftrace_file(struct tracecmd_handle *handle, | |||
245 | static int read_event_file(struct tracecmd_handle *handle, | 250 | static int read_event_file(struct tracecmd_handle *handle, |
246 | char *system, unsigned long long size) | 251 | char *system, unsigned long long size) |
247 | { | 252 | { |
253 | struct pevent *pevent = handle->pevent; | ||
248 | char *buf; | 254 | char *buf; |
249 | 255 | ||
250 | buf = malloc(size+1); | 256 | buf = malloc(size+1); |
@@ -259,7 +265,7 @@ static int read_event_file(struct tracecmd_handle *handle, | |||
259 | buf[size] = 0; | 265 | buf[size] = 0; |
260 | if (handle->print_events) | 266 | if (handle->print_events) |
261 | printf("%s\n", buf); | 267 | printf("%s\n", buf); |
262 | pevent_parse_event(buf, size, system); | 268 | pevent_parse_event(pevent, buf, size, system); |
263 | free(buf); | 269 | free(buf); |
264 | 270 | ||
265 | return 0; | 271 | return 0; |
@@ -331,6 +337,7 @@ static int read_event_files(struct tracecmd_handle *handle) | |||
331 | 337 | ||
332 | static int read_proc_kallsyms(struct tracecmd_handle *handle) | 338 | static int read_proc_kallsyms(struct tracecmd_handle *handle) |
333 | { | 339 | { |
340 | struct pevent *pevent = handle->pevent; | ||
334 | int size; | 341 | int size; |
335 | char *buf; | 342 | char *buf; |
336 | 343 | ||
@@ -349,7 +356,7 @@ static int read_proc_kallsyms(struct tracecmd_handle *handle) | |||
349 | return -1; | 356 | return -1; |
350 | } | 357 | } |
351 | 358 | ||
352 | parse_proc_kallsyms(buf, size); | 359 | parse_proc_kallsyms(pevent, buf, size); |
353 | 360 | ||
354 | free(buf); | 361 | free(buf); |
355 | return 0; | 362 | return 0; |
@@ -384,6 +391,7 @@ static int read_ftrace_printk(struct tracecmd_handle *handle) | |||
384 | 391 | ||
385 | int tracecmd_read_headers(struct tracecmd_handle *handle) | 392 | int tracecmd_read_headers(struct tracecmd_handle *handle) |
386 | { | 393 | { |
394 | struct pevent *pevent = handle->pevent; | ||
387 | int ret; | 395 | int ret; |
388 | 396 | ||
389 | ret = read_header_files(handle); | 397 | ret = read_header_files(handle); |
@@ -407,40 +415,52 @@ int tracecmd_read_headers(struct tracecmd_handle *handle) | |||
407 | return -1; | 415 | return -1; |
408 | 416 | ||
409 | /* register default ftrace functions first */ | 417 | /* register default ftrace functions first */ |
410 | tracecmd_ftrace_overrides(); | 418 | tracecmd_ftrace_overrides(handle); |
411 | 419 | ||
412 | trace_load_plugins(); | 420 | trace_load_plugins(pevent); |
413 | 421 | ||
414 | return 0; | 422 | return 0; |
415 | } | 423 | } |
416 | 424 | ||
417 | static unsigned int type4host(unsigned int type_len_ts) | 425 | static unsigned int type4host(struct tracecmd_handle *handle, |
426 | unsigned int type_len_ts) | ||
418 | { | 427 | { |
419 | if (file_bigendian) | 428 | struct pevent *pevent = handle->pevent; |
429 | |||
430 | if (pevent->file_bigendian) | ||
420 | return (type_len_ts >> 29) & 3; | 431 | return (type_len_ts >> 29) & 3; |
421 | else | 432 | else |
422 | return type_len_ts & 3; | 433 | return type_len_ts & 3; |
423 | } | 434 | } |
424 | 435 | ||
425 | static unsigned int len4host(unsigned int type_len_ts) | 436 | static unsigned int len4host(struct tracecmd_handle *handle, |
437 | unsigned int type_len_ts) | ||
426 | { | 438 | { |
427 | if (file_bigendian) | 439 | struct pevent *pevent = handle->pevent; |
440 | |||
441 | if (pevent->file_bigendian) | ||
428 | return (type_len_ts >> 27) & 7; | 442 | return (type_len_ts >> 27) & 7; |
429 | else | 443 | else |
430 | return (type_len_ts >> 2) & 7; | 444 | return (type_len_ts >> 2) & 7; |
431 | } | 445 | } |
432 | 446 | ||
433 | static unsigned int type_len4host(unsigned int type_len_ts) | 447 | static unsigned int type_len4host(struct tracecmd_handle *handle, |
448 | unsigned int type_len_ts) | ||
434 | { | 449 | { |
435 | if (file_bigendian) | 450 | struct pevent *pevent = handle->pevent; |
451 | |||
452 | if (pevent->file_bigendian) | ||
436 | return (type_len_ts >> 27) & ((1 << 5) - 1); | 453 | return (type_len_ts >> 27) & ((1 << 5) - 1); |
437 | else | 454 | else |
438 | return type_len_ts & ((1 << 5) - 1); | 455 | return type_len_ts & ((1 << 5) - 1); |
439 | } | 456 | } |
440 | 457 | ||
441 | static unsigned int ts4host(unsigned int type_len_ts) | 458 | static unsigned int ts4host(struct tracecmd_handle *handle, |
459 | unsigned int type_len_ts) | ||
442 | { | 460 | { |
443 | if (file_bigendian) | 461 | struct pevent *pevent = handle->pevent; |
462 | |||
463 | if (pevent->file_bigendian) | ||
444 | return type_len_ts & ((1 << 27) - 1); | 464 | return type_len_ts & ((1 << 27) - 1); |
445 | else | 465 | else |
446 | return type_len_ts >> 5; | 466 | return type_len_ts >> 5; |
@@ -522,6 +542,7 @@ enum old_ring_buffer_type { | |||
522 | static struct record * | 542 | static struct record * |
523 | read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | 543 | read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) |
524 | { | 544 | { |
545 | struct pevent *pevent = handle->pevent; | ||
525 | struct record *data; | 546 | struct record *data; |
526 | unsigned long long extend; | 547 | unsigned long long extend; |
527 | unsigned int type_len_ts; | 548 | unsigned int type_len_ts; |
@@ -533,12 +554,12 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
533 | 554 | ||
534 | index = calc_index(handle, *ptr, cpu); | 555 | index = calc_index(handle, *ptr, cpu); |
535 | 556 | ||
536 | type_len_ts = data2host4(*ptr); | 557 | type_len_ts = data2host4(pevent, *ptr); |
537 | *ptr += 4; | 558 | *ptr += 4; |
538 | 559 | ||
539 | type = type4host(type_len_ts); | 560 | type = type4host(handle, type_len_ts); |
540 | len = len4host(type_len_ts); | 561 | len = len4host(handle, type_len_ts); |
541 | delta = ts4host(type_len_ts); | 562 | delta = ts4host(handle, type_len_ts); |
542 | 563 | ||
543 | switch (type) { | 564 | switch (type) { |
544 | case OLD_RINGBUF_TYPE_PADDING: | 565 | case OLD_RINGBUF_TYPE_PADDING: |
@@ -547,7 +568,7 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
547 | return NULL; | 568 | return NULL; |
548 | 569 | ||
549 | case OLD_RINGBUF_TYPE_TIME_EXTEND: | 570 | case OLD_RINGBUF_TYPE_TIME_EXTEND: |
550 | extend = data2host4(ptr); | 571 | extend = data2host4(pevent, ptr); |
551 | extend <<= TS_SHIFT; | 572 | extend <<= TS_SHIFT; |
552 | extend += delta; | 573 | extend += delta; |
553 | handle->cpu_data[cpu].timestamp += extend; | 574 | handle->cpu_data[cpu].timestamp += extend; |
@@ -562,7 +583,7 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
562 | if (len) | 583 | if (len) |
563 | length = len * 4; | 584 | length = len * 4; |
564 | else { | 585 | else { |
565 | length = data2host4(*ptr); | 586 | length = data2host4(pevent, *ptr); |
566 | length -= 4; | 587 | length -= 4; |
567 | *ptr += 4; | 588 | *ptr += 4; |
568 | } | 589 | } |
@@ -709,28 +730,30 @@ tracecmd_read_at(struct tracecmd_handle *handle, unsigned long long offset, | |||
709 | } | 730 | } |
710 | 731 | ||
711 | static unsigned int | 732 | static unsigned int |
712 | translate_data(void **ptr, unsigned long long *delta, int *length) | 733 | translate_data(struct tracecmd_handle *handle, |
734 | void **ptr, unsigned long long *delta, int *length) | ||
713 | { | 735 | { |
736 | struct pevent *pevent = handle->pevent; | ||
714 | unsigned long long extend; | 737 | unsigned long long extend; |
715 | unsigned int type_len_ts; | 738 | unsigned int type_len_ts; |
716 | unsigned int type_len; | 739 | unsigned int type_len; |
717 | 740 | ||
718 | type_len_ts = data2host4(*ptr); | 741 | type_len_ts = data2host4(pevent, *ptr); |
719 | *ptr += 4; | 742 | *ptr += 4; |
720 | 743 | ||
721 | type_len = type_len4host(type_len_ts); | 744 | type_len = type_len4host(handle, type_len_ts); |
722 | *delta = ts4host(type_len_ts); | 745 | *delta = ts4host(handle, type_len_ts); |
723 | 746 | ||
724 | switch (type_len) { | 747 | switch (type_len) { |
725 | case RINGBUF_TYPE_PADDING: | 748 | case RINGBUF_TYPE_PADDING: |
726 | *length = data2host4(*ptr); | 749 | *length = data2host4(pevent, *ptr); |
727 | *ptr += 4; | 750 | *ptr += 4; |
728 | *length *= 4; | 751 | *length *= 4; |
729 | *ptr += *length; | 752 | *ptr += *length; |
730 | break; | 753 | break; |
731 | 754 | ||
732 | case RINGBUF_TYPE_TIME_EXTEND: | 755 | case RINGBUF_TYPE_TIME_EXTEND: |
733 | extend = data2host4(*ptr); | 756 | extend = data2host4(pevent, *ptr); |
734 | *ptr += 4; | 757 | *ptr += 4; |
735 | extend <<= TS_SHIFT; | 758 | extend <<= TS_SHIFT; |
736 | extend += *delta; | 759 | extend += *delta; |
@@ -741,7 +764,7 @@ translate_data(void **ptr, unsigned long long *delta, int *length) | |||
741 | *ptr += 12; | 764 | *ptr += 12; |
742 | break; | 765 | break; |
743 | case 0: | 766 | case 0: |
744 | *length = data2host4(*ptr) - 4; | 767 | *length = data2host4(pevent, *ptr) - 4; |
745 | *length = (*length + 3) & ~3; | 768 | *length = (*length + 3) & ~3; |
746 | *ptr += 4; | 769 | *ptr += 4; |
747 | break; | 770 | break; |
@@ -770,7 +793,7 @@ tracecmd_translate_data(struct tracecmd_handle *handle, | |||
770 | memset(data, 0, sizeof(*data)); | 793 | memset(data, 0, sizeof(*data)); |
771 | 794 | ||
772 | data->data = ptr; | 795 | data->data = ptr; |
773 | type_len = translate_data(&data->data, &data->ts, &data->size); | 796 | type_len = translate_data(handle, &data->data, &data->ts, &data->size); |
774 | switch (type_len) { | 797 | switch (type_len) { |
775 | case RINGBUF_TYPE_PADDING: | 798 | case RINGBUF_TYPE_PADDING: |
776 | case RINGBUF_TYPE_TIME_EXTEND: | 799 | case RINGBUF_TYPE_TIME_EXTEND: |
@@ -787,6 +810,7 @@ tracecmd_translate_data(struct tracecmd_handle *handle, | |||
787 | struct record * | 810 | struct record * |
788 | tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) | 811 | tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) |
789 | { | 812 | { |
813 | struct pevent *pevent = handle->pevent; | ||
790 | struct record *data; | 814 | struct record *data; |
791 | void *page = handle->cpu_data[cpu].page; | 815 | void *page = handle->cpu_data[cpu].page; |
792 | int index = handle->cpu_data[cpu].index; | 816 | int index = handle->cpu_data[cpu].index; |
@@ -806,26 +830,26 @@ tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) | |||
806 | 830 | ||
807 | if (!index) { | 831 | if (!index) { |
808 | /* FIXME: handle header page */ | 832 | /* FIXME: handle header page */ |
809 | if (header_page_ts_size != 8) { | 833 | if (pevent->header_page_ts_size != 8) { |
810 | warning("expected a long long type for timestamp"); | 834 | warning("expected a long long type for timestamp"); |
811 | return NULL; | 835 | return NULL; |
812 | } | 836 | } |
813 | handle->cpu_data[cpu].timestamp = data2host8(ptr); | 837 | handle->cpu_data[cpu].timestamp = data2host8(pevent, ptr); |
814 | ptr += 8; | 838 | ptr += 8; |
815 | switch (header_page_size_size) { | 839 | switch (pevent->header_page_size_size) { |
816 | case 4: | 840 | case 4: |
817 | handle->cpu_data[cpu].page_size = data2host4(ptr); | 841 | handle->cpu_data[cpu].page_size = data2host4(pevent,ptr); |
818 | ptr += 4; | 842 | ptr += 4; |
819 | break; | 843 | break; |
820 | case 8: | 844 | case 8: |
821 | handle->cpu_data[cpu].page_size = data2host8(ptr); | 845 | handle->cpu_data[cpu].page_size = data2host8(pevent, ptr); |
822 | ptr += 8; | 846 | ptr += 8; |
823 | break; | 847 | break; |
824 | default: | 848 | default: |
825 | warning("bad long size"); | 849 | warning("bad long size"); |
826 | return NULL; | 850 | return NULL; |
827 | } | 851 | } |
828 | ptr = handle->cpu_data[cpu].page + header_page_data_offset; | 852 | ptr = handle->cpu_data[cpu].page + pevent->header_page_data_offset; |
829 | } | 853 | } |
830 | 854 | ||
831 | read_again: | 855 | read_again: |
@@ -837,7 +861,7 @@ read_again: | |||
837 | return tracecmd_peek_data(handle, cpu); | 861 | return tracecmd_peek_data(handle, cpu); |
838 | } | 862 | } |
839 | 863 | ||
840 | if (old_format) { | 864 | if (pevent->old_format) { |
841 | data = read_old_format(handle, &ptr, cpu); | 865 | data = read_old_format(handle, &ptr, cpu); |
842 | if (!data) { | 866 | if (!data) { |
843 | if (!ptr) | 867 | if (!ptr) |
@@ -848,7 +872,7 @@ read_again: | |||
848 | return data; | 872 | return data; |
849 | } | 873 | } |
850 | 874 | ||
851 | type_len = translate_data(&ptr, &extend, &length); | 875 | type_len = translate_data(handle, &ptr, &extend, &length); |
852 | 876 | ||
853 | switch (type_len) { | 877 | switch (type_len) { |
854 | case RINGBUF_TYPE_PADDING: | 878 | case RINGBUF_TYPE_PADDING: |
@@ -949,6 +973,7 @@ static int init_cpu(struct tracecmd_handle *handle, int cpu) | |||
949 | 973 | ||
950 | int tracecmd_init_data(struct tracecmd_handle *handle) | 974 | int tracecmd_init_data(struct tracecmd_handle *handle) |
951 | { | 975 | { |
976 | struct pevent *pevent = handle->pevent; | ||
952 | unsigned long long size; | 977 | unsigned long long size; |
953 | char *cmdlines; | 978 | char *cmdlines; |
954 | char buf[10]; | 979 | char buf[10]; |
@@ -964,14 +989,15 @@ int tracecmd_init_data(struct tracecmd_handle *handle) | |||
964 | free(cmdlines); | 989 | free(cmdlines); |
965 | return -1; | 990 | return -1; |
966 | } | 991 | } |
967 | parse_cmdlines(cmdlines, size); | 992 | parse_cmdlines(pevent, cmdlines, size); |
968 | free(cmdlines); | 993 | free(cmdlines); |
969 | 994 | ||
970 | handle->cpus = read4(handle); | 995 | handle->cpus = read4(handle); |
971 | if (handle->cpus < 0) | 996 | if (handle->cpus < 0) |
972 | return -1; | 997 | return -1; |
973 | 998 | ||
974 | parse_set_info(handle->cpus, handle->long_size); | 999 | pevent_set_cpus(pevent, handle->cpus); |
1000 | pevent_set_long_size(pevent, handle->long_size); | ||
975 | 1001 | ||
976 | /* | 1002 | /* |
977 | * Check if this is a latency report or not. | 1003 | * Check if this is a latency report or not. |
@@ -1040,14 +1066,12 @@ struct tracecmd_handle *tracecmd_open(int fd) | |||
1040 | if (do_read_check(handle, buf, 1)) | 1066 | if (do_read_check(handle, buf, 1)) |
1041 | goto failed_read; | 1067 | goto failed_read; |
1042 | 1068 | ||
1043 | /* | 1069 | handle->pevent = pevent_alloc(); |
1044 | * TODO: | 1070 | if (!handle->pevent) |
1045 | * Need to make these part of the handle. | 1071 | goto failed_read; |
1046 | * But they are currently used by parsevent. | 1072 | |
1047 | * That may need a handler too. | 1073 | handle->pevent->file_bigendian = buf[0]; |
1048 | */ | 1074 | handle->pevent->host_bigendian = bigendian(); |
1049 | file_bigendian = buf[0]; | ||
1050 | host_bigendian = bigendian(); | ||
1051 | 1075 | ||
1052 | do_read_check(handle, buf, 1); | 1076 | do_read_check(handle, buf, 1); |
1053 | handle->long_size = buf[0]; | 1077 | handle->long_size = buf[0]; |
@@ -1076,3 +1100,8 @@ int tracecmd_cpus(struct tracecmd_handle *handle) | |||
1076 | { | 1100 | { |
1077 | return handle->cpus; | 1101 | return handle->cpus; |
1078 | } | 1102 | } |
1103 | |||
1104 | struct pevent *tracecmd_get_pevent(struct tracecmd_handle *handle) | ||
1105 | { | ||
1106 | return handle->pevent; | ||
1107 | } | ||
diff --git a/trace-read.c b/trace-read.c index 280f6d3..862200f 100644 --- a/trace-read.c +++ b/trace-read.c | |||
@@ -48,13 +48,16 @@ static int filter_cpu = -1; | |||
48 | 48 | ||
49 | static void show_data(struct tracecmd_handle *handle, int cpu) | 49 | static void show_data(struct tracecmd_handle *handle, int cpu) |
50 | { | 50 | { |
51 | struct pevent *pevent; | ||
51 | struct record *record; | 52 | struct record *record; |
52 | struct trace_seq s; | 53 | struct trace_seq s; |
53 | 54 | ||
55 | pevent = tracecmd_get_pevent(handle); | ||
56 | |||
54 | record = tracecmd_read_data(handle, cpu); | 57 | record = tracecmd_read_data(handle, cpu); |
55 | 58 | ||
56 | trace_seq_init(&s); | 59 | trace_seq_init(&s); |
57 | pevent_print_event(&s, cpu, record->data, record->size, record->ts); | 60 | pevent_print_event(pevent, &s, cpu, record->data, record->size, record->ts); |
58 | trace_seq_do_printf(&s); | 61 | trace_seq_do_printf(&s); |
59 | printf("\n"); | 62 | printf("\n"); |
60 | 63 | ||
@@ -132,10 +135,12 @@ struct tracecmd_handle *read_trace_header(void) | |||
132 | void trace_report (int argc, char **argv) | 135 | void trace_report (int argc, char **argv) |
133 | { | 136 | { |
134 | struct tracecmd_handle *handle; | 137 | struct tracecmd_handle *handle; |
138 | struct pevent *pevent; | ||
135 | int show_funcs = 0; | 139 | int show_funcs = 0; |
136 | int show_endian = 0; | 140 | int show_endian = 0; |
137 | int show_page_size = 0; | 141 | int show_page_size = 0; |
138 | int show_printk = 0; | 142 | int show_printk = 0; |
143 | int latency_format; | ||
139 | int c; | 144 | int c; |
140 | 145 | ||
141 | if (argc < 2) | 146 | if (argc < 2) |
@@ -208,10 +213,12 @@ void trace_report (int argc, char **argv) | |||
208 | return; | 213 | return; |
209 | } | 214 | } |
210 | 215 | ||
216 | pevent = tracecmd_get_pevent(handle); | ||
217 | |||
211 | if (show_endian) { | 218 | if (show_endian) { |
212 | printf("file is %s endian and host is %s endian\n", | 219 | printf("file is %s endian and host is %s endian\n", |
213 | file_bigendian ? "big" : "little", | 220 | pevent_is_file_bigendian(pevent) ? "big" : "little", |
214 | host_bigendian ? "big" : "little"); | 221 | pevent_is_host_bigendian(pevent) ? "big" : "little"); |
215 | return; | 222 | return; |
216 | } | 223 | } |
217 | 224 | ||
@@ -219,11 +226,11 @@ void trace_report (int argc, char **argv) | |||
219 | return; | 226 | return; |
220 | 227 | ||
221 | if (show_funcs) { | 228 | if (show_funcs) { |
222 | pevent_print_funcs(); | 229 | pevent_print_funcs(pevent); |
223 | return; | 230 | return; |
224 | } | 231 | } |
225 | if (show_printk) { | 232 | if (show_printk) { |
226 | pevent_print_printk(); | 233 | pevent_print_printk(pevent); |
227 | return; | 234 | return; |
228 | } | 235 | } |
229 | 236 | ||
@@ -232,7 +239,7 @@ void trace_report (int argc, char **argv) | |||
232 | struct event *event; | 239 | struct event *event; |
233 | int i; | 240 | int i; |
234 | 241 | ||
235 | events = pevent_list_events(EVENT_SORT_SYSTEM); | 242 | events = pevent_list_events(pevent, EVENT_SORT_SYSTEM); |
236 | for (i = 0; events[i]; i++) { | 243 | for (i = 0; events[i]; i++) { |
237 | event = events[i]; | 244 | event = events[i]; |
238 | if (event->system) | 245 | if (event->system) |
@@ -242,6 +249,9 @@ void trace_report (int argc, char **argv) | |||
242 | return; | 249 | return; |
243 | } | 250 | } |
244 | 251 | ||
252 | if (latency_format) | ||
253 | pevent_set_latency_format(pevent, latency_format); | ||
254 | |||
245 | read_data_info(handle); | 255 | read_data_info(handle); |
246 | 256 | ||
247 | return; | 257 | return; |
diff --git a/trace-util.c b/trace-util.c index fbdb071..a3ee05c 100644 --- a/trace-util.c +++ b/trace-util.c | |||
@@ -69,7 +69,8 @@ int __weak bigendian(void) | |||
69 | return *ptr == 0x01020304; | 69 | return *ptr == 0x01020304; |
70 | } | 70 | } |
71 | 71 | ||
72 | void parse_cmdlines(char *file, int size __unused) | 72 | void parse_cmdlines(struct pevent *pevent, |
73 | char *file, int size __unused) | ||
73 | { | 74 | { |
74 | char *comm; | 75 | char *comm; |
75 | char *line; | 76 | char *line; |
@@ -80,12 +81,13 @@ void parse_cmdlines(char *file, int size __unused) | |||
80 | while (line) { | 81 | while (line) { |
81 | sscanf(line, "%d %as", &pid, | 82 | sscanf(line, "%d %as", &pid, |
82 | (float *)(void *)&comm); /* workaround gcc warning */ | 83 | (float *)(void *)&comm); /* workaround gcc warning */ |
83 | pevent_register_comm(comm, pid); | 84 | pevent_register_comm(pevent, comm, pid); |
84 | line = strtok_r(NULL, "\n", &next); | 85 | line = strtok_r(NULL, "\n", &next); |
85 | } | 86 | } |
86 | } | 87 | } |
87 | 88 | ||
88 | void parse_proc_kallsyms(char *file, unsigned int size __unused) | 89 | void parse_proc_kallsyms(struct pevent *pevent, |
90 | char *file, unsigned int size __unused) | ||
89 | { | 91 | { |
90 | unsigned long long addr; | 92 | unsigned long long addr; |
91 | char *func; | 93 | char *func; |
@@ -111,7 +113,7 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused) | |||
111 | if (mod) | 113 | if (mod) |
112 | mod[strlen(mod) - 1] = 0; | 114 | mod[strlen(mod) - 1] = 0; |
113 | 115 | ||
114 | pevent_register_function(func, addr, mod); | 116 | pevent_register_function(pevent, func, addr, mod); |
115 | 117 | ||
116 | line = strtok_r(NULL, "\n", &next); | 118 | line = strtok_r(NULL, "\n", &next); |
117 | } | 119 | } |
@@ -136,7 +138,8 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
136 | } | 138 | } |
137 | } | 139 | } |
138 | 140 | ||
139 | static int load_plugin(const char *path, const char *file) | 141 | static int load_plugin(struct pevent *pevent, |
142 | const char *path, const char *file) | ||
140 | { | 143 | { |
141 | char *plugin; | 144 | char *plugin; |
142 | void *handle; | 145 | void *handle; |
@@ -164,13 +167,13 @@ static int load_plugin(const char *path, const char *file) | |||
164 | } | 167 | } |
165 | 168 | ||
166 | printf("registering plugin: %s\n", plugin); | 169 | printf("registering plugin: %s\n", plugin); |
167 | ret = func(); | 170 | ret = func(pevent); |
168 | 171 | ||
169 | /* dlclose ?? */ | 172 | /* dlclose ?? */ |
170 | return ret; | 173 | return ret; |
171 | } | 174 | } |
172 | 175 | ||
173 | int trace_load_plugins(void) | 176 | int trace_load_plugins(struct pevent *pevent) |
174 | { | 177 | { |
175 | struct dirent *dent; | 178 | struct dirent *dent; |
176 | struct stat st; | 179 | struct stat st; |
@@ -209,7 +212,7 @@ int trace_load_plugins(void) | |||
209 | strcmp(name, "..") == 0) | 212 | strcmp(name, "..") == 0) |
210 | continue; | 213 | continue; |
211 | 214 | ||
212 | load_plugin(path, name); | 215 | load_plugin(pevent, path, name); |
213 | } | 216 | } |
214 | 217 | ||
215 | fail: | 218 | fail: |