aboutsummaryrefslogtreecommitdiffstats
path: root/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse-events.c')
-rw-r--r--parse-events.c453
1 files changed, 258 insertions, 195 deletions
diff --git a/parse-events.c b/parse-events.c
index 8a59433..fe683c9 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -30,27 +30,10 @@
30 30
31#include "parse-events.h" 31#include "parse-events.h"
32 32
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}