aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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: