aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-04 00:41:44 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-04 00:50:25 -0500
commitcd001f7b40f9dd1e5dfbf0c436531a03064f9391 (patch)
treee02d368fdb7062f5da498ede824c3f018c659c9a
parentec350cbbabfb98965565a6d220b40f56a598be7f (diff)
Add handler to pevent functions
Currently pevent uses global variables to store the event types. This will eventually bite us since we may someday want to be able to read multiple files with different formats. This patch adds a handle to pevent, to keep it encapsulated. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c453
-rw-r--r--parse-events.h196
-rw-r--r--plugin_hrtimer.c9
-rw-r--r--plugin_mac80211.c6
-rw-r--r--trace-cmd.h9
-rw-r--r--trace-ftrace.c24
-rw-r--r--trace-input.c127
-rw-r--r--trace-read.c22
-rw-r--r--trace-util.c19
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
33int header_page_ts_offset;
34int header_page_ts_size;
35int header_page_size_offset;
36int header_page_size_size;
37int header_page_data_offset;
38int header_page_data_size;
39
40int file_bigendian;
41int host_bigendian;
42
43int latency_format;
44
45int old_format;
46
47static char *input_buf; 33static char *input_buf;
48static unsigned long long input_buf_ptr; 34static unsigned long long input_buf_ptr;
49static unsigned long long input_buf_siz; 35static unsigned long long input_buf_siz;
50 36
51static int cpus;
52static int long_size;
53
54static void init_input_buf(char *buf, unsigned long long size) 37static 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
72static struct cmdline *cmdlines;
73static int cmdline_count;
74
75static int cmdline_cmp(const void *a, const void *b) 55static 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
88static struct cmdline_list { 68struct 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
94static int cmdline_init(void) 74static 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
116static char *find_cmdline(int pid) 101static 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
137int pevent_register_comm(char *comm, int pid) 122int 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
152static struct func_map { 137struct 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};
157static unsigned int func_count;
158 142
159static struct func_list { 143struct 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
166static int func_cmp(const void *a, const void *b) 150static 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
200static int func_map_init(void) 184static 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
230static struct func_map *find_func(unsigned long long addr) 220static struct func_map *
221find_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
246const char *pevent_find_function(unsigned long long addr) 237const 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
257int pevent_register_function(char *func, unsigned long long addr, 248int 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
276void pevent_print_funcs(void) 267void 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
291static struct printk_map { 285struct printk_map {
292 unsigned long long addr; 286 unsigned long long addr;
293 char *printk; 287 char *printk;
294} *printk_map; 288};
295static unsigned int printk_count;
296 289
297static struct printk_list { 290struct 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
303static int printk_cmp(const void *a, const void *b) 296static 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
316static void printk_map_init(void) 309static 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
336static struct printk_map *find_printk(unsigned long long addr) 336static struct printk_map *
337find_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
352int pevent_register_print_string(char *fmt, unsigned long long addr) 353int 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
368void pevent_print_printk(void) 370void 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
401static struct event *event_list; 406static void add_event(struct pevent *pevent, struct event *event)
402static int nr_events;
403
404static 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
411static int event_item_type(enum event_type type) 415static 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
2083unsigned long long pevent_read_number(const void *ptr, int size) 2088unsigned 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
2115static int get_common_info(const char *type, int *offset, int *size) 2122static 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
2138static int __parse_common(void *data, int *size, int *offset, 2146static 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
2151static int trace_parse_common_type(void *data) 2159static 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
2160static int parse_common_pid(void *data) 2166static 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
2169static int parse_common_pc(void *data) 2173static 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
2178static int parse_common_flags(void *data) 2180static 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
2187static int parse_common_lock_depth(void *data) 2187static 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
2201struct event *pevent_find_event(int id) 2200struct 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
2212struct event * 2211struct event *
2213pevent_find_event_by_name(const char *sys, const char *name) 2212pevent_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
2228static unsigned long long eval_num_arg(void *data, int size, 2228static unsigned long long
2229 struct event *event, struct print_arg *arg) 2229eval_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)
2415static void print_str_arg(struct trace_seq *s, void *data, int size, 2418static 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
2521static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event *event) 2525static 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)
2634static char * 2644static char *
2635get_bprint_format(void *data, int size __unused, struct event *event) 2645get_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
2678static void pretty_print(struct trace_seq *s, void *data, int size, struct event *event) 2692static 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
2850void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused) 2865void 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
2887int pevent_data_type(void *data) 2903int 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
2892struct event *pevent_data_event_from_type(int type) 2908struct 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
2897int pevent_data_pid(void *data) 2913int 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
2902const char *pevent_data_comm_from_pid(int pid) 2918const 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
2921void pevent_print_event(struct trace_seq *s, 2937void 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
3018struct event **pevent_list_events(enum event_sort_type sort_type) 3034struct 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
3204int pevent_parse_header_page(char *buf, unsigned long size) 3223int 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
3229int pevent_parse_event(char *buf, unsigned long size, char *sys) 3248int 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
3304int pevent_register_event_handler(int id, char *sys_name, char *event_name, 3324int 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
3331void parse_set_info(int nr_cpus, int long_sz) 3352struct 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
3364static void free_formats(struct format *format)
3365{
3366 /* IMPLEMENT ME */
3367}
3368
3369static 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
3380void 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
52struct pevent;
52struct event; 53struct event;
53 54
54typedef int (*pevent_event_handler_func)(struct trace_seq *s, 55typedef 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
59typedef int (*pevent_plugin_load_func)(void); 60typedef 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
76struct format_field { 77struct 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
180struct event { 182struct 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
207extern int old_format; 210struct cmdline;
211struct cmdline_list;
212struct func_map;
213struct func_list;
208 214
209void parse_set_info(int nr_cpus, int long_sz); 215struct 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
270void parse_set_info(struct pevent *pevent, int nr_cpus, int long_sz);
210 271
211void die(char *fmt, ...); 272void die(char *fmt, ...);
212void *malloc_or_die(unsigned int size); 273void *malloc_or_die(unsigned int size);
213void warning(char *fmt, ...); 274void warning(char *fmt, ...);
214 275
215extern int file_bigendian;
216extern int host_bigendian;
217
218int bigendian(void); 276int bigendian(void);
219 277
220static inline unsigned short __data2host2(unsigned short data) 278static 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
233static inline unsigned int __data2host4(unsigned int data) 292static 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
248static inline unsigned long long __data2host8(unsigned long long data) 308static 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
271extern int header_page_ts_offset;
272extern int header_page_ts_size;
273extern int header_page_size_offset;
274extern int header_page_size_size;
275extern int header_page_data_offset;
276extern int header_page_data_size;
277
278extern int latency_format;
279 331
280/* taken from kernel/trace/trace.h */ 332/* taken from kernel/trace/trace.h */
281enum trace_flag_type { 333enum 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
289int pevent_register_comm(char *comm, int pid); 341int pevent_register_comm(struct pevent *pevent, char *comm, int pid);
290int pevent_register_function(char *name, unsigned long long addr, char *mod); 342int pevent_register_function(struct pevent *pevetn, char *name,
291int pevent_register_print_string(char *fmt, unsigned long long addr); 343 unsigned long long addr, char *mod);
344int pevent_register_print_string(struct pevent *pevent, char *fmt,
345 unsigned long long addr);
292 346
293void pevent_print_event(struct trace_seq *s, 347void 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
296int pevent_parse_header_page(char *buf, unsigned long size); 350int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size);
297 351
298int pevent_parse_event(char *buf, unsigned long size, char *sys); 352int pevent_parse_event(struct pevent *pevent, char *buf, unsigned long size, char *sys);
299 353
300int pevent_register_event_handler(int id, char *sys_name, char *event_name, 354int 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
303struct format_field *pevent_find_common_field(struct event *event, const char *name); 357struct format_field *pevent_find_common_field(struct event *event, const char *name);
304struct format_field *pevent_find_field(struct event *event, const char *name); 358struct format_field *pevent_find_field(struct event *event, const char *name);
305struct format_field *pevent_find_any_field(struct event *event, const char *name); 359struct format_field *pevent_find_any_field(struct event *event, const char *name);
306 360
307const char *pevent_find_function(unsigned long long addr); 361const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
308unsigned long long pevent_read_number(const void *ptr, int size); 362unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size);
309int pevent_read_number_field(struct format_field *field, const void *data, 363int pevent_read_number_field(struct format_field *field, const void *data,
310 unsigned long long *value); 364 unsigned long long *value);
311 365
312struct event *pevent_find_event(int id); 366struct event *pevent_find_event(struct pevent *pevent, int id);
313 367
314struct event * 368struct event *
315pevent_find_event_by_name(const char *sys, const char *name); 369pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
316 370
317void pevent_data_lat_fmt(struct trace_seq *s, void *data, int size __unused); 371void pevent_data_lat_fmt(struct pevent *pevent,
318int pevent_data_type(void *data); 372 struct trace_seq *s, void *data, int size __unused);
319struct event *pevent_data_event_from_type(int type); 373int pevent_data_type(struct pevent *pevent, void *data);
320int pevent_data_pid(void *data); 374struct event *pevent_data_event_from_type(struct pevent *pevent, int type);
321const char *pevent_data_comm_from_pid(int pid); 375int pevent_data_pid(struct pevent *pevent, void *data);
376const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
322void pevent_event_info(struct trace_seq *s, struct event *event, 377void 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
325struct event **pevent_list_events(enum event_sort_type); 380struct event **pevent_list_events(struct pevent *pevent, enum event_sort_type);
381
382static inline int pevent_get_cpus(struct pevent *pevent)
383{
384 return pevent->cpus;
385}
386
387static inline void pevent_set_cpus(struct pevent *pevent, int cpus)
388{
389 pevent->cpus = cpus;
390}
391
392static inline int pevent_get_long_size(struct pevent *pevent)
393{
394 return pevent->long_size;
395}
396
397static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
398{
399 pevent->long_size = long_size;
400}
401
402static inline int pevent_is_file_bigendian(struct pevent *pevent)
403{
404 return pevent->file_bigendian;
405}
406
407static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian)
408{
409 pevent->file_bigendian = endian;
410}
411
412static inline int pevent_is_host_bigendian(struct pevent *pevent)
413{
414 return pevent->host_bigendian;
415}
416
417static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian)
418{
419 pevent->host_bigendian = endian;
420}
421
422static inline int pevent_is_latency_format(struct pevent *pevent)
423{
424 return pevent->latency_format;
425}
426
427static inline void pevent_set_latency_format(struct pevent *pevent, int lat)
428{
429 pevent->latency_format = lat;
430}
431
432struct pevent *pevent_alloc(void);
433void pevent_free(struct pevent *pevent);
326 434
327/* for debugging */ 435/* for debugging */
328void pevent_print_funcs(void); 436void pevent_print_funcs(struct pevent *pevent);
329void pevent_print_printk(void); 437void 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
83int PEVENT_PLUGIN_LOADER(void) 84int 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
197int PEVENT_PLUGIN_LOADER(void) 197int 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
13void parse_cmdlines(char *file, int size); 13void parse_cmdlines(struct pevent *pevent, char *file, int size);
14void parse_proc_kallsyms(char *file, unsigned int size); 14void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
15void parse_ftrace_printk(char *file, unsigned int size); 15void parse_ftrace_printk(char *file, unsigned int size);
16 16
17int trace_load_plugins(void); 17int trace_load_plugins(struct pevent *pevent);
18 18
19enum { 19enum {
20 RINGBUF_TYPE_PADDING = 29, 20 RINGBUF_TYPE_PADDING = 29,
@@ -57,7 +57,8 @@ struct record *
57tracecmd_translate_data(struct tracecmd_handle *handle, 57tracecmd_translate_data(struct tracecmd_handle *handle,
58 void *ptr, int size); 58 void *ptr, int size);
59 59
60int tracecmd_ftrace_overrides(void); 60int tracecmd_ftrace_overrides(struct tracecmd_handle *handle);
61struct pevent *tracecmd_get_pevent(struct tracecmd_handle *handle);
61 62
62/* hack for function graph work around */ 63/* hack for function graph work around */
63extern __thread struct tracecmd_handle *tracecmd_curr_thread_handle; 64extern __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
145print_graph_entry_leaf(struct trace_seq *s, 146print_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,
186static int print_graph_nested(struct trace_seq *s, 188static 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
289int tracecmd_ftrace_overrides(void) 292int 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
36struct tracecmd_handle { 36struct 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
148static unsigned int read4(struct tracecmd_handle *handle) 149static 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
158static unsigned long long read8(struct tracecmd_handle *handle) 160static 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
168static int read_header_files(struct tracecmd_handle *handle) 171static 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)
226static int read_ftrace_file(struct tracecmd_handle *handle, 230static 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,
245static int read_event_file(struct tracecmd_handle *handle, 250static 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
332static int read_proc_kallsyms(struct tracecmd_handle *handle) 338static 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
385int tracecmd_read_headers(struct tracecmd_handle *handle) 392int 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
417static unsigned int type4host(unsigned int type_len_ts) 425static 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
425static unsigned int len4host(unsigned int type_len_ts) 436static 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
433static unsigned int type_len4host(unsigned int type_len_ts) 447static 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
441static unsigned int ts4host(unsigned int type_len_ts) 458static 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 {
522static struct record * 542static struct record *
523read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) 543read_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
711static unsigned int 732static unsigned int
712translate_data(void **ptr, unsigned long long *delta, int *length) 733translate_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,
787struct record * 810struct record *
788tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) 811tracecmd_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
831read_again: 855read_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
950int tracecmd_init_data(struct tracecmd_handle *handle) 974int 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
1104struct 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
49static void show_data(struct tracecmd_handle *handle, int cpu) 49static 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)
132void trace_report (int argc, char **argv) 135void 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
72void parse_cmdlines(char *file, int size __unused) 72void 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
88void parse_proc_kallsyms(char *file, unsigned int size __unused) 89void 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
139static int load_plugin(const char *path, const char *file) 141static 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
173int trace_load_plugins(void) 176int 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: