aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c93
1 files changed, 31 insertions, 62 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 722c0f54e549..1dba568e1941 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -10,9 +10,9 @@
10#include "util/util.h" 10#include "util/util.h"
11 11
12#include "util/color.h" 12#include "util/color.h"
13#include "util/list.h" 13#include <linux/list.h>
14#include "util/cache.h" 14#include "util/cache.h"
15#include "util/rbtree.h" 15#include <linux/rbtree.h>
16#include "util/symbol.h" 16#include "util/symbol.h"
17#include "util/string.h" 17#include "util/string.h"
18 18
@@ -25,10 +25,6 @@
25#define SHOW_USER 2 25#define SHOW_USER 2
26#define SHOW_HV 4 26#define SHOW_HV 4
27 27
28#define MIN_GREEN 0.5
29#define MIN_RED 5.0
30
31
32static char const *input_name = "perf.data"; 28static char const *input_name = "perf.data";
33static char *vmlinux = "vmlinux"; 29static char *vmlinux = "vmlinux";
34 30
@@ -43,6 +39,10 @@ static int dump_trace = 0;
43 39
44static int verbose; 40static int verbose;
45 41
42static int modules;
43
44static int full_paths;
45
46static int print_line; 46static int print_line;
47 47
48static unsigned long page_size; 48static unsigned long page_size;
@@ -74,20 +74,12 @@ struct fork_event {
74 u32 pid, ppid; 74 u32 pid, ppid;
75}; 75};
76 76
77struct period_event {
78 struct perf_event_header header;
79 u64 time;
80 u64 id;
81 u64 sample_period;
82};
83
84typedef union event_union { 77typedef union event_union {
85 struct perf_event_header header; 78 struct perf_event_header header;
86 struct ip_event ip; 79 struct ip_event ip;
87 struct mmap_event mmap; 80 struct mmap_event mmap;
88 struct comm_event comm; 81 struct comm_event comm;
89 struct fork_event fork; 82 struct fork_event fork;
90 struct period_event period;
91} event_t; 83} event_t;
92 84
93 85
@@ -160,7 +152,7 @@ static void dsos__fprintf(FILE *fp)
160 152
161static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) 153static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
162{ 154{
163 return dso__find_symbol(kernel_dso, ip); 155 return dso__find_symbol(dso, ip);
164} 156}
165 157
166static int load_kernel(void) 158static int load_kernel(void)
@@ -171,8 +163,8 @@ static int load_kernel(void)
171 if (!kernel_dso) 163 if (!kernel_dso)
172 return -1; 164 return -1;
173 165
174 err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); 166 err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
175 if (err) { 167 if (err <= 0) {
176 dso__delete(kernel_dso); 168 dso__delete(kernel_dso);
177 kernel_dso = NULL; 169 kernel_dso = NULL;
178 } else 170 } else
@@ -203,7 +195,7 @@ static u64 map__map_ip(struct map *map, u64 ip)
203 return ip - map->start + map->pgoff; 195 return ip - map->start + map->pgoff;
204} 196}
205 197
206static u64 vdso__map_ip(struct map *map, u64 ip) 198static u64 vdso__map_ip(struct map *map __used, u64 ip)
207{ 199{
208 return ip; 200 return ip;
209} 201}
@@ -600,7 +592,7 @@ static LIST_HEAD(hist_entry__sort_list);
600 592
601static int sort_dimension__add(char *tok) 593static int sort_dimension__add(char *tok)
602{ 594{
603 int i; 595 unsigned int i;
604 596
605 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { 597 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
606 struct sort_dimension *sd = &sort_dimensions[i]; 598 struct sort_dimension *sd = &sort_dimensions[i];
@@ -998,19 +990,6 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head)
998} 990}
999 991
1000static int 992static int
1001process_period_event(event_t *event, unsigned long offset, unsigned long head)
1002{
1003 dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
1004 (void *)(offset + head),
1005 (void *)(long)(event->header.size),
1006 event->period.time,
1007 event->period.id,
1008 event->period.sample_period);
1009
1010 return 0;
1011}
1012
1013static int
1014process_event(event_t *event, unsigned long offset, unsigned long head) 993process_event(event_t *event, unsigned long offset, unsigned long head)
1015{ 994{
1016 switch (event->header.type) { 995 switch (event->header.type) {
@@ -1025,9 +1004,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
1025 1004
1026 case PERF_EVENT_FORK: 1005 case PERF_EVENT_FORK:
1027 return process_fork_event(event, offset, head); 1006 return process_fork_event(event, offset, head);
1028
1029 case PERF_EVENT_PERIOD:
1030 return process_period_event(event, offset, head);
1031 /* 1007 /*
1032 * We dont process them right now but they are fine: 1008 * We dont process them right now but they are fine:
1033 */ 1009 */
@@ -1043,24 +1019,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
1043 return 0; 1019 return 0;
1044} 1020}
1045 1021
1046static char *get_color(double percent)
1047{
1048 char *color = PERF_COLOR_NORMAL;
1049
1050 /*
1051 * We color high-overhead entries in red, mid-overhead
1052 * entries in green - and keep the low overhead places
1053 * normal:
1054 */
1055 if (percent >= MIN_RED)
1056 color = PERF_COLOR_RED;
1057 else {
1058 if (percent > MIN_GREEN)
1059 color = PERF_COLOR_GREEN;
1060 }
1061 return color;
1062}
1063
1064static int 1022static int
1065parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) 1023parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
1066{ 1024{
@@ -1069,7 +1027,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
1069 static const char *prev_color; 1027 static const char *prev_color;
1070 unsigned int offset; 1028 unsigned int offset;
1071 size_t line_len; 1029 size_t line_len;
1072 u64 line_ip; 1030 s64 line_ip;
1073 int ret; 1031 int ret;
1074 char *c; 1032 char *c;
1075 1033
@@ -1122,7 +1080,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
1122 } else if (sym->hist_sum) 1080 } else if (sym->hist_sum)
1123 percent = 100.0 * hits / sym->hist_sum; 1081 percent = 100.0 * hits / sym->hist_sum;
1124 1082
1125 color = get_color(percent); 1083 color = get_percent_color(percent);
1126 1084
1127 /* 1085 /*
1128 * Also color the filename and line if needed, with 1086 * Also color the filename and line if needed, with
@@ -1258,7 +1216,7 @@ static void print_summary(char *filename)
1258 1216
1259 sym_ext = rb_entry(node, struct sym_ext, node); 1217 sym_ext = rb_entry(node, struct sym_ext, node);
1260 percent = sym_ext->percent; 1218 percent = sym_ext->percent;
1261 color = get_color(percent); 1219 color = get_percent_color(percent);
1262 path = sym_ext->path; 1220 path = sym_ext->path;
1263 1221
1264 color_fprintf(stdout, color, " %7.2f %s", percent, path); 1222 color_fprintf(stdout, color, " %7.2f %s", percent, path);
@@ -1268,19 +1226,25 @@ static void print_summary(char *filename)
1268 1226
1269static void annotate_sym(struct dso *dso, struct symbol *sym) 1227static void annotate_sym(struct dso *dso, struct symbol *sym)
1270{ 1228{
1271 char *filename = dso->name; 1229 char *filename = dso->name, *d_filename;
1272 u64 start, end, len; 1230 u64 start, end, len;
1273 char command[PATH_MAX*2]; 1231 char command[PATH_MAX*2];
1274 FILE *file; 1232 FILE *file;
1275 1233
1276 if (!filename) 1234 if (!filename)
1277 return; 1235 return;
1278 if (dso == kernel_dso) 1236 if (sym->module)
1237 filename = sym->module->path;
1238 else if (dso == kernel_dso)
1279 filename = vmlinux; 1239 filename = vmlinux;
1280 1240
1281 start = sym->obj_start; 1241 start = sym->obj_start;
1282 if (!start) 1242 if (!start)
1283 start = sym->start; 1243 start = sym->start;
1244 if (full_paths)
1245 d_filename = filename;
1246 else
1247 d_filename = basename(filename);
1284 1248
1285 end = start + sym->end - sym->start + 1; 1249 end = start + sym->end - sym->start + 1;
1286 len = sym->end - sym->start; 1250 len = sym->end - sym->start;
@@ -1291,13 +1255,14 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
1291 } 1255 }
1292 1256
1293 printf("\n\n------------------------------------------------\n"); 1257 printf("\n\n------------------------------------------------\n");
1294 printf(" Percent | Source code & Disassembly of %s\n", filename); 1258 printf(" Percent | Source code & Disassembly of %s\n", d_filename);
1295 printf("------------------------------------------------\n"); 1259 printf("------------------------------------------------\n");
1296 1260
1297 if (verbose >= 2) 1261 if (verbose >= 2)
1298 printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); 1262 printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
1299 1263
1300 sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (u64)start, (u64)end, filename); 1264 sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
1265 (u64)start, (u64)end, filename, filename);
1301 1266
1302 if (verbose >= 3) 1267 if (verbose >= 3)
1303 printf("doing: %s\n", command); 1268 printf("doing: %s\n", command);
@@ -1428,7 +1393,7 @@ more:
1428 1393
1429 head += size; 1394 head += size;
1430 1395
1431 if (offset + head < stat.st_size) 1396 if (offset + head < (unsigned long)stat.st_size)
1432 goto more; 1397 goto more;
1433 1398
1434 rc = EXIT_SUCCESS; 1399 rc = EXIT_SUCCESS;
@@ -1472,8 +1437,12 @@ static const struct option options[] = {
1472 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1437 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1473 "dump raw trace in ASCII"), 1438 "dump raw trace in ASCII"),
1474 OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), 1439 OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
1440 OPT_BOOLEAN('m', "modules", &modules,
1441 "load module symbols - WARNING: use only with -k and LIVE kernel"),
1475 OPT_BOOLEAN('l', "print-line", &print_line, 1442 OPT_BOOLEAN('l', "print-line", &print_line,
1476 "print matching source lines (may be slow)"), 1443 "print matching source lines (may be slow)"),
1444 OPT_BOOLEAN('P', "full-paths", &full_paths,
1445 "Don't shorten the displayed pathnames"),
1477 OPT_END() 1446 OPT_END()
1478}; 1447};
1479 1448
@@ -1492,7 +1461,7 @@ static void setup_sorting(void)
1492 free(str); 1461 free(str);
1493} 1462}
1494 1463
1495int cmd_annotate(int argc, const char **argv, const char *prefix) 1464int cmd_annotate(int argc, const char **argv, const char *prefix __used)
1496{ 1465{
1497 symbol__init(); 1466 symbol__init();
1498 1467