perf hists: Move sort__has_thread into struct perf_hpp_list
[linux-2.6-block.git] / tools / perf / util / sort.c
1 #include <sys/mman.h>
2 #include "sort.h"
3 #include "hist.h"
4 #include "comm.h"
5 #include "symbol.h"
6 #include "evsel.h"
7 #include "evlist.h"
8 #include <traceevent/event-parse.h>
9 #include "mem-events.h"
10
11 regex_t         parent_regex;
12 const char      default_parent_pattern[] = "^sys_|^do_page_fault";
13 const char      *parent_pattern = default_parent_pattern;
14 const char      default_sort_order[] = "comm,dso,symbol";
15 const char      default_branch_sort_order[] = "comm,dso_from,symbol_from,symbol_to,cycles";
16 const char      default_mem_sort_order[] = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked";
17 const char      default_top_sort_order[] = "dso,symbol";
18 const char      default_diff_sort_order[] = "dso,symbol";
19 const char      default_tracepoint_sort_order[] = "trace";
20 const char      *sort_order;
21 const char      *field_order;
22 regex_t         ignore_callees_regex;
23 int             have_ignore_callees = 0;
24 int             sort__has_comm = 0;
25 enum sort_mode  sort__mode = SORT_MODE__NORMAL;
26
27 /*
28  * Replaces all occurrences of a char used with the:
29  *
30  * -t, --field-separator
31  *
32  * option, that uses a special separator character and don't pad with spaces,
33  * replacing all occurances of this separator in symbol names (and other
34  * output) with a '.' character, that thus it's the only non valid separator.
35 */
36 static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
37 {
38         int n;
39         va_list ap;
40
41         va_start(ap, fmt);
42         n = vsnprintf(bf, size, fmt, ap);
43         if (symbol_conf.field_sep && n > 0) {
44                 char *sep = bf;
45
46                 while (1) {
47                         sep = strchr(sep, *symbol_conf.field_sep);
48                         if (sep == NULL)
49                                 break;
50                         *sep = '.';
51                 }
52         }
53         va_end(ap);
54
55         if (n >= (int)size)
56                 return size - 1;
57         return n;
58 }
59
60 static int64_t cmp_null(const void *l, const void *r)
61 {
62         if (!l && !r)
63                 return 0;
64         else if (!l)
65                 return -1;
66         else
67                 return 1;
68 }
69
70 /* --sort pid */
71
72 static int64_t
73 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
74 {
75         return right->thread->tid - left->thread->tid;
76 }
77
78 static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
79                                        size_t size, unsigned int width)
80 {
81         const char *comm = thread__comm_str(he->thread);
82
83         width = max(7U, width) - 6;
84         return repsep_snprintf(bf, size, "%5d:%-*.*s", he->thread->tid,
85                                width, width, comm ?: "");
86 }
87
88 static int hist_entry__thread_filter(struct hist_entry *he, int type, const void *arg)
89 {
90         const struct thread *th = arg;
91
92         if (type != HIST_FILTER__THREAD)
93                 return -1;
94
95         return th && he->thread != th;
96 }
97
98 struct sort_entry sort_thread = {
99         .se_header      = "  Pid:Command",
100         .se_cmp         = sort__thread_cmp,
101         .se_snprintf    = hist_entry__thread_snprintf,
102         .se_filter      = hist_entry__thread_filter,
103         .se_width_idx   = HISTC_THREAD,
104 };
105
106 /* --sort comm */
107
108 static int64_t
109 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
110 {
111         /* Compare the addr that should be unique among comm */
112         return strcmp(comm__str(right->comm), comm__str(left->comm));
113 }
114
115 static int64_t
116 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
117 {
118         /* Compare the addr that should be unique among comm */
119         return strcmp(comm__str(right->comm), comm__str(left->comm));
120 }
121
122 static int64_t
123 sort__comm_sort(struct hist_entry *left, struct hist_entry *right)
124 {
125         return strcmp(comm__str(right->comm), comm__str(left->comm));
126 }
127
128 static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
129                                      size_t size, unsigned int width)
130 {
131         return repsep_snprintf(bf, size, "%-*.*s", width, width, comm__str(he->comm));
132 }
133
134 struct sort_entry sort_comm = {
135         .se_header      = "Command",
136         .se_cmp         = sort__comm_cmp,
137         .se_collapse    = sort__comm_collapse,
138         .se_sort        = sort__comm_sort,
139         .se_snprintf    = hist_entry__comm_snprintf,
140         .se_filter      = hist_entry__thread_filter,
141         .se_width_idx   = HISTC_COMM,
142 };
143
144 /* --sort dso */
145
146 static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
147 {
148         struct dso *dso_l = map_l ? map_l->dso : NULL;
149         struct dso *dso_r = map_r ? map_r->dso : NULL;
150         const char *dso_name_l, *dso_name_r;
151
152         if (!dso_l || !dso_r)
153                 return cmp_null(dso_r, dso_l);
154
155         if (verbose) {
156                 dso_name_l = dso_l->long_name;
157                 dso_name_r = dso_r->long_name;
158         } else {
159                 dso_name_l = dso_l->short_name;
160                 dso_name_r = dso_r->short_name;
161         }
162
163         return strcmp(dso_name_l, dso_name_r);
164 }
165
166 static int64_t
167 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
168 {
169         return _sort__dso_cmp(right->ms.map, left->ms.map);
170 }
171
172 static int _hist_entry__dso_snprintf(struct map *map, char *bf,
173                                      size_t size, unsigned int width)
174 {
175         if (map && map->dso) {
176                 const char *dso_name = !verbose ? map->dso->short_name :
177                         map->dso->long_name;
178                 return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name);
179         }
180
181         return repsep_snprintf(bf, size, "%-*.*s", width, width, "[unknown]");
182 }
183
184 static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
185                                     size_t size, unsigned int width)
186 {
187         return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
188 }
189
190 static int hist_entry__dso_filter(struct hist_entry *he, int type, const void *arg)
191 {
192         const struct dso *dso = arg;
193
194         if (type != HIST_FILTER__DSO)
195                 return -1;
196
197         return dso && (!he->ms.map || he->ms.map->dso != dso);
198 }
199
200 struct sort_entry sort_dso = {
201         .se_header      = "Shared Object",
202         .se_cmp         = sort__dso_cmp,
203         .se_snprintf    = hist_entry__dso_snprintf,
204         .se_filter      = hist_entry__dso_filter,
205         .se_width_idx   = HISTC_DSO,
206 };
207
208 /* --sort symbol */
209
210 static int64_t _sort__addr_cmp(u64 left_ip, u64 right_ip)
211 {
212         return (int64_t)(right_ip - left_ip);
213 }
214
215 static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
216 {
217         if (!sym_l || !sym_r)
218                 return cmp_null(sym_l, sym_r);
219
220         if (sym_l == sym_r)
221                 return 0;
222
223         if (sym_l->start != sym_r->start)
224                 return (int64_t)(sym_r->start - sym_l->start);
225
226         return (int64_t)(sym_r->end - sym_l->end);
227 }
228
229 static int64_t
230 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
231 {
232         int64_t ret;
233
234         if (!left->ms.sym && !right->ms.sym)
235                 return _sort__addr_cmp(left->ip, right->ip);
236
237         /*
238          * comparing symbol address alone is not enough since it's a
239          * relative address within a dso.
240          */
241         if (!hists__has(left->hists, dso) || hists__has(right->hists, dso)) {
242                 ret = sort__dso_cmp(left, right);
243                 if (ret != 0)
244                         return ret;
245         }
246
247         return _sort__sym_cmp(left->ms.sym, right->ms.sym);
248 }
249
250 static int64_t
251 sort__sym_sort(struct hist_entry *left, struct hist_entry *right)
252 {
253         if (!left->ms.sym || !right->ms.sym)
254                 return cmp_null(left->ms.sym, right->ms.sym);
255
256         return strcmp(right->ms.sym->name, left->ms.sym->name);
257 }
258
259 static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
260                                      u64 ip, char level, char *bf, size_t size,
261                                      unsigned int width)
262 {
263         size_t ret = 0;
264
265         if (verbose) {
266                 char o = map ? dso__symtab_origin(map->dso) : '!';
267                 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
268                                        BITS_PER_LONG / 4 + 2, ip, o);
269         }
270
271         ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
272         if (sym && map) {
273                 if (map->type == MAP__VARIABLE) {
274                         ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
275                         ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
276                                         ip - map->unmap_ip(map, sym->start));
277                 } else {
278                         ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
279                                                width - ret,
280                                                sym->name);
281                 }
282         } else {
283                 size_t len = BITS_PER_LONG / 4;
284                 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx",
285                                        len, ip);
286         }
287
288         return ret;
289 }
290
291 static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
292                                     size_t size, unsigned int width)
293 {
294         return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
295                                          he->level, bf, size, width);
296 }
297
298 static int hist_entry__sym_filter(struct hist_entry *he, int type, const void *arg)
299 {
300         const char *sym = arg;
301
302         if (type != HIST_FILTER__SYMBOL)
303                 return -1;
304
305         return sym && (!he->ms.sym || !strstr(he->ms.sym->name, sym));
306 }
307
308 struct sort_entry sort_sym = {
309         .se_header      = "Symbol",
310         .se_cmp         = sort__sym_cmp,
311         .se_sort        = sort__sym_sort,
312         .se_snprintf    = hist_entry__sym_snprintf,
313         .se_filter      = hist_entry__sym_filter,
314         .se_width_idx   = HISTC_SYMBOL,
315 };
316
317 /* --sort srcline */
318
319 static char *hist_entry__get_srcline(struct hist_entry *he)
320 {
321         struct map *map = he->ms.map;
322
323         if (!map)
324                 return SRCLINE_UNKNOWN;
325
326         return get_srcline(map->dso, map__rip_2objdump(map, he->ip),
327                            he->ms.sym, true);
328 }
329
330 static int64_t
331 sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
332 {
333         if (!left->srcline)
334                 left->srcline = hist_entry__get_srcline(left);
335         if (!right->srcline)
336                 right->srcline = hist_entry__get_srcline(right);
337
338         return strcmp(right->srcline, left->srcline);
339 }
340
341 static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
342                                         size_t size, unsigned int width)
343 {
344         if (!he->srcline)
345                 he->srcline = hist_entry__get_srcline(he);
346
347         return repsep_snprintf(bf, size, "%-.*s", width, he->srcline);
348 }
349
350 struct sort_entry sort_srcline = {
351         .se_header      = "Source:Line",
352         .se_cmp         = sort__srcline_cmp,
353         .se_snprintf    = hist_entry__srcline_snprintf,
354         .se_width_idx   = HISTC_SRCLINE,
355 };
356
357 /* --sort srcfile */
358
359 static char no_srcfile[1];
360
361 static char *hist_entry__get_srcfile(struct hist_entry *e)
362 {
363         char *sf, *p;
364         struct map *map = e->ms.map;
365
366         if (!map)
367                 return no_srcfile;
368
369         sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip),
370                          e->ms.sym, false, true);
371         if (!strcmp(sf, SRCLINE_UNKNOWN))
372                 return no_srcfile;
373         p = strchr(sf, ':');
374         if (p && *sf) {
375                 *p = 0;
376                 return sf;
377         }
378         free(sf);
379         return no_srcfile;
380 }
381
382 static int64_t
383 sort__srcfile_cmp(struct hist_entry *left, struct hist_entry *right)
384 {
385         if (!left->srcfile)
386                 left->srcfile = hist_entry__get_srcfile(left);
387         if (!right->srcfile)
388                 right->srcfile = hist_entry__get_srcfile(right);
389
390         return strcmp(right->srcfile, left->srcfile);
391 }
392
393 static int hist_entry__srcfile_snprintf(struct hist_entry *he, char *bf,
394                                         size_t size, unsigned int width)
395 {
396         if (!he->srcfile)
397                 he->srcfile = hist_entry__get_srcfile(he);
398
399         return repsep_snprintf(bf, size, "%-.*s", width, he->srcfile);
400 }
401
402 struct sort_entry sort_srcfile = {
403         .se_header      = "Source File",
404         .se_cmp         = sort__srcfile_cmp,
405         .se_snprintf    = hist_entry__srcfile_snprintf,
406         .se_width_idx   = HISTC_SRCFILE,
407 };
408
409 /* --sort parent */
410
411 static int64_t
412 sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
413 {
414         struct symbol *sym_l = left->parent;
415         struct symbol *sym_r = right->parent;
416
417         if (!sym_l || !sym_r)
418                 return cmp_null(sym_l, sym_r);
419
420         return strcmp(sym_r->name, sym_l->name);
421 }
422
423 static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
424                                        size_t size, unsigned int width)
425 {
426         return repsep_snprintf(bf, size, "%-*.*s", width, width,
427                               he->parent ? he->parent->name : "[other]");
428 }
429
430 struct sort_entry sort_parent = {
431         .se_header      = "Parent symbol",
432         .se_cmp         = sort__parent_cmp,
433         .se_snprintf    = hist_entry__parent_snprintf,
434         .se_width_idx   = HISTC_PARENT,
435 };
436
437 /* --sort cpu */
438
439 static int64_t
440 sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
441 {
442         return right->cpu - left->cpu;
443 }
444
445 static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
446                                     size_t size, unsigned int width)
447 {
448         return repsep_snprintf(bf, size, "%*.*d", width, width, he->cpu);
449 }
450
451 struct sort_entry sort_cpu = {
452         .se_header      = "CPU",
453         .se_cmp         = sort__cpu_cmp,
454         .se_snprintf    = hist_entry__cpu_snprintf,
455         .se_width_idx   = HISTC_CPU,
456 };
457
458 /* --sort socket */
459
460 static int64_t
461 sort__socket_cmp(struct hist_entry *left, struct hist_entry *right)
462 {
463         return right->socket - left->socket;
464 }
465
466 static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf,
467                                     size_t size, unsigned int width)
468 {
469         return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket);
470 }
471
472 static int hist_entry__socket_filter(struct hist_entry *he, int type, const void *arg)
473 {
474         int sk = *(const int *)arg;
475
476         if (type != HIST_FILTER__SOCKET)
477                 return -1;
478
479         return sk >= 0 && he->socket != sk;
480 }
481
482 struct sort_entry sort_socket = {
483         .se_header      = "Socket",
484         .se_cmp         = sort__socket_cmp,
485         .se_snprintf    = hist_entry__socket_snprintf,
486         .se_filter      = hist_entry__socket_filter,
487         .se_width_idx   = HISTC_SOCKET,
488 };
489
490 /* --sort trace */
491
492 static char *get_trace_output(struct hist_entry *he)
493 {
494         struct trace_seq seq;
495         struct perf_evsel *evsel;
496         struct pevent_record rec = {
497                 .data = he->raw_data,
498                 .size = he->raw_size,
499         };
500
501         evsel = hists_to_evsel(he->hists);
502
503         trace_seq_init(&seq);
504         if (symbol_conf.raw_trace) {
505                 pevent_print_fields(&seq, he->raw_data, he->raw_size,
506                                     evsel->tp_format);
507         } else {
508                 pevent_event_info(&seq, evsel->tp_format, &rec);
509         }
510         return seq.buffer;
511 }
512
513 static int64_t
514 sort__trace_cmp(struct hist_entry *left, struct hist_entry *right)
515 {
516         struct perf_evsel *evsel;
517
518         evsel = hists_to_evsel(left->hists);
519         if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
520                 return 0;
521
522         if (left->trace_output == NULL)
523                 left->trace_output = get_trace_output(left);
524         if (right->trace_output == NULL)
525                 right->trace_output = get_trace_output(right);
526
527         return strcmp(right->trace_output, left->trace_output);
528 }
529
530 static int hist_entry__trace_snprintf(struct hist_entry *he, char *bf,
531                                     size_t size, unsigned int width)
532 {
533         struct perf_evsel *evsel;
534
535         evsel = hists_to_evsel(he->hists);
536         if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
537                 return scnprintf(bf, size, "%-.*s", width, "N/A");
538
539         if (he->trace_output == NULL)
540                 he->trace_output = get_trace_output(he);
541         return repsep_snprintf(bf, size, "%-.*s", width, he->trace_output);
542 }
543
544 struct sort_entry sort_trace = {
545         .se_header      = "Trace output",
546         .se_cmp         = sort__trace_cmp,
547         .se_snprintf    = hist_entry__trace_snprintf,
548         .se_width_idx   = HISTC_TRACE,
549 };
550
551 /* sort keys for branch stacks */
552
553 static int64_t
554 sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
555 {
556         if (!left->branch_info || !right->branch_info)
557                 return cmp_null(left->branch_info, right->branch_info);
558
559         return _sort__dso_cmp(left->branch_info->from.map,
560                               right->branch_info->from.map);
561 }
562
563 static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
564                                     size_t size, unsigned int width)
565 {
566         if (he->branch_info)
567                 return _hist_entry__dso_snprintf(he->branch_info->from.map,
568                                                  bf, size, width);
569         else
570                 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
571 }
572
573 static int hist_entry__dso_from_filter(struct hist_entry *he, int type,
574                                        const void *arg)
575 {
576         const struct dso *dso = arg;
577
578         if (type != HIST_FILTER__DSO)
579                 return -1;
580
581         return dso && (!he->branch_info || !he->branch_info->from.map ||
582                        he->branch_info->from.map->dso != dso);
583 }
584
585 static int64_t
586 sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
587 {
588         if (!left->branch_info || !right->branch_info)
589                 return cmp_null(left->branch_info, right->branch_info);
590
591         return _sort__dso_cmp(left->branch_info->to.map,
592                               right->branch_info->to.map);
593 }
594
595 static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
596                                        size_t size, unsigned int width)
597 {
598         if (he->branch_info)
599                 return _hist_entry__dso_snprintf(he->branch_info->to.map,
600                                                  bf, size, width);
601         else
602                 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
603 }
604
605 static int hist_entry__dso_to_filter(struct hist_entry *he, int type,
606                                      const void *arg)
607 {
608         const struct dso *dso = arg;
609
610         if (type != HIST_FILTER__DSO)
611                 return -1;
612
613         return dso && (!he->branch_info || !he->branch_info->to.map ||
614                        he->branch_info->to.map->dso != dso);
615 }
616
617 static int64_t
618 sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
619 {
620         struct addr_map_symbol *from_l = &left->branch_info->from;
621         struct addr_map_symbol *from_r = &right->branch_info->from;
622
623         if (!left->branch_info || !right->branch_info)
624                 return cmp_null(left->branch_info, right->branch_info);
625
626         from_l = &left->branch_info->from;
627         from_r = &right->branch_info->from;
628
629         if (!from_l->sym && !from_r->sym)
630                 return _sort__addr_cmp(from_l->addr, from_r->addr);
631
632         return _sort__sym_cmp(from_l->sym, from_r->sym);
633 }
634
635 static int64_t
636 sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
637 {
638         struct addr_map_symbol *to_l, *to_r;
639
640         if (!left->branch_info || !right->branch_info)
641                 return cmp_null(left->branch_info, right->branch_info);
642
643         to_l = &left->branch_info->to;
644         to_r = &right->branch_info->to;
645
646         if (!to_l->sym && !to_r->sym)
647                 return _sort__addr_cmp(to_l->addr, to_r->addr);
648
649         return _sort__sym_cmp(to_l->sym, to_r->sym);
650 }
651
652 static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
653                                          size_t size, unsigned int width)
654 {
655         if (he->branch_info) {
656                 struct addr_map_symbol *from = &he->branch_info->from;
657
658                 return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
659                                                  he->level, bf, size, width);
660         }
661
662         return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
663 }
664
665 static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
666                                        size_t size, unsigned int width)
667 {
668         if (he->branch_info) {
669                 struct addr_map_symbol *to = &he->branch_info->to;
670
671                 return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
672                                                  he->level, bf, size, width);
673         }
674
675         return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
676 }
677
678 static int hist_entry__sym_from_filter(struct hist_entry *he, int type,
679                                        const void *arg)
680 {
681         const char *sym = arg;
682
683         if (type != HIST_FILTER__SYMBOL)
684                 return -1;
685
686         return sym && !(he->branch_info && he->branch_info->from.sym &&
687                         strstr(he->branch_info->from.sym->name, sym));
688 }
689
690 static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
691                                        const void *arg)
692 {
693         const char *sym = arg;
694
695         if (type != HIST_FILTER__SYMBOL)
696                 return -1;
697
698         return sym && !(he->branch_info && he->branch_info->to.sym &&
699                         strstr(he->branch_info->to.sym->name, sym));
700 }
701
702 struct sort_entry sort_dso_from = {
703         .se_header      = "Source Shared Object",
704         .se_cmp         = sort__dso_from_cmp,
705         .se_snprintf    = hist_entry__dso_from_snprintf,
706         .se_filter      = hist_entry__dso_from_filter,
707         .se_width_idx   = HISTC_DSO_FROM,
708 };
709
710 struct sort_entry sort_dso_to = {
711         .se_header      = "Target Shared Object",
712         .se_cmp         = sort__dso_to_cmp,
713         .se_snprintf    = hist_entry__dso_to_snprintf,
714         .se_filter      = hist_entry__dso_to_filter,
715         .se_width_idx   = HISTC_DSO_TO,
716 };
717
718 struct sort_entry sort_sym_from = {
719         .se_header      = "Source Symbol",
720         .se_cmp         = sort__sym_from_cmp,
721         .se_snprintf    = hist_entry__sym_from_snprintf,
722         .se_filter      = hist_entry__sym_from_filter,
723         .se_width_idx   = HISTC_SYMBOL_FROM,
724 };
725
726 struct sort_entry sort_sym_to = {
727         .se_header      = "Target Symbol",
728         .se_cmp         = sort__sym_to_cmp,
729         .se_snprintf    = hist_entry__sym_to_snprintf,
730         .se_filter      = hist_entry__sym_to_filter,
731         .se_width_idx   = HISTC_SYMBOL_TO,
732 };
733
734 static int64_t
735 sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
736 {
737         unsigned char mp, p;
738
739         if (!left->branch_info || !right->branch_info)
740                 return cmp_null(left->branch_info, right->branch_info);
741
742         mp = left->branch_info->flags.mispred != right->branch_info->flags.mispred;
743         p  = left->branch_info->flags.predicted != right->branch_info->flags.predicted;
744         return mp || p;
745 }
746
747 static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
748                                     size_t size, unsigned int width){
749         static const char *out = "N/A";
750
751         if (he->branch_info) {
752                 if (he->branch_info->flags.predicted)
753                         out = "N";
754                 else if (he->branch_info->flags.mispred)
755                         out = "Y";
756         }
757
758         return repsep_snprintf(bf, size, "%-*.*s", width, width, out);
759 }
760
761 static int64_t
762 sort__cycles_cmp(struct hist_entry *left, struct hist_entry *right)
763 {
764         return left->branch_info->flags.cycles -
765                 right->branch_info->flags.cycles;
766 }
767
768 static int hist_entry__cycles_snprintf(struct hist_entry *he, char *bf,
769                                     size_t size, unsigned int width)
770 {
771         if (he->branch_info->flags.cycles == 0)
772                 return repsep_snprintf(bf, size, "%-*s", width, "-");
773         return repsep_snprintf(bf, size, "%-*hd", width,
774                                he->branch_info->flags.cycles);
775 }
776
777 struct sort_entry sort_cycles = {
778         .se_header      = "Basic Block Cycles",
779         .se_cmp         = sort__cycles_cmp,
780         .se_snprintf    = hist_entry__cycles_snprintf,
781         .se_width_idx   = HISTC_CYCLES,
782 };
783
784 /* --sort daddr_sym */
785 static int64_t
786 sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
787 {
788         uint64_t l = 0, r = 0;
789
790         if (left->mem_info)
791                 l = left->mem_info->daddr.addr;
792         if (right->mem_info)
793                 r = right->mem_info->daddr.addr;
794
795         return (int64_t)(r - l);
796 }
797
798 static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
799                                     size_t size, unsigned int width)
800 {
801         uint64_t addr = 0;
802         struct map *map = NULL;
803         struct symbol *sym = NULL;
804
805         if (he->mem_info) {
806                 addr = he->mem_info->daddr.addr;
807                 map = he->mem_info->daddr.map;
808                 sym = he->mem_info->daddr.sym;
809         }
810         return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
811                                          width);
812 }
813
814 static int64_t
815 sort__iaddr_cmp(struct hist_entry *left, struct hist_entry *right)
816 {
817         uint64_t l = 0, r = 0;
818
819         if (left->mem_info)
820                 l = left->mem_info->iaddr.addr;
821         if (right->mem_info)
822                 r = right->mem_info->iaddr.addr;
823
824         return (int64_t)(r - l);
825 }
826
827 static int hist_entry__iaddr_snprintf(struct hist_entry *he, char *bf,
828                                     size_t size, unsigned int width)
829 {
830         uint64_t addr = 0;
831         struct map *map = NULL;
832         struct symbol *sym = NULL;
833
834         if (he->mem_info) {
835                 addr = he->mem_info->iaddr.addr;
836                 map  = he->mem_info->iaddr.map;
837                 sym  = he->mem_info->iaddr.sym;
838         }
839         return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
840                                          width);
841 }
842
843 static int64_t
844 sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
845 {
846         struct map *map_l = NULL;
847         struct map *map_r = NULL;
848
849         if (left->mem_info)
850                 map_l = left->mem_info->daddr.map;
851         if (right->mem_info)
852                 map_r = right->mem_info->daddr.map;
853
854         return _sort__dso_cmp(map_l, map_r);
855 }
856
857 static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
858                                     size_t size, unsigned int width)
859 {
860         struct map *map = NULL;
861
862         if (he->mem_info)
863                 map = he->mem_info->daddr.map;
864
865         return _hist_entry__dso_snprintf(map, bf, size, width);
866 }
867
868 static int64_t
869 sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
870 {
871         union perf_mem_data_src data_src_l;
872         union perf_mem_data_src data_src_r;
873
874         if (left->mem_info)
875                 data_src_l = left->mem_info->data_src;
876         else
877                 data_src_l.mem_lock = PERF_MEM_LOCK_NA;
878
879         if (right->mem_info)
880                 data_src_r = right->mem_info->data_src;
881         else
882                 data_src_r.mem_lock = PERF_MEM_LOCK_NA;
883
884         return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
885 }
886
887 static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
888                                     size_t size, unsigned int width)
889 {
890         char out[10];
891
892         perf_mem__lck_scnprintf(out, sizeof(out), he->mem_info);
893         return repsep_snprintf(bf, size, "%.*s", width, out);
894 }
895
896 static int64_t
897 sort__tlb_cmp(struct hist_entry *left, struct hist_entry *right)
898 {
899         union perf_mem_data_src data_src_l;
900         union perf_mem_data_src data_src_r;
901
902         if (left->mem_info)
903                 data_src_l = left->mem_info->data_src;
904         else
905                 data_src_l.mem_dtlb = PERF_MEM_TLB_NA;
906
907         if (right->mem_info)
908                 data_src_r = right->mem_info->data_src;
909         else
910                 data_src_r.mem_dtlb = PERF_MEM_TLB_NA;
911
912         return (int64_t)(data_src_r.mem_dtlb - data_src_l.mem_dtlb);
913 }
914
915 static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
916                                     size_t size, unsigned int width)
917 {
918         char out[64];
919
920         perf_mem__tlb_scnprintf(out, sizeof(out), he->mem_info);
921         return repsep_snprintf(bf, size, "%-*s", width, out);
922 }
923
924 static int64_t
925 sort__lvl_cmp(struct hist_entry *left, struct hist_entry *right)
926 {
927         union perf_mem_data_src data_src_l;
928         union perf_mem_data_src data_src_r;
929
930         if (left->mem_info)
931                 data_src_l = left->mem_info->data_src;
932         else
933                 data_src_l.mem_lvl = PERF_MEM_LVL_NA;
934
935         if (right->mem_info)
936                 data_src_r = right->mem_info->data_src;
937         else
938                 data_src_r.mem_lvl = PERF_MEM_LVL_NA;
939
940         return (int64_t)(data_src_r.mem_lvl - data_src_l.mem_lvl);
941 }
942
943 static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
944                                     size_t size, unsigned int width)
945 {
946         char out[64];
947
948         perf_mem__lvl_scnprintf(out, sizeof(out), he->mem_info);
949         return repsep_snprintf(bf, size, "%-*s", width, out);
950 }
951
952 static int64_t
953 sort__snoop_cmp(struct hist_entry *left, struct hist_entry *right)
954 {
955         union perf_mem_data_src data_src_l;
956         union perf_mem_data_src data_src_r;
957
958         if (left->mem_info)
959                 data_src_l = left->mem_info->data_src;
960         else
961                 data_src_l.mem_snoop = PERF_MEM_SNOOP_NA;
962
963         if (right->mem_info)
964                 data_src_r = right->mem_info->data_src;
965         else
966                 data_src_r.mem_snoop = PERF_MEM_SNOOP_NA;
967
968         return (int64_t)(data_src_r.mem_snoop - data_src_l.mem_snoop);
969 }
970
971 static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
972                                     size_t size, unsigned int width)
973 {
974         char out[64];
975
976         perf_mem__snp_scnprintf(out, sizeof(out), he->mem_info);
977         return repsep_snprintf(bf, size, "%-*s", width, out);
978 }
979
980 static int64_t
981 sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
982 {
983         u64 l, r;
984         struct map *l_map, *r_map;
985
986         if (!left->mem_info)  return -1;
987         if (!right->mem_info) return 1;
988
989         /* group event types together */
990         if (left->cpumode > right->cpumode) return -1;
991         if (left->cpumode < right->cpumode) return 1;
992
993         l_map = left->mem_info->daddr.map;
994         r_map = right->mem_info->daddr.map;
995
996         /* if both are NULL, jump to sort on al_addr instead */
997         if (!l_map && !r_map)
998                 goto addr;
999
1000         if (!l_map) return -1;
1001         if (!r_map) return 1;
1002
1003         if (l_map->maj > r_map->maj) return -1;
1004         if (l_map->maj < r_map->maj) return 1;
1005
1006         if (l_map->min > r_map->min) return -1;
1007         if (l_map->min < r_map->min) return 1;
1008
1009         if (l_map->ino > r_map->ino) return -1;
1010         if (l_map->ino < r_map->ino) return 1;
1011
1012         if (l_map->ino_generation > r_map->ino_generation) return -1;
1013         if (l_map->ino_generation < r_map->ino_generation) return 1;
1014
1015         /*
1016          * Addresses with no major/minor numbers are assumed to be
1017          * anonymous in userspace.  Sort those on pid then address.
1018          *
1019          * The kernel and non-zero major/minor mapped areas are
1020          * assumed to be unity mapped.  Sort those on address.
1021          */
1022
1023         if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
1024             (!(l_map->flags & MAP_SHARED)) &&
1025             !l_map->maj && !l_map->min && !l_map->ino &&
1026             !l_map->ino_generation) {
1027                 /* userspace anonymous */
1028
1029                 if (left->thread->pid_ > right->thread->pid_) return -1;
1030                 if (left->thread->pid_ < right->thread->pid_) return 1;
1031         }
1032
1033 addr:
1034         /* al_addr does all the right addr - start + offset calculations */
1035         l = cl_address(left->mem_info->daddr.al_addr);
1036         r = cl_address(right->mem_info->daddr.al_addr);
1037
1038         if (l > r) return -1;
1039         if (l < r) return 1;
1040
1041         return 0;
1042 }
1043
1044 static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
1045                                           size_t size, unsigned int width)
1046 {
1047
1048         uint64_t addr = 0;
1049         struct map *map = NULL;
1050         struct symbol *sym = NULL;
1051         char level = he->level;
1052
1053         if (he->mem_info) {
1054                 addr = cl_address(he->mem_info->daddr.al_addr);
1055                 map = he->mem_info->daddr.map;
1056                 sym = he->mem_info->daddr.sym;
1057
1058                 /* print [s] for shared data mmaps */
1059                 if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
1060                      map && (map->type == MAP__VARIABLE) &&
1061                     (map->flags & MAP_SHARED) &&
1062                     (map->maj || map->min || map->ino ||
1063                      map->ino_generation))
1064                         level = 's';
1065                 else if (!map)
1066                         level = 'X';
1067         }
1068         return _hist_entry__sym_snprintf(map, sym, addr, level, bf, size,
1069                                          width);
1070 }
1071
1072 struct sort_entry sort_mispredict = {
1073         .se_header      = "Branch Mispredicted",
1074         .se_cmp         = sort__mispredict_cmp,
1075         .se_snprintf    = hist_entry__mispredict_snprintf,
1076         .se_width_idx   = HISTC_MISPREDICT,
1077 };
1078
1079 static u64 he_weight(struct hist_entry *he)
1080 {
1081         return he->stat.nr_events ? he->stat.weight / he->stat.nr_events : 0;
1082 }
1083
1084 static int64_t
1085 sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
1086 {
1087         return he_weight(left) - he_weight(right);
1088 }
1089
1090 static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
1091                                     size_t size, unsigned int width)
1092 {
1093         return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
1094 }
1095
1096 struct sort_entry sort_local_weight = {
1097         .se_header      = "Local Weight",
1098         .se_cmp         = sort__local_weight_cmp,
1099         .se_snprintf    = hist_entry__local_weight_snprintf,
1100         .se_width_idx   = HISTC_LOCAL_WEIGHT,
1101 };
1102
1103 static int64_t
1104 sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
1105 {
1106         return left->stat.weight - right->stat.weight;
1107 }
1108
1109 static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
1110                                               size_t size, unsigned int width)
1111 {
1112         return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
1113 }
1114
1115 struct sort_entry sort_global_weight = {
1116         .se_header      = "Weight",
1117         .se_cmp         = sort__global_weight_cmp,
1118         .se_snprintf    = hist_entry__global_weight_snprintf,
1119         .se_width_idx   = HISTC_GLOBAL_WEIGHT,
1120 };
1121
1122 struct sort_entry sort_mem_daddr_sym = {
1123         .se_header      = "Data Symbol",
1124         .se_cmp         = sort__daddr_cmp,
1125         .se_snprintf    = hist_entry__daddr_snprintf,
1126         .se_width_idx   = HISTC_MEM_DADDR_SYMBOL,
1127 };
1128
1129 struct sort_entry sort_mem_iaddr_sym = {
1130         .se_header      = "Code Symbol",
1131         .se_cmp         = sort__iaddr_cmp,
1132         .se_snprintf    = hist_entry__iaddr_snprintf,
1133         .se_width_idx   = HISTC_MEM_IADDR_SYMBOL,
1134 };
1135
1136 struct sort_entry sort_mem_daddr_dso = {
1137         .se_header      = "Data Object",
1138         .se_cmp         = sort__dso_daddr_cmp,
1139         .se_snprintf    = hist_entry__dso_daddr_snprintf,
1140         .se_width_idx   = HISTC_MEM_DADDR_SYMBOL,
1141 };
1142
1143 struct sort_entry sort_mem_locked = {
1144         .se_header      = "Locked",
1145         .se_cmp         = sort__locked_cmp,
1146         .se_snprintf    = hist_entry__locked_snprintf,
1147         .se_width_idx   = HISTC_MEM_LOCKED,
1148 };
1149
1150 struct sort_entry sort_mem_tlb = {
1151         .se_header      = "TLB access",
1152         .se_cmp         = sort__tlb_cmp,
1153         .se_snprintf    = hist_entry__tlb_snprintf,
1154         .se_width_idx   = HISTC_MEM_TLB,
1155 };
1156
1157 struct sort_entry sort_mem_lvl = {
1158         .se_header      = "Memory access",
1159         .se_cmp         = sort__lvl_cmp,
1160         .se_snprintf    = hist_entry__lvl_snprintf,
1161         .se_width_idx   = HISTC_MEM_LVL,
1162 };
1163
1164 struct sort_entry sort_mem_snoop = {
1165         .se_header      = "Snoop",
1166         .se_cmp         = sort__snoop_cmp,
1167         .se_snprintf    = hist_entry__snoop_snprintf,
1168         .se_width_idx   = HISTC_MEM_SNOOP,
1169 };
1170
1171 struct sort_entry sort_mem_dcacheline = {
1172         .se_header      = "Data Cacheline",
1173         .se_cmp         = sort__dcacheline_cmp,
1174         .se_snprintf    = hist_entry__dcacheline_snprintf,
1175         .se_width_idx   = HISTC_MEM_DCACHELINE,
1176 };
1177
1178 static int64_t
1179 sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
1180 {
1181         if (!left->branch_info || !right->branch_info)
1182                 return cmp_null(left->branch_info, right->branch_info);
1183
1184         return left->branch_info->flags.abort !=
1185                 right->branch_info->flags.abort;
1186 }
1187
1188 static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
1189                                     size_t size, unsigned int width)
1190 {
1191         static const char *out = "N/A";
1192
1193         if (he->branch_info) {
1194                 if (he->branch_info->flags.abort)
1195                         out = "A";
1196                 else
1197                         out = ".";
1198         }
1199
1200         return repsep_snprintf(bf, size, "%-*s", width, out);
1201 }
1202
1203 struct sort_entry sort_abort = {
1204         .se_header      = "Transaction abort",
1205         .se_cmp         = sort__abort_cmp,
1206         .se_snprintf    = hist_entry__abort_snprintf,
1207         .se_width_idx   = HISTC_ABORT,
1208 };
1209
1210 static int64_t
1211 sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
1212 {
1213         if (!left->branch_info || !right->branch_info)
1214                 return cmp_null(left->branch_info, right->branch_info);
1215
1216         return left->branch_info->flags.in_tx !=
1217                 right->branch_info->flags.in_tx;
1218 }
1219
1220 static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
1221                                     size_t size, unsigned int width)
1222 {
1223         static const char *out = "N/A";
1224
1225         if (he->branch_info) {
1226                 if (he->branch_info->flags.in_tx)
1227                         out = "T";
1228                 else
1229                         out = ".";
1230         }
1231
1232         return repsep_snprintf(bf, size, "%-*s", width, out);
1233 }
1234
1235 struct sort_entry sort_in_tx = {
1236         .se_header      = "Branch in transaction",
1237         .se_cmp         = sort__in_tx_cmp,
1238         .se_snprintf    = hist_entry__in_tx_snprintf,
1239         .se_width_idx   = HISTC_IN_TX,
1240 };
1241
1242 static int64_t
1243 sort__transaction_cmp(struct hist_entry *left, struct hist_entry *right)
1244 {
1245         return left->transaction - right->transaction;
1246 }
1247
1248 static inline char *add_str(char *p, const char *str)
1249 {
1250         strcpy(p, str);
1251         return p + strlen(str);
1252 }
1253
1254 static struct txbit {
1255         unsigned flag;
1256         const char *name;
1257         int skip_for_len;
1258 } txbits[] = {
1259         { PERF_TXN_ELISION,        "EL ",        0 },
1260         { PERF_TXN_TRANSACTION,    "TX ",        1 },
1261         { PERF_TXN_SYNC,           "SYNC ",      1 },
1262         { PERF_TXN_ASYNC,          "ASYNC ",     0 },
1263         { PERF_TXN_RETRY,          "RETRY ",     0 },
1264         { PERF_TXN_CONFLICT,       "CON ",       0 },
1265         { PERF_TXN_CAPACITY_WRITE, "CAP-WRITE ", 1 },
1266         { PERF_TXN_CAPACITY_READ,  "CAP-READ ",  0 },
1267         { 0, NULL, 0 }
1268 };
1269
1270 int hist_entry__transaction_len(void)
1271 {
1272         int i;
1273         int len = 0;
1274
1275         for (i = 0; txbits[i].name; i++) {
1276                 if (!txbits[i].skip_for_len)
1277                         len += strlen(txbits[i].name);
1278         }
1279         len += 4; /* :XX<space> */
1280         return len;
1281 }
1282
1283 static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
1284                                             size_t size, unsigned int width)
1285 {
1286         u64 t = he->transaction;
1287         char buf[128];
1288         char *p = buf;
1289         int i;
1290
1291         buf[0] = 0;
1292         for (i = 0; txbits[i].name; i++)
1293                 if (txbits[i].flag & t)
1294                         p = add_str(p, txbits[i].name);
1295         if (t && !(t & (PERF_TXN_SYNC|PERF_TXN_ASYNC)))
1296                 p = add_str(p, "NEITHER ");
1297         if (t & PERF_TXN_ABORT_MASK) {
1298                 sprintf(p, ":%" PRIx64,
1299                         (t & PERF_TXN_ABORT_MASK) >>
1300                         PERF_TXN_ABORT_SHIFT);
1301                 p += strlen(p);
1302         }
1303
1304         return repsep_snprintf(bf, size, "%-*s", width, buf);
1305 }
1306
1307 struct sort_entry sort_transaction = {
1308         .se_header      = "Transaction                ",
1309         .se_cmp         = sort__transaction_cmp,
1310         .se_snprintf    = hist_entry__transaction_snprintf,
1311         .se_width_idx   = HISTC_TRANSACTION,
1312 };
1313
1314 struct sort_dimension {
1315         const char              *name;
1316         struct sort_entry       *entry;
1317         int                     taken;
1318 };
1319
1320 #define DIM(d, n, func) [d] = { .name = n, .entry = &(func) }
1321
1322 static struct sort_dimension common_sort_dimensions[] = {
1323         DIM(SORT_PID, "pid", sort_thread),
1324         DIM(SORT_COMM, "comm", sort_comm),
1325         DIM(SORT_DSO, "dso", sort_dso),
1326         DIM(SORT_SYM, "symbol", sort_sym),
1327         DIM(SORT_PARENT, "parent", sort_parent),
1328         DIM(SORT_CPU, "cpu", sort_cpu),
1329         DIM(SORT_SOCKET, "socket", sort_socket),
1330         DIM(SORT_SRCLINE, "srcline", sort_srcline),
1331         DIM(SORT_SRCFILE, "srcfile", sort_srcfile),
1332         DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
1333         DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
1334         DIM(SORT_TRANSACTION, "transaction", sort_transaction),
1335         DIM(SORT_TRACE, "trace", sort_trace),
1336 };
1337
1338 #undef DIM
1339
1340 #define DIM(d, n, func) [d - __SORT_BRANCH_STACK] = { .name = n, .entry = &(func) }
1341
1342 static struct sort_dimension bstack_sort_dimensions[] = {
1343         DIM(SORT_DSO_FROM, "dso_from", sort_dso_from),
1344         DIM(SORT_DSO_TO, "dso_to", sort_dso_to),
1345         DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),
1346         DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
1347         DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
1348         DIM(SORT_IN_TX, "in_tx", sort_in_tx),
1349         DIM(SORT_ABORT, "abort", sort_abort),
1350         DIM(SORT_CYCLES, "cycles", sort_cycles),
1351 };
1352
1353 #undef DIM
1354
1355 #define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) }
1356
1357 static struct sort_dimension memory_sort_dimensions[] = {
1358         DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
1359         DIM(SORT_MEM_IADDR_SYMBOL, "symbol_iaddr", sort_mem_iaddr_sym),
1360         DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
1361         DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
1362         DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
1363         DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
1364         DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
1365         DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline),
1366 };
1367
1368 #undef DIM
1369
1370 struct hpp_dimension {
1371         const char              *name;
1372         struct perf_hpp_fmt     *fmt;
1373         int                     taken;
1374 };
1375
1376 #define DIM(d, n) { .name = n, .fmt = &perf_hpp__format[d], }
1377
1378 static struct hpp_dimension hpp_sort_dimensions[] = {
1379         DIM(PERF_HPP__OVERHEAD, "overhead"),
1380         DIM(PERF_HPP__OVERHEAD_SYS, "overhead_sys"),
1381         DIM(PERF_HPP__OVERHEAD_US, "overhead_us"),
1382         DIM(PERF_HPP__OVERHEAD_GUEST_SYS, "overhead_guest_sys"),
1383         DIM(PERF_HPP__OVERHEAD_GUEST_US, "overhead_guest_us"),
1384         DIM(PERF_HPP__OVERHEAD_ACC, "overhead_children"),
1385         DIM(PERF_HPP__SAMPLES, "sample"),
1386         DIM(PERF_HPP__PERIOD, "period"),
1387 };
1388
1389 #undef DIM
1390
1391 struct hpp_sort_entry {
1392         struct perf_hpp_fmt hpp;
1393         struct sort_entry *se;
1394 };
1395
1396 void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists)
1397 {
1398         struct hpp_sort_entry *hse;
1399
1400         if (!perf_hpp__is_sort_entry(fmt))
1401                 return;
1402
1403         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1404         hists__new_col_len(hists, hse->se->se_width_idx, strlen(fmt->name));
1405 }
1406
1407 static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1408                               struct perf_evsel *evsel)
1409 {
1410         struct hpp_sort_entry *hse;
1411         size_t len = fmt->user_len;
1412
1413         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1414
1415         if (!len)
1416                 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx);
1417
1418         return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name);
1419 }
1420
1421 static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
1422                              struct perf_hpp *hpp __maybe_unused,
1423                              struct perf_evsel *evsel)
1424 {
1425         struct hpp_sort_entry *hse;
1426         size_t len = fmt->user_len;
1427
1428         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1429
1430         if (!len)
1431                 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx);
1432
1433         return len;
1434 }
1435
1436 static int __sort__hpp_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1437                              struct hist_entry *he)
1438 {
1439         struct hpp_sort_entry *hse;
1440         size_t len = fmt->user_len;
1441
1442         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1443
1444         if (!len)
1445                 len = hists__col_len(he->hists, hse->se->se_width_idx);
1446
1447         return hse->se->se_snprintf(he, hpp->buf, hpp->size, len);
1448 }
1449
1450 static int64_t __sort__hpp_cmp(struct perf_hpp_fmt *fmt,
1451                                struct hist_entry *a, struct hist_entry *b)
1452 {
1453         struct hpp_sort_entry *hse;
1454
1455         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1456         return hse->se->se_cmp(a, b);
1457 }
1458
1459 static int64_t __sort__hpp_collapse(struct perf_hpp_fmt *fmt,
1460                                     struct hist_entry *a, struct hist_entry *b)
1461 {
1462         struct hpp_sort_entry *hse;
1463         int64_t (*collapse_fn)(struct hist_entry *, struct hist_entry *);
1464
1465         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1466         collapse_fn = hse->se->se_collapse ?: hse->se->se_cmp;
1467         return collapse_fn(a, b);
1468 }
1469
1470 static int64_t __sort__hpp_sort(struct perf_hpp_fmt *fmt,
1471                                 struct hist_entry *a, struct hist_entry *b)
1472 {
1473         struct hpp_sort_entry *hse;
1474         int64_t (*sort_fn)(struct hist_entry *, struct hist_entry *);
1475
1476         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1477         sort_fn = hse->se->se_sort ?: hse->se->se_cmp;
1478         return sort_fn(a, b);
1479 }
1480
1481 bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format)
1482 {
1483         return format->header == __sort__hpp_header;
1484 }
1485
1486 #define MK_SORT_ENTRY_CHK(key)                                  \
1487 bool perf_hpp__is_ ## key ## _entry(struct perf_hpp_fmt *fmt)   \
1488 {                                                               \
1489         struct hpp_sort_entry *hse;                             \
1490                                                                 \
1491         if (!perf_hpp__is_sort_entry(fmt))                      \
1492                 return false;                                   \
1493                                                                 \
1494         hse = container_of(fmt, struct hpp_sort_entry, hpp);    \
1495         return hse->se == &sort_ ## key ;                       \
1496 }
1497
1498 MK_SORT_ENTRY_CHK(trace)
1499 MK_SORT_ENTRY_CHK(srcline)
1500 MK_SORT_ENTRY_CHK(srcfile)
1501 MK_SORT_ENTRY_CHK(thread)
1502 MK_SORT_ENTRY_CHK(comm)
1503 MK_SORT_ENTRY_CHK(dso)
1504 MK_SORT_ENTRY_CHK(sym)
1505
1506
1507 static bool __sort__hpp_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
1508 {
1509         struct hpp_sort_entry *hse_a;
1510         struct hpp_sort_entry *hse_b;
1511
1512         if (!perf_hpp__is_sort_entry(a) || !perf_hpp__is_sort_entry(b))
1513                 return false;
1514
1515         hse_a = container_of(a, struct hpp_sort_entry, hpp);
1516         hse_b = container_of(b, struct hpp_sort_entry, hpp);
1517
1518         return hse_a->se == hse_b->se;
1519 }
1520
1521 static void hse_free(struct perf_hpp_fmt *fmt)
1522 {
1523         struct hpp_sort_entry *hse;
1524
1525         hse = container_of(fmt, struct hpp_sort_entry, hpp);
1526         free(hse);
1527 }
1528
1529 static struct hpp_sort_entry *
1530 __sort_dimension__alloc_hpp(struct sort_dimension *sd, int level)
1531 {
1532         struct hpp_sort_entry *hse;
1533
1534         hse = malloc(sizeof(*hse));
1535         if (hse == NULL) {
1536                 pr_err("Memory allocation failed\n");
1537                 return NULL;
1538         }
1539
1540         hse->se = sd->entry;
1541         hse->hpp.name = sd->entry->se_header;
1542         hse->hpp.header = __sort__hpp_header;
1543         hse->hpp.width = __sort__hpp_width;
1544         hse->hpp.entry = __sort__hpp_entry;
1545         hse->hpp.color = NULL;
1546
1547         hse->hpp.cmp = __sort__hpp_cmp;
1548         hse->hpp.collapse = __sort__hpp_collapse;
1549         hse->hpp.sort = __sort__hpp_sort;
1550         hse->hpp.equal = __sort__hpp_equal;
1551         hse->hpp.free = hse_free;
1552
1553         INIT_LIST_HEAD(&hse->hpp.list);
1554         INIT_LIST_HEAD(&hse->hpp.sort_list);
1555         hse->hpp.elide = false;
1556         hse->hpp.len = 0;
1557         hse->hpp.user_len = 0;
1558         hse->hpp.level = level;
1559
1560         return hse;
1561 }
1562
1563 static void hpp_free(struct perf_hpp_fmt *fmt)
1564 {
1565         free(fmt);
1566 }
1567
1568 static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd,
1569                                                        int level)
1570 {
1571         struct perf_hpp_fmt *fmt;
1572
1573         fmt = memdup(hd->fmt, sizeof(*fmt));
1574         if (fmt) {
1575                 INIT_LIST_HEAD(&fmt->list);
1576                 INIT_LIST_HEAD(&fmt->sort_list);
1577                 fmt->free = hpp_free;
1578                 fmt->level = level;
1579         }
1580
1581         return fmt;
1582 }
1583
1584 int hist_entry__filter(struct hist_entry *he, int type, const void *arg)
1585 {
1586         struct perf_hpp_fmt *fmt;
1587         struct hpp_sort_entry *hse;
1588         int ret = -1;
1589         int r;
1590
1591         perf_hpp_list__for_each_format(he->hpp_list, fmt) {
1592                 if (!perf_hpp__is_sort_entry(fmt))
1593                         continue;
1594
1595                 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1596                 if (hse->se->se_filter == NULL)
1597                         continue;
1598
1599                 /*
1600                  * hist entry is filtered if any of sort key in the hpp list
1601                  * is applied.  But it should skip non-matched filter types.
1602                  */
1603                 r = hse->se->se_filter(he, type, arg);
1604                 if (r >= 0) {
1605                         if (ret < 0)
1606                                 ret = 0;
1607                         ret |= r;
1608                 }
1609         }
1610
1611         return ret;
1612 }
1613
1614 static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd,
1615                                           struct perf_hpp_list *list,
1616                                           int level)
1617 {
1618         struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, level);
1619
1620         if (hse == NULL)
1621                 return -1;
1622
1623         perf_hpp_list__register_sort_field(list, &hse->hpp);
1624         return 0;
1625 }
1626
1627 static int __sort_dimension__add_hpp_output(struct sort_dimension *sd,
1628                                             struct perf_hpp_list *list)
1629 {
1630         struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, 0);
1631
1632         if (hse == NULL)
1633                 return -1;
1634
1635         perf_hpp_list__column_register(list, &hse->hpp);
1636         return 0;
1637 }
1638
1639 struct hpp_dynamic_entry {
1640         struct perf_hpp_fmt hpp;
1641         struct perf_evsel *evsel;
1642         struct format_field *field;
1643         unsigned dynamic_len;
1644         bool raw_trace;
1645 };
1646
1647 static int hde_width(struct hpp_dynamic_entry *hde)
1648 {
1649         if (!hde->hpp.len) {
1650                 int len = hde->dynamic_len;
1651                 int namelen = strlen(hde->field->name);
1652                 int fieldlen = hde->field->size;
1653
1654                 if (namelen > len)
1655                         len = namelen;
1656
1657                 if (!(hde->field->flags & FIELD_IS_STRING)) {
1658                         /* length for print hex numbers */
1659                         fieldlen = hde->field->size * 2 + 2;
1660                 }
1661                 if (fieldlen > len)
1662                         len = fieldlen;
1663
1664                 hde->hpp.len = len;
1665         }
1666         return hde->hpp.len;
1667 }
1668
1669 static void update_dynamic_len(struct hpp_dynamic_entry *hde,
1670                                struct hist_entry *he)
1671 {
1672         char *str, *pos;
1673         struct format_field *field = hde->field;
1674         size_t namelen;
1675         bool last = false;
1676
1677         if (hde->raw_trace)
1678                 return;
1679
1680         /* parse pretty print result and update max length */
1681         if (!he->trace_output)
1682                 he->trace_output = get_trace_output(he);
1683
1684         namelen = strlen(field->name);
1685         str = he->trace_output;
1686
1687         while (str) {
1688                 pos = strchr(str, ' ');
1689                 if (pos == NULL) {
1690                         last = true;
1691                         pos = str + strlen(str);
1692                 }
1693
1694                 if (!strncmp(str, field->name, namelen)) {
1695                         size_t len;
1696
1697                         str += namelen + 1;
1698                         len = pos - str;
1699
1700                         if (len > hde->dynamic_len)
1701                                 hde->dynamic_len = len;
1702                         break;
1703                 }
1704
1705                 if (last)
1706                         str = NULL;
1707                 else
1708                         str = pos + 1;
1709         }
1710 }
1711
1712 static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1713                               struct perf_evsel *evsel __maybe_unused)
1714 {
1715         struct hpp_dynamic_entry *hde;
1716         size_t len = fmt->user_len;
1717
1718         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1719
1720         if (!len)
1721                 len = hde_width(hde);
1722
1723         return scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, hde->field->name);
1724 }
1725
1726 static int __sort__hde_width(struct perf_hpp_fmt *fmt,
1727                              struct perf_hpp *hpp __maybe_unused,
1728                              struct perf_evsel *evsel __maybe_unused)
1729 {
1730         struct hpp_dynamic_entry *hde;
1731         size_t len = fmt->user_len;
1732
1733         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1734
1735         if (!len)
1736                 len = hde_width(hde);
1737
1738         return len;
1739 }
1740
1741 bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists)
1742 {
1743         struct hpp_dynamic_entry *hde;
1744
1745         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1746
1747         return hists_to_evsel(hists) == hde->evsel;
1748 }
1749
1750 static int __sort__hde_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1751                              struct hist_entry *he)
1752 {
1753         struct hpp_dynamic_entry *hde;
1754         size_t len = fmt->user_len;
1755         char *str, *pos;
1756         struct format_field *field;
1757         size_t namelen;
1758         bool last = false;
1759         int ret;
1760
1761         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1762
1763         if (!len)
1764                 len = hde_width(hde);
1765
1766         if (hde->raw_trace)
1767                 goto raw_field;
1768
1769         if (!he->trace_output)
1770                 he->trace_output = get_trace_output(he);
1771
1772         field = hde->field;
1773         namelen = strlen(field->name);
1774         str = he->trace_output;
1775
1776         while (str) {
1777                 pos = strchr(str, ' ');
1778                 if (pos == NULL) {
1779                         last = true;
1780                         pos = str + strlen(str);
1781                 }
1782
1783                 if (!strncmp(str, field->name, namelen)) {
1784                         str += namelen + 1;
1785                         str = strndup(str, pos - str);
1786
1787                         if (str == NULL)
1788                                 return scnprintf(hpp->buf, hpp->size,
1789                                                  "%*.*s", len, len, "ERROR");
1790                         break;
1791                 }
1792
1793                 if (last)
1794                         str = NULL;
1795                 else
1796                         str = pos + 1;
1797         }
1798
1799         if (str == NULL) {
1800                 struct trace_seq seq;
1801 raw_field:
1802                 trace_seq_init(&seq);
1803                 pevent_print_field(&seq, he->raw_data, hde->field);
1804                 str = seq.buffer;
1805         }
1806
1807         ret = scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, str);
1808         free(str);
1809         return ret;
1810 }
1811
1812 static int64_t __sort__hde_cmp(struct perf_hpp_fmt *fmt,
1813                                struct hist_entry *a, struct hist_entry *b)
1814 {
1815         struct hpp_dynamic_entry *hde;
1816         struct format_field *field;
1817         unsigned offset, size;
1818
1819         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1820
1821         if (b == NULL) {
1822                 update_dynamic_len(hde, a);
1823                 return 0;
1824         }
1825
1826         field = hde->field;
1827         if (field->flags & FIELD_IS_DYNAMIC) {
1828                 unsigned long long dyn;
1829
1830                 pevent_read_number_field(field, a->raw_data, &dyn);
1831                 offset = dyn & 0xffff;
1832                 size = (dyn >> 16) & 0xffff;
1833
1834                 /* record max width for output */
1835                 if (size > hde->dynamic_len)
1836                         hde->dynamic_len = size;
1837         } else {
1838                 offset = field->offset;
1839                 size = field->size;
1840         }
1841
1842         return memcmp(a->raw_data + offset, b->raw_data + offset, size);
1843 }
1844
1845 bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *fmt)
1846 {
1847         return fmt->cmp == __sort__hde_cmp;
1848 }
1849
1850 static bool __sort__hde_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
1851 {
1852         struct hpp_dynamic_entry *hde_a;
1853         struct hpp_dynamic_entry *hde_b;
1854
1855         if (!perf_hpp__is_dynamic_entry(a) || !perf_hpp__is_dynamic_entry(b))
1856                 return false;
1857
1858         hde_a = container_of(a, struct hpp_dynamic_entry, hpp);
1859         hde_b = container_of(b, struct hpp_dynamic_entry, hpp);
1860
1861         return hde_a->field == hde_b->field;
1862 }
1863
1864 static void hde_free(struct perf_hpp_fmt *fmt)
1865 {
1866         struct hpp_dynamic_entry *hde;
1867
1868         hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1869         free(hde);
1870 }
1871
1872 static struct hpp_dynamic_entry *
1873 __alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field,
1874                       int level)
1875 {
1876         struct hpp_dynamic_entry *hde;
1877
1878         hde = malloc(sizeof(*hde));
1879         if (hde == NULL) {
1880                 pr_debug("Memory allocation failed\n");
1881                 return NULL;
1882         }
1883
1884         hde->evsel = evsel;
1885         hde->field = field;
1886         hde->dynamic_len = 0;
1887
1888         hde->hpp.name = field->name;
1889         hde->hpp.header = __sort__hde_header;
1890         hde->hpp.width  = __sort__hde_width;
1891         hde->hpp.entry  = __sort__hde_entry;
1892         hde->hpp.color  = NULL;
1893
1894         hde->hpp.cmp = __sort__hde_cmp;
1895         hde->hpp.collapse = __sort__hde_cmp;
1896         hde->hpp.sort = __sort__hde_cmp;
1897         hde->hpp.equal = __sort__hde_equal;
1898         hde->hpp.free = hde_free;
1899
1900         INIT_LIST_HEAD(&hde->hpp.list);
1901         INIT_LIST_HEAD(&hde->hpp.sort_list);
1902         hde->hpp.elide = false;
1903         hde->hpp.len = 0;
1904         hde->hpp.user_len = 0;
1905         hde->hpp.level = level;
1906
1907         return hde;
1908 }
1909
1910 struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt)
1911 {
1912         struct perf_hpp_fmt *new_fmt = NULL;
1913
1914         if (perf_hpp__is_sort_entry(fmt)) {
1915                 struct hpp_sort_entry *hse, *new_hse;
1916
1917                 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1918                 new_hse = memdup(hse, sizeof(*hse));
1919                 if (new_hse)
1920                         new_fmt = &new_hse->hpp;
1921         } else if (perf_hpp__is_dynamic_entry(fmt)) {
1922                 struct hpp_dynamic_entry *hde, *new_hde;
1923
1924                 hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
1925                 new_hde = memdup(hde, sizeof(*hde));
1926                 if (new_hde)
1927                         new_fmt = &new_hde->hpp;
1928         } else {
1929                 new_fmt = memdup(fmt, sizeof(*fmt));
1930         }
1931
1932         INIT_LIST_HEAD(&new_fmt->list);
1933         INIT_LIST_HEAD(&new_fmt->sort_list);
1934
1935         return new_fmt;
1936 }
1937
1938 static int parse_field_name(char *str, char **event, char **field, char **opt)
1939 {
1940         char *event_name, *field_name, *opt_name;
1941
1942         event_name = str;
1943         field_name = strchr(str, '.');
1944
1945         if (field_name) {
1946                 *field_name++ = '\0';
1947         } else {
1948                 event_name = NULL;
1949                 field_name = str;
1950         }
1951
1952         opt_name = strchr(field_name, '/');
1953         if (opt_name)
1954                 *opt_name++ = '\0';
1955
1956         *event = event_name;
1957         *field = field_name;
1958         *opt   = opt_name;
1959
1960         return 0;
1961 }
1962
1963 /* find match evsel using a given event name.  The event name can be:
1964  *   1. '%' + event index (e.g. '%1' for first event)
1965  *   2. full event name (e.g. sched:sched_switch)
1966  *   3. partial event name (should not contain ':')
1967  */
1968 static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_name)
1969 {
1970         struct perf_evsel *evsel = NULL;
1971         struct perf_evsel *pos;
1972         bool full_name;
1973
1974         /* case 1 */
1975         if (event_name[0] == '%') {
1976                 int nr = strtol(event_name+1, NULL, 0);
1977
1978                 if (nr > evlist->nr_entries)
1979                         return NULL;
1980
1981                 evsel = perf_evlist__first(evlist);
1982                 while (--nr > 0)
1983                         evsel = perf_evsel__next(evsel);
1984
1985                 return evsel;
1986         }
1987
1988         full_name = !!strchr(event_name, ':');
1989         evlist__for_each(evlist, pos) {
1990                 /* case 2 */
1991                 if (full_name && !strcmp(pos->name, event_name))
1992                         return pos;
1993                 /* case 3 */
1994                 if (!full_name && strstr(pos->name, event_name)) {
1995                         if (evsel) {
1996                                 pr_debug("'%s' event is ambiguous: it can be %s or %s\n",
1997                                          event_name, evsel->name, pos->name);
1998                                 return NULL;
1999                         }
2000                         evsel = pos;
2001                 }
2002         }
2003
2004         return evsel;
2005 }
2006
2007 static int __dynamic_dimension__add(struct perf_evsel *evsel,
2008                                     struct format_field *field,
2009                                     bool raw_trace, int level)
2010 {
2011         struct hpp_dynamic_entry *hde;
2012
2013         hde = __alloc_dynamic_entry(evsel, field, level);
2014         if (hde == NULL)
2015                 return -ENOMEM;
2016
2017         hde->raw_trace = raw_trace;
2018
2019         perf_hpp__register_sort_field(&hde->hpp);
2020         return 0;
2021 }
2022
2023 static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace, int level)
2024 {
2025         int ret;
2026         struct format_field *field;
2027
2028         field = evsel->tp_format->format.fields;
2029         while (field) {
2030                 ret = __dynamic_dimension__add(evsel, field, raw_trace, level);
2031                 if (ret < 0)
2032                         return ret;
2033
2034                 field = field->next;
2035         }
2036         return 0;
2037 }
2038
2039 static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace,
2040                                   int level)
2041 {
2042         int ret;
2043         struct perf_evsel *evsel;
2044
2045         evlist__for_each(evlist, evsel) {
2046                 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2047                         continue;
2048
2049                 ret = add_evsel_fields(evsel, raw_trace, level);
2050                 if (ret < 0)
2051                         return ret;
2052         }
2053         return 0;
2054 }
2055
2056 static int add_all_matching_fields(struct perf_evlist *evlist,
2057                                    char *field_name, bool raw_trace, int level)
2058 {
2059         int ret = -ESRCH;
2060         struct perf_evsel *evsel;
2061         struct format_field *field;
2062
2063         evlist__for_each(evlist, evsel) {
2064                 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2065                         continue;
2066
2067                 field = pevent_find_any_field(evsel->tp_format, field_name);
2068                 if (field == NULL)
2069                         continue;
2070
2071                 ret = __dynamic_dimension__add(evsel, field, raw_trace, level);
2072                 if (ret < 0)
2073                         break;
2074         }
2075         return ret;
2076 }
2077
2078 static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok,
2079                              int level)
2080 {
2081         char *str, *event_name, *field_name, *opt_name;
2082         struct perf_evsel *evsel;
2083         struct format_field *field;
2084         bool raw_trace = symbol_conf.raw_trace;
2085         int ret = 0;
2086
2087         if (evlist == NULL)
2088                 return -ENOENT;
2089
2090         str = strdup(tok);
2091         if (str == NULL)
2092                 return -ENOMEM;
2093
2094         if (parse_field_name(str, &event_name, &field_name, &opt_name) < 0) {
2095                 ret = -EINVAL;
2096                 goto out;
2097         }
2098
2099         if (opt_name) {
2100                 if (strcmp(opt_name, "raw")) {
2101                         pr_debug("unsupported field option %s\n", opt_name);
2102                         ret = -EINVAL;
2103                         goto out;
2104                 }
2105                 raw_trace = true;
2106         }
2107
2108         if (!strcmp(field_name, "trace_fields")) {
2109                 ret = add_all_dynamic_fields(evlist, raw_trace, level);
2110                 goto out;
2111         }
2112
2113         if (event_name == NULL) {
2114                 ret = add_all_matching_fields(evlist, field_name, raw_trace, level);
2115                 goto out;
2116         }
2117
2118         evsel = find_evsel(evlist, event_name);
2119         if (evsel == NULL) {
2120                 pr_debug("Cannot find event: %s\n", event_name);
2121                 ret = -ENOENT;
2122                 goto out;
2123         }
2124
2125         if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2126                 pr_debug("%s is not a tracepoint event\n", event_name);
2127                 ret = -EINVAL;
2128                 goto out;
2129         }
2130
2131         if (!strcmp(field_name, "*")) {
2132                 ret = add_evsel_fields(evsel, raw_trace, level);
2133         } else {
2134                 field = pevent_find_any_field(evsel->tp_format, field_name);
2135                 if (field == NULL) {
2136                         pr_debug("Cannot find event field for %s.%s\n",
2137                                  event_name, field_name);
2138                         return -ENOENT;
2139                 }
2140
2141                 ret = __dynamic_dimension__add(evsel, field, raw_trace, level);
2142         }
2143
2144 out:
2145         free(str);
2146         return ret;
2147 }
2148
2149 static int __sort_dimension__add(struct sort_dimension *sd,
2150                                  struct perf_hpp_list *list,
2151                                  int level)
2152 {
2153         if (sd->taken)
2154                 return 0;
2155
2156         if (__sort_dimension__add_hpp_sort(sd, list, level) < 0)
2157                 return -1;
2158
2159         if (sd->entry->se_collapse)
2160                 list->need_collapse = 1;
2161
2162         sd->taken = 1;
2163
2164         return 0;
2165 }
2166
2167 static int __hpp_dimension__add(struct hpp_dimension *hd,
2168                                 struct perf_hpp_list *list,
2169                                 int level)
2170 {
2171         struct perf_hpp_fmt *fmt;
2172
2173         if (hd->taken)
2174                 return 0;
2175
2176         fmt = __hpp_dimension__alloc_hpp(hd, level);
2177         if (!fmt)
2178                 return -1;
2179
2180         hd->taken = 1;
2181         perf_hpp_list__register_sort_field(list, fmt);
2182         return 0;
2183 }
2184
2185 static int __sort_dimension__add_output(struct perf_hpp_list *list,
2186                                         struct sort_dimension *sd)
2187 {
2188         if (sd->taken)
2189                 return 0;
2190
2191         if (__sort_dimension__add_hpp_output(sd, list) < 0)
2192                 return -1;
2193
2194         sd->taken = 1;
2195         return 0;
2196 }
2197
2198 static int __hpp_dimension__add_output(struct perf_hpp_list *list,
2199                                        struct hpp_dimension *hd)
2200 {
2201         struct perf_hpp_fmt *fmt;
2202
2203         if (hd->taken)
2204                 return 0;
2205
2206         fmt = __hpp_dimension__alloc_hpp(hd, 0);
2207         if (!fmt)
2208                 return -1;
2209
2210         hd->taken = 1;
2211         perf_hpp_list__column_register(list, fmt);
2212         return 0;
2213 }
2214
2215 int hpp_dimension__add_output(unsigned col)
2216 {
2217         BUG_ON(col >= PERF_HPP__MAX_INDEX);
2218         return __hpp_dimension__add_output(&perf_hpp_list, &hpp_sort_dimensions[col]);
2219 }
2220
2221 static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2222                                struct perf_evlist *evlist,
2223                                int level)
2224 {
2225         unsigned int i;
2226
2227         for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) {
2228                 struct sort_dimension *sd = &common_sort_dimensions[i];
2229
2230                 if (strncasecmp(tok, sd->name, strlen(tok)))
2231                         continue;
2232
2233                 if (sd->entry == &sort_parent) {
2234                         int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
2235                         if (ret) {
2236                                 char err[BUFSIZ];
2237
2238                                 regerror(ret, &parent_regex, err, sizeof(err));
2239                                 pr_err("Invalid regex: %s\n%s", parent_pattern, err);
2240                                 return -EINVAL;
2241                         }
2242                         list->parent = 1;
2243                 } else if (sd->entry == &sort_sym) {
2244                         list->sym = 1;
2245                         /*
2246                          * perf diff displays the performance difference amongst
2247                          * two or more perf.data files. Those files could come
2248                          * from different binaries. So we should not compare
2249                          * their ips, but the name of symbol.
2250                          */
2251                         if (sort__mode == SORT_MODE__DIFF)
2252                                 sd->entry->se_collapse = sort__sym_sort;
2253
2254                 } else if (sd->entry == &sort_dso) {
2255                         list->dso = 1;
2256                 } else if (sd->entry == &sort_socket) {
2257                         list->socket = 1;
2258                 } else if (sd->entry == &sort_thread) {
2259                         list->thread = 1;
2260                 } else if (sd->entry == &sort_comm) {
2261                         sort__has_comm = 1;
2262                 }
2263
2264                 return __sort_dimension__add(sd, list, level);
2265         }
2266
2267         for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) {
2268                 struct hpp_dimension *hd = &hpp_sort_dimensions[i];
2269
2270                 if (strncasecmp(tok, hd->name, strlen(tok)))
2271                         continue;
2272
2273                 return __hpp_dimension__add(hd, list, level);
2274         }
2275
2276         for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) {
2277                 struct sort_dimension *sd = &bstack_sort_dimensions[i];
2278
2279                 if (strncasecmp(tok, sd->name, strlen(tok)))
2280                         continue;
2281
2282                 if (sort__mode != SORT_MODE__BRANCH)
2283                         return -EINVAL;
2284
2285                 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
2286                         list->sym = 1;
2287
2288                 __sort_dimension__add(sd, list, level);
2289                 return 0;
2290         }
2291
2292         for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
2293                 struct sort_dimension *sd = &memory_sort_dimensions[i];
2294
2295                 if (strncasecmp(tok, sd->name, strlen(tok)))
2296                         continue;
2297
2298                 if (sort__mode != SORT_MODE__MEMORY)
2299                         return -EINVAL;
2300
2301                 if (sd->entry == &sort_mem_daddr_sym)
2302                         list->sym = 1;
2303
2304                 __sort_dimension__add(sd, list, level);
2305                 return 0;
2306         }
2307
2308         if (!add_dynamic_entry(evlist, tok, level))
2309                 return 0;
2310
2311         return -ESRCH;
2312 }
2313
2314 static int setup_sort_list(struct perf_hpp_list *list, char *str,
2315                            struct perf_evlist *evlist)
2316 {
2317         char *tmp, *tok;
2318         int ret = 0;
2319         int level = 0;
2320         int next_level = 1;
2321         bool in_group = false;
2322
2323         do {
2324                 tok = str;
2325                 tmp = strpbrk(str, "{}, ");
2326                 if (tmp) {
2327                         if (in_group)
2328                                 next_level = level;
2329                         else
2330                                 next_level = level + 1;
2331
2332                         if (*tmp == '{')
2333                                 in_group = true;
2334                         else if (*tmp == '}')
2335                                 in_group = false;
2336
2337                         *tmp = '\0';
2338                         str = tmp + 1;
2339                 }
2340
2341                 if (*tok) {
2342                         ret = sort_dimension__add(list, tok, evlist, level);
2343                         if (ret == -EINVAL) {
2344                                 error("Invalid --sort key: `%s'", tok);
2345                                 break;
2346                         } else if (ret == -ESRCH) {
2347                                 error("Unknown --sort key: `%s'", tok);
2348                                 break;
2349                         }
2350                 }
2351
2352                 level = next_level;
2353         } while (tmp);
2354
2355         return ret;
2356 }
2357
2358 static const char *get_default_sort_order(struct perf_evlist *evlist)
2359 {
2360         const char *default_sort_orders[] = {
2361                 default_sort_order,
2362                 default_branch_sort_order,
2363                 default_mem_sort_order,
2364                 default_top_sort_order,
2365                 default_diff_sort_order,
2366                 default_tracepoint_sort_order,
2367         };
2368         bool use_trace = true;
2369         struct perf_evsel *evsel;
2370
2371         BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders));
2372
2373         if (evlist == NULL)
2374                 goto out_no_evlist;
2375
2376         evlist__for_each(evlist, evsel) {
2377                 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2378                         use_trace = false;
2379                         break;
2380                 }
2381         }
2382
2383         if (use_trace) {
2384                 sort__mode = SORT_MODE__TRACEPOINT;
2385                 if (symbol_conf.raw_trace)
2386                         return "trace_fields";
2387         }
2388 out_no_evlist:
2389         return default_sort_orders[sort__mode];
2390 }
2391
2392 static int setup_sort_order(struct perf_evlist *evlist)
2393 {
2394         char *new_sort_order;
2395
2396         /*
2397          * Append '+'-prefixed sort order to the default sort
2398          * order string.
2399          */
2400         if (!sort_order || is_strict_order(sort_order))
2401                 return 0;
2402
2403         if (sort_order[1] == '\0') {
2404                 error("Invalid --sort key: `+'");
2405                 return -EINVAL;
2406         }
2407
2408         /*
2409          * We allocate new sort_order string, but we never free it,
2410          * because it's checked over the rest of the code.
2411          */
2412         if (asprintf(&new_sort_order, "%s,%s",
2413                      get_default_sort_order(evlist), sort_order + 1) < 0) {
2414                 error("Not enough memory to set up --sort");
2415                 return -ENOMEM;
2416         }
2417
2418         sort_order = new_sort_order;
2419         return 0;
2420 }
2421
2422 /*
2423  * Adds 'pre,' prefix into 'str' is 'pre' is
2424  * not already part of 'str'.
2425  */
2426 static char *prefix_if_not_in(const char *pre, char *str)
2427 {
2428         char *n;
2429
2430         if (!str || strstr(str, pre))
2431                 return str;
2432
2433         if (asprintf(&n, "%s,%s", pre, str) < 0)
2434                 return NULL;
2435
2436         free(str);
2437         return n;
2438 }
2439
2440 static char *setup_overhead(char *keys)
2441 {
2442         keys = prefix_if_not_in("overhead", keys);
2443
2444         if (symbol_conf.cumulate_callchain)
2445                 keys = prefix_if_not_in("overhead_children", keys);
2446
2447         return keys;
2448 }
2449
2450 static int __setup_sorting(struct perf_evlist *evlist)
2451 {
2452         char *str;
2453         const char *sort_keys;
2454         int ret = 0;
2455
2456         ret = setup_sort_order(evlist);
2457         if (ret)
2458                 return ret;
2459
2460         sort_keys = sort_order;
2461         if (sort_keys == NULL) {
2462                 if (is_strict_order(field_order)) {
2463                         /*
2464                          * If user specified field order but no sort order,
2465                          * we'll honor it and not add default sort orders.
2466                          */
2467                         return 0;
2468                 }
2469
2470                 sort_keys = get_default_sort_order(evlist);
2471         }
2472
2473         str = strdup(sort_keys);
2474         if (str == NULL) {
2475                 error("Not enough memory to setup sort keys");
2476                 return -ENOMEM;
2477         }
2478
2479         /*
2480          * Prepend overhead fields for backward compatibility.
2481          */
2482         if (!is_strict_order(field_order)) {
2483                 str = setup_overhead(str);
2484                 if (str == NULL) {
2485                         error("Not enough memory to setup overhead keys");
2486                         return -ENOMEM;
2487                 }
2488         }
2489
2490         ret = setup_sort_list(&perf_hpp_list, str, evlist);
2491
2492         free(str);
2493         return ret;
2494 }
2495
2496 void perf_hpp__set_elide(int idx, bool elide)
2497 {
2498         struct perf_hpp_fmt *fmt;
2499         struct hpp_sort_entry *hse;
2500
2501         perf_hpp_list__for_each_format(&perf_hpp_list, fmt) {
2502                 if (!perf_hpp__is_sort_entry(fmt))
2503                         continue;
2504
2505                 hse = container_of(fmt, struct hpp_sort_entry, hpp);
2506                 if (hse->se->se_width_idx == idx) {
2507                         fmt->elide = elide;
2508                         break;
2509                 }
2510         }
2511 }
2512
2513 static bool __get_elide(struct strlist *list, const char *list_name, FILE *fp)
2514 {
2515         if (list && strlist__nr_entries(list) == 1) {
2516                 if (fp != NULL)
2517                         fprintf(fp, "# %s: %s\n", list_name,
2518                                 strlist__entry(list, 0)->s);
2519                 return true;
2520         }
2521         return false;
2522 }
2523
2524 static bool get_elide(int idx, FILE *output)
2525 {
2526         switch (idx) {
2527         case HISTC_SYMBOL:
2528                 return __get_elide(symbol_conf.sym_list, "symbol", output);
2529         case HISTC_DSO:
2530                 return __get_elide(symbol_conf.dso_list, "dso", output);
2531         case HISTC_COMM:
2532                 return __get_elide(symbol_conf.comm_list, "comm", output);
2533         default:
2534                 break;
2535         }
2536
2537         if (sort__mode != SORT_MODE__BRANCH)
2538                 return false;
2539
2540         switch (idx) {
2541         case HISTC_SYMBOL_FROM:
2542                 return __get_elide(symbol_conf.sym_from_list, "sym_from", output);
2543         case HISTC_SYMBOL_TO:
2544                 return __get_elide(symbol_conf.sym_to_list, "sym_to", output);
2545         case HISTC_DSO_FROM:
2546                 return __get_elide(symbol_conf.dso_from_list, "dso_from", output);
2547         case HISTC_DSO_TO:
2548                 return __get_elide(symbol_conf.dso_to_list, "dso_to", output);
2549         default:
2550                 break;
2551         }
2552
2553         return false;
2554 }
2555
2556 void sort__setup_elide(FILE *output)
2557 {
2558         struct perf_hpp_fmt *fmt;
2559         struct hpp_sort_entry *hse;
2560
2561         perf_hpp_list__for_each_format(&perf_hpp_list, fmt) {
2562                 if (!perf_hpp__is_sort_entry(fmt))
2563                         continue;
2564
2565                 hse = container_of(fmt, struct hpp_sort_entry, hpp);
2566                 fmt->elide = get_elide(hse->se->se_width_idx, output);
2567         }
2568
2569         /*
2570          * It makes no sense to elide all of sort entries.
2571          * Just revert them to show up again.
2572          */
2573         perf_hpp_list__for_each_format(&perf_hpp_list, fmt) {
2574                 if (!perf_hpp__is_sort_entry(fmt))
2575                         continue;
2576
2577                 if (!fmt->elide)
2578                         return;
2579         }
2580
2581         perf_hpp_list__for_each_format(&perf_hpp_list, fmt) {
2582                 if (!perf_hpp__is_sort_entry(fmt))
2583                         continue;
2584
2585                 fmt->elide = false;
2586         }
2587 }
2588
2589 static int output_field_add(struct perf_hpp_list *list, char *tok)
2590 {
2591         unsigned int i;
2592
2593         for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) {
2594                 struct sort_dimension *sd = &common_sort_dimensions[i];
2595
2596                 if (strncasecmp(tok, sd->name, strlen(tok)))
2597                         continue;
2598
2599                 return __sort_dimension__add_output(list, sd);
2600         }
2601
2602         for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) {
2603                 struct hpp_dimension *hd = &hpp_sort_dimensions[i];
2604
2605                 if (strncasecmp(tok, hd->name, strlen(tok)))
2606                         continue;
2607
2608                 return __hpp_dimension__add_output(list, hd);
2609         }
2610
2611         for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) {
2612                 struct sort_dimension *sd = &bstack_sort_dimensions[i];
2613
2614                 if (strncasecmp(tok, sd->name, strlen(tok)))
2615                         continue;
2616
2617                 return __sort_dimension__add_output(list, sd);
2618         }
2619
2620         for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
2621                 struct sort_dimension *sd = &memory_sort_dimensions[i];
2622
2623                 if (strncasecmp(tok, sd->name, strlen(tok)))
2624                         continue;
2625
2626                 return __sort_dimension__add_output(list, sd);
2627         }
2628
2629         return -ESRCH;
2630 }
2631
2632 static int setup_output_list(struct perf_hpp_list *list, char *str)
2633 {
2634         char *tmp, *tok;
2635         int ret = 0;
2636
2637         for (tok = strtok_r(str, ", ", &tmp);
2638                         tok; tok = strtok_r(NULL, ", ", &tmp)) {
2639                 ret = output_field_add(list, tok);
2640                 if (ret == -EINVAL) {
2641                         error("Invalid --fields key: `%s'", tok);
2642                         break;
2643                 } else if (ret == -ESRCH) {
2644                         error("Unknown --fields key: `%s'", tok);
2645                         break;
2646                 }
2647         }
2648
2649         return ret;
2650 }
2651
2652 static void reset_dimensions(void)
2653 {
2654         unsigned int i;
2655
2656         for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++)
2657                 common_sort_dimensions[i].taken = 0;
2658
2659         for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++)
2660                 hpp_sort_dimensions[i].taken = 0;
2661
2662         for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++)
2663                 bstack_sort_dimensions[i].taken = 0;
2664
2665         for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++)
2666                 memory_sort_dimensions[i].taken = 0;
2667 }
2668
2669 bool is_strict_order(const char *order)
2670 {
2671         return order && (*order != '+');
2672 }
2673
2674 static int __setup_output_field(void)
2675 {
2676         char *str, *strp;
2677         int ret = -EINVAL;
2678
2679         if (field_order == NULL)
2680                 return 0;
2681
2682         strp = str = strdup(field_order);
2683         if (str == NULL) {
2684                 error("Not enough memory to setup output fields");
2685                 return -ENOMEM;
2686         }
2687
2688         if (!is_strict_order(field_order))
2689                 strp++;
2690
2691         if (!strlen(strp)) {
2692                 error("Invalid --fields key: `+'");
2693                 goto out;
2694         }
2695
2696         ret = setup_output_list(&perf_hpp_list, strp);
2697
2698 out:
2699         free(str);
2700         return ret;
2701 }
2702
2703 int setup_sorting(struct perf_evlist *evlist)
2704 {
2705         int err;
2706
2707         err = __setup_sorting(evlist);
2708         if (err < 0)
2709                 return err;
2710
2711         if (parent_pattern != default_parent_pattern) {
2712                 err = sort_dimension__add(&perf_hpp_list, "parent", evlist, -1);
2713                 if (err < 0)
2714                         return err;
2715         }
2716
2717         reset_dimensions();
2718
2719         /*
2720          * perf diff doesn't use default hpp output fields.
2721          */
2722         if (sort__mode != SORT_MODE__DIFF)
2723                 perf_hpp__init();
2724
2725         err = __setup_output_field();
2726         if (err < 0)
2727                 return err;
2728
2729         /* copy sort keys to output fields */
2730         perf_hpp__setup_output_field(&perf_hpp_list);
2731         /* and then copy output fields to sort keys */
2732         perf_hpp__append_sort_keys(&perf_hpp_list);
2733
2734         /* setup hists-specific output fields */
2735         if (perf_hpp__setup_hists_formats(&perf_hpp_list, evlist) < 0)
2736                 return -1;
2737
2738         return 0;
2739 }
2740
2741 void reset_output_field(void)
2742 {
2743         perf_hpp_list.need_collapse = 0;
2744         perf_hpp_list.parent = 0;
2745         perf_hpp_list.sym = 0;
2746         perf_hpp_list.dso = 0;
2747
2748         field_order = NULL;
2749         sort_order = NULL;
2750
2751         reset_dimensions();
2752         perf_hpp__reset_output_field(&perf_hpp_list);
2753 }