aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-12-11 05:57:46 -0500
committerIngo Molnar <mingo@kernel.org>2013-12-11 05:57:46 -0500
commit813932149e7847c91f544a03b943a84c5b264f76 (patch)
tree8e9a5f016e28797e7c07dfa1c16d15822a54a63c
parent789790791ad254408267eb6a216ae7a90973c05a (diff)
parent1448fef40af6079de38380c3a81bcf9994a1037d (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: * Add an option in 'perf script' to print the source line number, from Adrian Hunter * Add --header/--header-only options to 'script' and 'report', the default is not tho show the header info, but as this has been the default for some time, leave a single line explaining how to obtain that information, from Jiri Olsa. * Fix symoff printing in callchains in 'perf script', from Adrian Hunter. * Assorted mmap_pages handling fixes, from Adrian Hunter. * Fix summary percentage when processing files in 'perf trace', from David Ahern. * Handle old kernels where the "raw_syscalls" tracepoints were called plan "syscalls", in 'perf trace', from David Ahern. * Several man pages typo fixes from Dongsheng Yang. * Add '-v' option to 'perf kvm', from Dongsheng Yang. * Make perf kvm diff support --guestmount, from Dongsheng Yang. * Get rid of several die() calls in libtraceevent, from Namhyung Kim. * Use basename() in a more robust way, to avoid problems related to different system library implementations for that function, from Stephane Eranian. * Remove open coded management of short_name_allocated member, from Adrian Hunter * Several cleanups in the "dso" methods, constifying some parameters and renaming some fields to clarify its purpose. (Arnaldo Carvalho de Melo.) * Add per-feature check flags, fixing libunwind related build problems on some architectures, from Jean Pihet. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/lib/traceevent/event-parse.c28
-rw-r--r--tools/lib/traceevent/event-parse.h2
-rw-r--r--tools/lib/traceevent/parse-filter.c57
-rw-r--r--tools/perf/Documentation/perf-archive.txt6
-rw-r--r--tools/perf/Documentation/perf-kvm.txt7
-rw-r--r--tools/perf/Documentation/perf-report.txt9
-rw-r--r--tools/perf/Documentation/perf-script.txt8
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-diff.c3
-rw-r--r--tools/perf/builtin-kvm.c11
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c22
-rw-r--r--tools/perf/builtin-script.c23
-rw-r--r--tools/perf/builtin-trace.c32
-rw-r--r--tools/perf/config/Makefile52
-rw-r--r--tools/perf/config/feature-checks/Makefile8
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/build-id.c2
-rw-r--r--tools/perf/util/build-id.h2
-rw-r--r--tools/perf/util/dso.c112
-rw-r--r--tools/perf/util/dso.h16
-rw-r--r--tools/perf/util/evlist.c10
-rw-r--r--tools/perf/util/header.c6
-rw-r--r--tools/perf/util/machine.c6
-rw-r--r--tools/perf/util/map.c17
-rw-r--r--tools/perf/util/map.h2
-rw-r--r--tools/perf/util/probe-event.c2
-rw-r--r--tools/perf/util/session.c15
-rw-r--r--tools/perf/util/session.h1
-rw-r--r--tools/perf/util/srcline.c2
-rw-r--r--tools/perf/util/symbol.c38
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/util.c14
-rw-r--r--tools/perf/util/util.h14
-rw-r--r--tools/perf/util/vdso.c2
35 files changed, 375 insertions, 163 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 9849873265d4..22566c271275 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -2710,7 +2710,6 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
2710 struct print_arg *farg; 2710 struct print_arg *farg;
2711 enum event_type type; 2711 enum event_type type;
2712 char *token; 2712 char *token;
2713 const char *test;
2714 int i; 2713 int i;
2715 2714
2716 arg->type = PRINT_FUNC; 2715 arg->type = PRINT_FUNC;
@@ -2727,15 +2726,19 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
2727 } 2726 }
2728 2727
2729 type = process_arg(event, farg, &token); 2728 type = process_arg(event, farg, &token);
2730 if (i < (func->nr_args - 1)) 2729 if (i < (func->nr_args - 1)) {
2731 test = ","; 2730 if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
2732 else 2731 warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
2733 test = ")"; 2732 func->name, func->nr_args,
2734 2733 event->name, i + 1);
2735 if (test_type_token(type, token, EVENT_DELIM, test)) { 2734 goto err;
2736 free_arg(farg); 2735 }
2737 free_token(token); 2736 } else {
2738 return EVENT_ERROR; 2737 if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
2738 warning("Error: function '%s()' only expects %d arguments but event %s has more",
2739 func->name, func->nr_args, event->name);
2740 goto err;
2741 }
2739 } 2742 }
2740 2743
2741 *next_arg = farg; 2744 *next_arg = farg;
@@ -2747,6 +2750,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
2747 *tok = token; 2750 *tok = token;
2748 2751
2749 return type; 2752 return type;
2753
2754err:
2755 free_arg(farg);
2756 free_token(token);
2757 return EVENT_ERROR;
2750} 2758}
2751 2759
2752static enum event_type 2760static enum event_type
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 620c27a72960..6e23f197175f 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -860,7 +860,7 @@ int pevent_event_filtered(struct event_filter *filter,
860 860
861void pevent_filter_reset(struct event_filter *filter); 861void pevent_filter_reset(struct event_filter *filter);
862 862
863void pevent_filter_clear_trivial(struct event_filter *filter, 863int pevent_filter_clear_trivial(struct event_filter *filter,
864 enum filter_trivial_type type); 864 enum filter_trivial_type type);
865 865
866void pevent_filter_free(struct event_filter *filter); 866void pevent_filter_free(struct event_filter *filter);
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 2500e75583fc..ab402fb2dcf7 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -182,7 +182,10 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent)
182{ 182{
183 struct event_filter *filter; 183 struct event_filter *filter;
184 184
185 filter = malloc_or_die(sizeof(*filter)); 185 filter = malloc(sizeof(*filter));
186 if (filter == NULL)
187 return NULL;
188
186 memset(filter, 0, sizeof(*filter)); 189 memset(filter, 0, sizeof(*filter));
187 filter->pevent = pevent; 190 filter->pevent = pevent;
188 pevent_ref(pevent); 191 pevent_ref(pevent);
@@ -242,15 +245,19 @@ static void free_arg(struct filter_arg *arg)
242 free(arg); 245 free(arg);
243} 246}
244 247
245static void add_event(struct event_list **events, 248static int add_event(struct event_list **events,
246 struct event_format *event) 249 struct event_format *event)
247{ 250{
248 struct event_list *list; 251 struct event_list *list;
249 252
250 list = malloc_or_die(sizeof(*list)); 253 list = malloc(sizeof(*list));
254 if (list == NULL)
255 return -1;
256
251 list->next = *events; 257 list->next = *events;
252 *events = list; 258 *events = list;
253 list->event = event; 259 list->event = event;
260 return 0;
254} 261}
255 262
256static int event_match(struct event_format *event, 263static int event_match(struct event_format *event,
@@ -273,6 +280,7 @@ find_event(struct pevent *pevent, struct event_list **events,
273 regex_t ereg; 280 regex_t ereg;
274 regex_t sreg; 281 regex_t sreg;
275 int match = 0; 282 int match = 0;
283 int fail = 0;
276 char *reg; 284 char *reg;
277 int ret; 285 int ret;
278 int i; 286 int i;
@@ -307,7 +315,10 @@ find_event(struct pevent *pevent, struct event_list **events,
307 event = pevent->events[i]; 315 event = pevent->events[i];
308 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { 316 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
309 match = 1; 317 match = 1;
310 add_event(events, event); 318 if (add_event(events, event) < 0) {
319 fail = 1;
320 break;
321 }
311 } 322 }
312 } 323 }
313 324
@@ -317,6 +328,8 @@ find_event(struct pevent *pevent, struct event_list **events,
317 328
318 if (!match) 329 if (!match)
319 return -1; 330 return -1;
331 if (fail)
332 return -2;
320 333
321 return 0; 334 return 0;
322} 335}
@@ -349,8 +362,11 @@ create_arg_item(struct event_format *event, const char *token,
349 arg->value.type = 362 arg->value.type =
350 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR; 363 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
351 arg->value.str = strdup(token); 364 arg->value.str = strdup(token);
352 if (!arg->value.str) 365 if (!arg->value.str) {
353 die("malloc string"); 366 free_arg(arg);
367 show_error(error_str, "failed to allocate string filter arg");
368 return NULL;
369 }
354 break; 370 break;
355 case EVENT_ITEM: 371 case EVENT_ITEM:
356 /* if it is a number, then convert it */ 372 /* if it is a number, then convert it */
@@ -1210,7 +1226,13 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
1210 else 1226 else
1211 len = strlen(filter_str); 1227 len = strlen(filter_str);
1212 1228
1213 this_event = malloc_or_die(len + 1); 1229 this_event = malloc(len + 1);
1230 if (this_event == NULL) {
1231 show_error(error_str, "Memory allocation failure");
1232 /* This can only happen when events is NULL, but still */
1233 free_events(events);
1234 return -1;
1235 }
1214 memcpy(this_event, filter_str, len); 1236 memcpy(this_event, filter_str, len);
1215 this_event[len] = 0; 1237 this_event[len] = 0;
1216 1238
@@ -1482,8 +1504,10 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source
1482 * @type: remove only true, false, or both 1504 * @type: remove only true, false, or both
1483 * 1505 *
1484 * Removes filters that only contain a TRUE or FALES boolean arg. 1506 * Removes filters that only contain a TRUE or FALES boolean arg.
1507 *
1508 * Returns 0 on success and -1 if there was a problem.
1485 */ 1509 */
1486void pevent_filter_clear_trivial(struct event_filter *filter, 1510int pevent_filter_clear_trivial(struct event_filter *filter,
1487 enum filter_trivial_type type) 1511 enum filter_trivial_type type)
1488{ 1512{
1489 struct filter_type *filter_type; 1513 struct filter_type *filter_type;
@@ -1492,13 +1516,15 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1492 int i; 1516 int i;
1493 1517
1494 if (!filter->filters) 1518 if (!filter->filters)
1495 return; 1519 return 0;
1496 1520
1497 /* 1521 /*
1498 * Two steps, first get all ids with trivial filters. 1522 * Two steps, first get all ids with trivial filters.
1499 * then remove those ids. 1523 * then remove those ids.
1500 */ 1524 */
1501 for (i = 0; i < filter->filters; i++) { 1525 for (i = 0; i < filter->filters; i++) {
1526 int *new_ids;
1527
1502 filter_type = &filter->event_filters[i]; 1528 filter_type = &filter->event_filters[i];
1503 if (filter_type->filter->type != FILTER_ARG_BOOLEAN) 1529 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1504 continue; 1530 continue;
@@ -1513,19 +1539,24 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1513 break; 1539 break;
1514 } 1540 }
1515 1541
1516 ids = realloc(ids, sizeof(*ids) * (count + 1)); 1542 new_ids = realloc(ids, sizeof(*ids) * (count + 1));
1517 if (!ids) 1543 if (!new_ids) {
1518 die("Can't allocate ids"); 1544 free(ids);
1545 return -1;
1546 }
1547
1548 ids = new_ids;
1519 ids[count++] = filter_type->event_id; 1549 ids[count++] = filter_type->event_id;
1520 } 1550 }
1521 1551
1522 if (!count) 1552 if (!count)
1523 return; 1553 return 0;
1524 1554
1525 for (i = 0; i < count; i++) 1555 for (i = 0; i < count; i++)
1526 pevent_filter_remove_event(filter, ids[i]); 1556 pevent_filter_remove_event(filter, ids[i]);
1527 1557
1528 free(ids); 1558 free(ids);
1559 return 0;
1529} 1560}
1530 1561
1531/** 1562/**
diff --git a/tools/perf/Documentation/perf-archive.txt b/tools/perf/Documentation/perf-archive.txt
index 5032a142853e..ac6ecbb3e669 100644
--- a/tools/perf/Documentation/perf-archive.txt
+++ b/tools/perf/Documentation/perf-archive.txt
@@ -12,9 +12,9 @@ SYNOPSIS
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15This command runs runs perf-buildid-list --with-hits, and collects the files 15This command runs perf-buildid-list --with-hits, and collects the files with the
16with the buildids found so that analysis of perf.data contents can be possible 16buildids found so that analysis of perf.data contents can be possible on another
17on another machine. 17machine.
18 18
19 19
20SEE ALSO 20SEE ALSO
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
index 96a9a1dea727..52276a6d2b75 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -10,9 +10,9 @@ SYNOPSIS
10[verse] 10[verse]
11'perf kvm' [--host] [--guest] [--guestmount=<path> 11'perf kvm' [--host] [--guest] [--guestmount=<path>
12 [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]] 12 [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
13 {top|record|report|diff|buildid-list} 13 {top|record|report|diff|buildid-list} [<options>]
14'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path> 14'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
15 | --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat} 15 | --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat} [<options>]
16'perf kvm stat [record|report|live] [<options>] 16'perf kvm stat [record|report|live] [<options>]
17 17
18DESCRIPTION 18DESCRIPTION
@@ -93,6 +93,9 @@ OPTIONS
93 kernel module information. Users copy it out from guest os. 93 kernel module information. Users copy it out from guest os.
94--guestvmlinux=<path>:: 94--guestvmlinux=<path>::
95 Guest os kernel vmlinux. 95 Guest os kernel vmlinux.
96-v::
97--verbose::
98 Be more verbose (show counter open errors, etc).
96 99
97STAT REPORT OPTIONS 100STAT REPORT OPTIONS
98------------------- 101-------------------
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 10a279871251..8eab8a4bdeb8 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -237,6 +237,15 @@ OPTIONS
237 Do not show entries which have an overhead under that percent. 237 Do not show entries which have an overhead under that percent.
238 (Default: 0). 238 (Default: 0).
239 239
240--header::
241 Show header information in the perf.data file. This includes
242 various information like hostname, OS and perf version, cpu/mem
243 info, perf command line, event list and so on. Currently only
244 --stdio output supports this feature.
245
246--header-only::
247 Show only perf.data header (forces --stdio).
248
240SEE ALSO 249SEE ALSO
241-------- 250--------
242linkperf:perf-stat[1], linkperf:perf-annotate[1] 251linkperf:perf-stat[1], linkperf:perf-annotate[1]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index cfdbb1e045b5..05f9a0a6784c 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,7 +115,7 @@ OPTIONS
115-f:: 115-f::
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff. 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline.
119 Field list can be prepended with the type, trace, sw or hw, 119 Field list can be prepended with the type, trace, sw or hw,
120 to indicate to which event type the field list applies. 120 to indicate to which event type the field list applies.
121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace 121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
@@ -209,6 +209,12 @@ OPTIONS
209--show-mmap-events 209--show-mmap-events
210 Display mmap related events (e.g. MMAP, MMAP2). 210 Display mmap related events (e.g. MMAP, MMAP2).
211 211
212--header
213 Show perf.data header.
214
215--header-only
216 Show only perf.data header.
217
212SEE ALSO 218SEE ALSO
213-------- 219--------
214linkperf:perf-record[1], linkperf:perf-script-perl[1], 220linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 4087ab19823c..6fd52c8fa682 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -373,7 +373,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
373 373
374 if (argc) { 374 if (argc) {
375 /* 375 /*
376 * Special case: if there's an argument left then assume tha 376 * Special case: if there's an argument left then assume that
377 * it's a symbol filter: 377 * it's a symbol filter:
378 */ 378 */
379 if (argc > 1) 379 if (argc > 1)
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 3b67ea2444bd..2a85cc9a2d09 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -1000,8 +1000,7 @@ static int data_init(int argc, const char **argv)
1000 data__files_cnt = argc; 1000 data__files_cnt = argc;
1001 use_default = false; 1001 use_default = false;
1002 } 1002 }
1003 } else if (symbol_conf.default_guest_vmlinux_name || 1003 } else if (perf_guest) {
1004 symbol_conf.default_guest_kallsyms) {
1005 defaults[0] = "perf.data.host"; 1004 defaults[0] = "perf.data.host";
1006 defaults[1] = "perf.data.guest"; 1005 defaults[1] = "perf.data.guest";
1007 } 1006 }
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index f8bf5f244d77..c6fa3cbd45a9 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1232,7 +1232,7 @@ static int read_events(struct perf_kvm_stat *kvm)
1232 .ordered_samples = true, 1232 .ordered_samples = true,
1233 }; 1233 };
1234 struct perf_data_file file = { 1234 struct perf_data_file file = {
1235 .path = input_name, 1235 .path = kvm->file_name,
1236 .mode = PERF_DATA_MODE_READ, 1236 .mode = PERF_DATA_MODE_READ,
1237 }; 1237 };
1238 1238
@@ -1690,6 +1690,8 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
1690 "file", "file saving guest os /proc/kallsyms"), 1690 "file", "file saving guest os /proc/kallsyms"),
1691 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, 1691 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
1692 "file", "file saving guest os /proc/modules"), 1692 "file", "file saving guest os /proc/modules"),
1693 OPT_INCR('v', "verbose", &verbose,
1694 "be more verbose (show counter open errors, etc)"),
1693 OPT_END() 1695 OPT_END()
1694 }; 1696 };
1695 1697
@@ -1711,12 +1713,7 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
1711 perf_guest = 1; 1713 perf_guest = 1;
1712 1714
1713 if (!file_name) { 1715 if (!file_name) {
1714 if (perf_host && !perf_guest) 1716 file_name = get_filename_for_perf_kvm();
1715 file_name = strdup("perf.data.host");
1716 else if (!perf_host && perf_guest)
1717 file_name = strdup("perf.data.guest");
1718 else
1719 file_name = strdup("perf.data.kvm");
1720 1717
1721 if (!file_name) { 1718 if (!file_name) {
1722 pr_err("Failed to allocate memory for filename\n"); 1719 pr_err("Failed to allocate memory for filename\n");
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d93e2eef0979..c1c1200d2f0a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -224,7 +224,7 @@ try_again:
224 "Consider increasing " 224 "Consider increasing "
225 "/proc/sys/kernel/perf_event_mlock_kb,\n" 225 "/proc/sys/kernel/perf_event_mlock_kb,\n"
226 "or try again with a smaller value of -m/--mmap_pages.\n" 226 "or try again with a smaller value of -m/--mmap_pages.\n"
227 "(current value: %d)\n", opts->mmap_pages); 227 "(current value: %u)\n", opts->mmap_pages);
228 rc = -errno; 228 rc = -errno;
229 } else { 229 } else {
230 pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno)); 230 pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 8cf8e66ba594..3a14dbed387c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -49,6 +49,8 @@ struct perf_report {
49 bool show_threads; 49 bool show_threads;
50 bool inverted_callchain; 50 bool inverted_callchain;
51 bool mem_mode; 51 bool mem_mode;
52 bool header;
53 bool header_only;
52 int max_stack; 54 int max_stack;
53 struct perf_read_values show_threads_values; 55 struct perf_read_values show_threads_values;
54 const char *pretty_printing_style; 56 const char *pretty_printing_style;
@@ -514,9 +516,6 @@ static int __cmd_report(struct perf_report *rep)
514 return ret; 516 return ret;
515 } 517 }
516 518
517 if (use_browser <= 0)
518 perf_session__fprintf_info(session, stdout, rep->show_full_info);
519
520 if (rep->show_threads) 519 if (rep->show_threads)
521 perf_read_values_init(&rep->show_threads_values); 520 perf_read_values_init(&rep->show_threads_values);
522 521
@@ -820,6 +819,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
820 OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"), 819 OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
821 OPT_BOOLEAN(0, "stdio", &report.use_stdio, 820 OPT_BOOLEAN(0, "stdio", &report.use_stdio,
822 "Use the stdio interface"), 821 "Use the stdio interface"),
822 OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
823 OPT_BOOLEAN(0, "header-only", &report.header_only,
824 "Show only data header."),
823 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 825 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
824 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," 826 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
825 " dso_to, dso_from, symbol_to, symbol_from, mispredict," 827 " dso_to, dso_from, symbol_to, symbol_from, mispredict,"
@@ -963,6 +965,10 @@ repeat:
963 goto error; 965 goto error;
964 } 966 }
965 967
968 /* Force tty output for header output. */
969 if (report.header || report.header_only)
970 use_browser = 0;
971
966 if (strcmp(input_name, "-") != 0) 972 if (strcmp(input_name, "-") != 0)
967 setup_browser(true); 973 setup_browser(true);
968 else { 974 else {
@@ -970,6 +976,16 @@ repeat:
970 perf_hpp__init(); 976 perf_hpp__init();
971 } 977 }
972 978
979 if (report.header || report.header_only) {
980 perf_session__fprintf_info(session, stdout,
981 report.show_full_info);
982 if (report.header_only)
983 return 0;
984 } else if (use_browser == 0) {
985 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
986 stdout);
987 }
988
973 /* 989 /*
974 * Only in the TUI browser we are doing integrated annotation, 990 * Only in the TUI browser we are doing integrated annotation,
975 * so don't allocate extra space that won't be used in the stdio 991 * so don't allocate extra space that won't be used in the stdio
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4484886dcf08..f8ab125aac48 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -43,6 +43,7 @@ enum perf_output_field {
43 PERF_OUTPUT_DSO = 1U << 9, 43 PERF_OUTPUT_DSO = 1U << 9,
44 PERF_OUTPUT_ADDR = 1U << 10, 44 PERF_OUTPUT_ADDR = 1U << 10,
45 PERF_OUTPUT_SYMOFFSET = 1U << 11, 45 PERF_OUTPUT_SYMOFFSET = 1U << 11,
46 PERF_OUTPUT_SRCLINE = 1U << 12,
46}; 47};
47 48
48struct output_option { 49struct output_option {
@@ -61,6 +62,7 @@ struct output_option {
61 {.str = "dso", .field = PERF_OUTPUT_DSO}, 62 {.str = "dso", .field = PERF_OUTPUT_DSO},
62 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 63 {.str = "addr", .field = PERF_OUTPUT_ADDR},
63 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 64 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
65 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
64}; 66};
65 67
66/* default set to maintain compatibility with current format */ 68/* default set to maintain compatibility with current format */
@@ -210,6 +212,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
210 "to DSO.\n"); 212 "to DSO.\n");
211 return -EINVAL; 213 return -EINVAL;
212 } 214 }
215 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
216 pr_err("Display of source line number requested but sample IP is not\n"
217 "selected. Hence, no address to lookup the source line number.\n");
218 return -EINVAL;
219 }
213 220
214 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 221 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
215 perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", 222 perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
@@ -245,6 +252,9 @@ static void set_print_ip_opts(struct perf_event_attr *attr)
245 252
246 if (PRINT_FIELD(SYMOFFSET)) 253 if (PRINT_FIELD(SYMOFFSET))
247 output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET; 254 output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
255
256 if (PRINT_FIELD(SRCLINE))
257 output[type].print_ip_opts |= PRINT_IP_OPT_SRCLINE;
248} 258}
249 259
250/* 260/*
@@ -1484,6 +1494,8 @@ static int have_cmd(int argc, const char **argv)
1484int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) 1494int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1485{ 1495{
1486 bool show_full_info = false; 1496 bool show_full_info = false;
1497 bool header = false;
1498 bool header_only = false;
1487 char *rec_script_path = NULL; 1499 char *rec_script_path = NULL;
1488 char *rep_script_path = NULL; 1500 char *rep_script_path = NULL;
1489 struct perf_session *session; 1501 struct perf_session *session;
@@ -1522,6 +1534,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1522 OPT_STRING('i', "input", &input_name, "file", "input file name"), 1534 OPT_STRING('i', "input", &input_name, "file", "input file name"),
1523 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 1535 OPT_BOOLEAN('d', "debug-mode", &debug_mode,
1524 "do various checks like samples ordering and lost events"), 1536 "do various checks like samples ordering and lost events"),
1537 OPT_BOOLEAN(0, "header", &header, "Show data header."),
1538 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
1525 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1539 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1526 "file", "vmlinux pathname"), 1540 "file", "vmlinux pathname"),
1527 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 1541 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
@@ -1738,6 +1752,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1738 if (session == NULL) 1752 if (session == NULL)
1739 return -ENOMEM; 1753 return -ENOMEM;
1740 1754
1755 if (header || header_only) {
1756 perf_session__fprintf_info(session, stdout, show_full_info);
1757 if (header_only)
1758 return 0;
1759 }
1760
1741 script.session = session; 1761 script.session = session;
1742 1762
1743 if (cpu_list) { 1763 if (cpu_list) {
@@ -1745,9 +1765,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1745 return -1; 1765 return -1;
1746 } 1766 }
1747 1767
1748 if (!script_name && !generate_script_lang)
1749 perf_session__fprintf_info(session, stdout, show_full_info);
1750
1751 if (!no_callchain) 1768 if (!no_callchain)
1752 symbol_conf.use_callchain = true; 1769 symbol_conf.use_callchain = true;
1753 else 1770 else
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 56afe339661a..56bbca5bc2dc 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -12,6 +12,7 @@
12#include "util/thread_map.h" 12#include "util/thread_map.h"
13#include "util/stat.h" 13#include "util/stat.h"
14#include "trace-event.h" 14#include "trace-event.h"
15#include "util/parse-events.h"
15 16
16#include <libaudit.h> 17#include <libaudit.h>
17#include <stdlib.h> 18#include <stdlib.h>
@@ -173,6 +174,10 @@ static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void
173{ 174{
174 struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction); 175 struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
175 176
177 /* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */
178 if (evsel == NULL)
179 evsel = perf_evsel__newtp("syscalls", direction);
180
176 if (evsel) { 181 if (evsel) {
177 if (perf_evsel__init_syscall_tp(evsel, handler)) 182 if (perf_evsel__init_syscall_tp(evsel, handler))
178 goto out_delete; 183 goto out_delete;
@@ -1765,8 +1770,10 @@ static int trace__process_sample(struct perf_tool *tool,
1765 if (!trace->full_time && trace->base_time == 0) 1770 if (!trace->full_time && trace->base_time == 0)
1766 trace->base_time = sample->time; 1771 trace->base_time = sample->time;
1767 1772
1768 if (handler) 1773 if (handler) {
1774 ++trace->nr_events;
1769 handler(trace, evsel, sample); 1775 handler(trace, evsel, sample);
1776 }
1770 1777
1771 return err; 1778 return err;
1772} 1779}
@@ -1801,10 +1808,11 @@ static int trace__record(int argc, const char **argv)
1801 "-R", 1808 "-R",
1802 "-m", "1024", 1809 "-m", "1024",
1803 "-c", "1", 1810 "-c", "1",
1804 "-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit", 1811 "-e",
1805 }; 1812 };
1806 1813
1807 rec_argc = ARRAY_SIZE(record_args) + argc; 1814 /* +1 is for the event string below */
1815 rec_argc = ARRAY_SIZE(record_args) + 1 + argc;
1808 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1816 rec_argv = calloc(rec_argc + 1, sizeof(char *));
1809 1817
1810 if (rec_argv == NULL) 1818 if (rec_argv == NULL)
@@ -1813,6 +1821,17 @@ static int trace__record(int argc, const char **argv)
1813 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1821 for (i = 0; i < ARRAY_SIZE(record_args); i++)
1814 rec_argv[i] = record_args[i]; 1822 rec_argv[i] = record_args[i];
1815 1823
1824 /* event string may be different for older kernels - e.g., RHEL6 */
1825 if (is_valid_tracepoint("raw_syscalls:sys_enter"))
1826 rec_argv[i] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit";
1827 else if (is_valid_tracepoint("syscalls:sys_enter"))
1828 rec_argv[i] = "syscalls:sys_enter,syscalls:sys_exit";
1829 else {
1830 pr_err("Neither raw_syscalls nor syscalls events exist.\n");
1831 return -1;
1832 }
1833 i++;
1834
1816 for (j = 0; j < (unsigned int)argc; j++, i++) 1835 for (j = 0; j < (unsigned int)argc; j++, i++)
1817 rec_argv[i] = argv[j]; 1836 rec_argv[i] = argv[j];
1818 1837
@@ -2048,6 +2067,10 @@ static int trace__replay(struct trace *trace)
2048 2067
2049 evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2068 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2050 "raw_syscalls:sys_enter"); 2069 "raw_syscalls:sys_enter");
2070 /* older kernels have syscalls tp versus raw_syscalls */
2071 if (evsel == NULL)
2072 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2073 "syscalls:sys_enter");
2051 if (evsel == NULL) { 2074 if (evsel == NULL) {
2052 pr_err("Data file does not have raw_syscalls:sys_enter event\n"); 2075 pr_err("Data file does not have raw_syscalls:sys_enter event\n");
2053 goto out; 2076 goto out;
@@ -2061,6 +2084,9 @@ static int trace__replay(struct trace *trace)
2061 2084
2062 evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2085 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2063 "raw_syscalls:sys_exit"); 2086 "raw_syscalls:sys_exit");
2087 if (evsel == NULL)
2088 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2089 "syscalls:sys_exit");
2064 if (evsel == NULL) { 2090 if (evsel == NULL) {
2065 pr_err("Data file does not have raw_syscalls:sys_exit event\n"); 2091 pr_err("Data file does not have raw_syscalls:sys_exit event\n");
2066 goto out; 2092 goto out;
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index bae10720a136..5a1f4df3c3a8 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -36,6 +36,30 @@ ifeq ($(ARCH),arm)
36 LIBUNWIND_LIBS = -lunwind -lunwind-arm 36 LIBUNWIND_LIBS = -lunwind -lunwind-arm
37endif 37endif
38 38
39ifeq ($(LIBUNWIND_LIBS),)
40 NO_LIBUNWIND := 1
41else
42 #
43 # For linking with debug library, run like:
44 #
45 # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
46 #
47 ifdef LIBUNWIND_DIR
48 LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include
49 LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib
50 endif
51 LIBUNWIND_LDFLAGS += $(LIBUNWIND_LIBS)
52
53 # Set per-feature check compilation flags
54 FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS)
55 FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS)
56 FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS)
57 FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS)
58 # and the flags for the test-all case
59 FEATURE_CHECK_CFLAGS-all += $(LIBUNWIND_CFLAGS)
60 FEATURE_CHECK_LDFLAGS-all += $(LIBUNWIND_LDFLAGS)
61endif
62
39ifeq ($(NO_PERF_REGS),0) 63ifeq ($(NO_PERF_REGS),0)
40 CFLAGS += -DHAVE_PERF_REGS_SUPPORT 64 CFLAGS += -DHAVE_PERF_REGS_SUPPORT
41endif 65endif
@@ -102,7 +126,7 @@ endif
102 126
103feature_check = $(eval $(feature_check_code)) 127feature_check = $(eval $(feature_check_code))
104define feature_check_code 128define feature_check_code
105 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBUNWIND_LIBS="$(LIBUNWIND_LIBS)" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) 129 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
106endef 130endef
107 131
108feature_set = $(eval $(feature_set_code)) 132feature_set = $(eval $(feature_set_code))
@@ -305,21 +329,7 @@ ifndef NO_LIBELF
305 endif # NO_DWARF 329 endif # NO_DWARF
306endif # NO_LIBELF 330endif # NO_LIBELF
307 331
308ifeq ($(LIBUNWIND_LIBS),)
309 NO_LIBUNWIND := 1
310endif
311
312ifndef NO_LIBUNWIND 332ifndef NO_LIBUNWIND
313 #
314 # For linking with debug library, run like:
315 #
316 # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
317 #
318 ifdef LIBUNWIND_DIR
319 LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
320 LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
321 endif
322
323 ifneq ($(feature-libunwind), 1) 333 ifneq ($(feature-libunwind), 1)
324 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1); 334 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
325 NO_LIBUNWIND := 1 335 NO_LIBUNWIND := 1
@@ -334,14 +344,12 @@ ifndef NO_LIBUNWIND
334 # non-ARM has no dwarf_find_debug_frame() function: 344 # non-ARM has no dwarf_find_debug_frame() function:
335 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME 345 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
336 endif 346 endif
337 endif
338endif
339 347
340ifndef NO_LIBUNWIND 348 CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
341 CFLAGS += -DHAVE_LIBUNWIND_SUPPORT 349 EXTLIBS += $(LIBUNWIND_LIBS)
342 EXTLIBS += $(LIBUNWIND_LIBS) 350 CFLAGS += $(LIBUNWIND_CFLAGS)
343 CFLAGS += $(LIBUNWIND_CFLAGS) 351 LDFLAGS += $(LIBUNWIND_LDFLAGS)
344 LDFLAGS += $(LIBUNWIND_LDFLAGS) 352 endif # ifneq ($(feature-libunwind), 1)
345endif 353endif
346 354
347ifndef NO_LIBAUDIT 355ifndef NO_LIBAUDIT
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index b8bb749c3392..bc86462e80a2 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -32,12 +32,12 @@ CC := $(CC) -MD
32 32
33all: $(FILES) 33all: $(FILES)
34 34
35BUILD = $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT)$@ $@.c 35BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS)
36 36
37############################### 37###############################
38 38
39test-all: 39test-all:
40 $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma $(LIBUNWIND_LIBS) -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl 40 $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
41 41
42test-hello: 42test-hello:
43 $(BUILD) 43 $(BUILD)
@@ -70,10 +70,10 @@ test-libnuma:
70 $(BUILD) -lnuma 70 $(BUILD) -lnuma
71 71
72test-libunwind: 72test-libunwind:
73 $(BUILD) $(LIBUNWIND_LIBS) -lelf 73 $(BUILD) -lelf
74 74
75test-libunwind-debug-frame: 75test-libunwind-debug-frame:
76 $(BUILD) $(LIBUNWIND_LIBS) -lelf 76 $(BUILD) -lelf
77 77
78test-libaudit: 78test-libaudit:
79 $(BUILD) -laudit 79 $(BUILD) -laudit
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index cf6242c92ee2..0fcd81ea31ae 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -900,7 +900,7 @@ fallback:
900 * cache, or is just a kallsyms file, well, lets hope that this 900 * cache, or is just a kallsyms file, well, lets hope that this
901 * DSO is the same as when 'perf record' ran. 901 * DSO is the same as when 'perf record' ran.
902 */ 902 */
903 filename = dso->long_name; 903 filename = (char *)dso->long_name;
904 snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", 904 snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
905 symbol_conf.symfs, filename); 905 symbol_conf.symfs, filename);
906 free_filename = false; 906 free_filename = false;
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a92770c98cc7..6baabe63182b 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -89,7 +89,7 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
89 return raw - build_id; 89 return raw - build_id;
90} 90}
91 91
92char *dso__build_id_filename(struct dso *dso, char *bf, size_t size) 92char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
93{ 93{
94 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 94 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
95 95
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 929f28a7c14d..845ef865eced 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -10,7 +10,7 @@ extern struct perf_tool build_id__mark_dso_hit_ops;
10struct dso; 10struct dso;
11 11
12int build_id__sprintf(const u8 *build_id, int len, char *bf); 12int build_id__sprintf(const u8 *build_id, int len, char *bf);
13char *dso__build_id_filename(struct dso *dso, char *bf, size_t size); 13char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
14 14
15int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, 15int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
16 struct perf_sample *sample, struct perf_evsel *evsel, 16 struct perf_sample *sample, struct perf_evsel *evsel,
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index a0c7c591f4b2..436922f1f9d9 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -28,8 +28,8 @@ char dso__symtab_origin(const struct dso *dso)
28 return origin[dso->symtab_type]; 28 return origin[dso->symtab_type];
29} 29}
30 30
31int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, 31int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
32 char *root_dir, char *file, size_t size) 32 char *root_dir, char *filename, size_t size)
33{ 33{
34 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 34 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
35 int ret = 0; 35 int ret = 0;
@@ -38,36 +38,36 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
38 case DSO_BINARY_TYPE__DEBUGLINK: { 38 case DSO_BINARY_TYPE__DEBUGLINK: {
39 char *debuglink; 39 char *debuglink;
40 40
41 strncpy(file, dso->long_name, size); 41 strncpy(filename, dso->long_name, size);
42 debuglink = file + dso->long_name_len; 42 debuglink = filename + dso->long_name_len;
43 while (debuglink != file && *debuglink != '/') 43 while (debuglink != filename && *debuglink != '/')
44 debuglink--; 44 debuglink--;
45 if (*debuglink == '/') 45 if (*debuglink == '/')
46 debuglink++; 46 debuglink++;
47 filename__read_debuglink(dso->long_name, debuglink, 47 filename__read_debuglink(dso->long_name, debuglink,
48 size - (debuglink - file)); 48 size - (debuglink - filename));
49 } 49 }
50 break; 50 break;
51 case DSO_BINARY_TYPE__BUILD_ID_CACHE: 51 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
52 /* skip the locally configured cache if a symfs is given */ 52 /* skip the locally configured cache if a symfs is given */
53 if (symbol_conf.symfs[0] || 53 if (symbol_conf.symfs[0] ||
54 (dso__build_id_filename(dso, file, size) == NULL)) 54 (dso__build_id_filename(dso, filename, size) == NULL))
55 ret = -1; 55 ret = -1;
56 break; 56 break;
57 57
58 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: 58 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
59 snprintf(file, size, "%s/usr/lib/debug%s.debug", 59 snprintf(filename, size, "%s/usr/lib/debug%s.debug",
60 symbol_conf.symfs, dso->long_name); 60 symbol_conf.symfs, dso->long_name);
61 break; 61 break;
62 62
63 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: 63 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
64 snprintf(file, size, "%s/usr/lib/debug%s", 64 snprintf(filename, size, "%s/usr/lib/debug%s",
65 symbol_conf.symfs, dso->long_name); 65 symbol_conf.symfs, dso->long_name);
66 break; 66 break;
67 67
68 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: 68 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
69 { 69 {
70 char *last_slash; 70 const char *last_slash;
71 size_t len; 71 size_t len;
72 size_t dir_size; 72 size_t dir_size;
73 73
@@ -75,14 +75,14 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
75 while (last_slash != dso->long_name && *last_slash != '/') 75 while (last_slash != dso->long_name && *last_slash != '/')
76 last_slash--; 76 last_slash--;
77 77
78 len = scnprintf(file, size, "%s", symbol_conf.symfs); 78 len = scnprintf(filename, size, "%s", symbol_conf.symfs);
79 dir_size = last_slash - dso->long_name + 2; 79 dir_size = last_slash - dso->long_name + 2;
80 if (dir_size > (size - len)) { 80 if (dir_size > (size - len)) {
81 ret = -1; 81 ret = -1;
82 break; 82 break;
83 } 83 }
84 len += scnprintf(file + len, dir_size, "%s", dso->long_name); 84 len += scnprintf(filename + len, dir_size, "%s", dso->long_name);
85 len += scnprintf(file + len , size - len, ".debug%s", 85 len += scnprintf(filename + len , size - len, ".debug%s",
86 last_slash); 86 last_slash);
87 break; 87 break;
88 } 88 }
@@ -96,7 +96,7 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
96 build_id__sprintf(dso->build_id, 96 build_id__sprintf(dso->build_id,
97 sizeof(dso->build_id), 97 sizeof(dso->build_id),
98 build_id_hex); 98 build_id_hex);
99 snprintf(file, size, 99 snprintf(filename, size,
100 "%s/usr/lib/debug/.build-id/%.2s/%s.debug", 100 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
101 symbol_conf.symfs, build_id_hex, build_id_hex + 2); 101 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
102 break; 102 break;
@@ -104,23 +104,23 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
104 case DSO_BINARY_TYPE__VMLINUX: 104 case DSO_BINARY_TYPE__VMLINUX:
105 case DSO_BINARY_TYPE__GUEST_VMLINUX: 105 case DSO_BINARY_TYPE__GUEST_VMLINUX:
106 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: 106 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
107 snprintf(file, size, "%s%s", 107 snprintf(filename, size, "%s%s",
108 symbol_conf.symfs, dso->long_name); 108 symbol_conf.symfs, dso->long_name);
109 break; 109 break;
110 110
111 case DSO_BINARY_TYPE__GUEST_KMODULE: 111 case DSO_BINARY_TYPE__GUEST_KMODULE:
112 snprintf(file, size, "%s%s%s", symbol_conf.symfs, 112 snprintf(filename, size, "%s%s%s", symbol_conf.symfs,
113 root_dir, dso->long_name); 113 root_dir, dso->long_name);
114 break; 114 break;
115 115
116 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: 116 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
117 snprintf(file, size, "%s%s", symbol_conf.symfs, 117 snprintf(filename, size, "%s%s", symbol_conf.symfs,
118 dso->long_name); 118 dso->long_name);
119 break; 119 break;
120 120
121 case DSO_BINARY_TYPE__KCORE: 121 case DSO_BINARY_TYPE__KCORE:
122 case DSO_BINARY_TYPE__GUEST_KCORE: 122 case DSO_BINARY_TYPE__GUEST_KCORE:
123 snprintf(file, size, "%s", dso->long_name); 123 snprintf(filename, size, "%s", dso->long_name);
124 break; 124 break;
125 125
126 default: 126 default:
@@ -200,11 +200,10 @@ dso_cache__free(struct rb_root *root)
200 } 200 }
201} 201}
202 202
203static struct dso_cache* 203static struct dso_cache *dso_cache__find(const struct rb_root *root, u64 offset)
204dso_cache__find(struct rb_root *root, u64 offset)
205{ 204{
206 struct rb_node **p = &root->rb_node; 205 struct rb_node * const *p = &root->rb_node;
207 struct rb_node *parent = NULL; 206 const struct rb_node *parent = NULL;
208 struct dso_cache *cache; 207 struct dso_cache *cache;
209 208
210 while (*p != NULL) { 209 while (*p != NULL) {
@@ -379,32 +378,63 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
379 * processing we had no idea this was the kernel dso. 378 * processing we had no idea this was the kernel dso.
380 */ 379 */
381 if (dso != NULL) { 380 if (dso != NULL) {
382 dso__set_short_name(dso, short_name); 381 dso__set_short_name(dso, short_name, false);
383 dso->kernel = dso_type; 382 dso->kernel = dso_type;
384 } 383 }
385 384
386 return dso; 385 return dso;
387} 386}
388 387
389void dso__set_long_name(struct dso *dso, char *name) 388void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
390{ 389{
391 if (name == NULL) 390 if (name == NULL)
392 return; 391 return;
393 dso->long_name = name; 392
394 dso->long_name_len = strlen(name); 393 if (dso->long_name_allocated)
394 free((char *)dso->long_name);
395
396 dso->long_name = name;
397 dso->long_name_len = strlen(name);
398 dso->long_name_allocated = name_allocated;
395} 399}
396 400
397void dso__set_short_name(struct dso *dso, const char *name) 401void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
398{ 402{
399 if (name == NULL) 403 if (name == NULL)
400 return; 404 return;
401 dso->short_name = name; 405
402 dso->short_name_len = strlen(name); 406 if (dso->short_name_allocated)
407 free((char *)dso->short_name);
408
409 dso->short_name = name;
410 dso->short_name_len = strlen(name);
411 dso->short_name_allocated = name_allocated;
403} 412}
404 413
405static void dso__set_basename(struct dso *dso) 414static void dso__set_basename(struct dso *dso)
406{ 415{
407 dso__set_short_name(dso, basename(dso->long_name)); 416 /*
417 * basename() may modify path buffer, so we must pass
418 * a copy.
419 */
420 char *base, *lname = strdup(dso->long_name);
421
422 if (!lname)
423 return;
424
425 /*
426 * basename() may return a pointer to internal
427 * storage which is reused in subsequent calls
428 * so copy the result.
429 */
430 base = strdup(basename(lname));
431
432 free(lname);
433
434 if (!base)
435 return;
436
437 dso__set_short_name(dso, base, true);
408} 438}
409 439
410int dso__name_len(const struct dso *dso) 440int dso__name_len(const struct dso *dso)
@@ -439,8 +469,8 @@ struct dso *dso__new(const char *name)
439 if (dso != NULL) { 469 if (dso != NULL) {
440 int i; 470 int i;
441 strcpy(dso->name, name); 471 strcpy(dso->name, name);
442 dso__set_long_name(dso, dso->name); 472 dso__set_long_name(dso, dso->name, false);
443 dso__set_short_name(dso, dso->name); 473 dso__set_short_name(dso, dso->name, false);
444 for (i = 0; i < MAP__NR_TYPES; ++i) 474 for (i = 0; i < MAP__NR_TYPES; ++i)
445 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; 475 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
446 dso->cache = RB_ROOT; 476 dso->cache = RB_ROOT;
@@ -465,13 +495,23 @@ void dso__delete(struct dso *dso)
465 int i; 495 int i;
466 for (i = 0; i < MAP__NR_TYPES; ++i) 496 for (i = 0; i < MAP__NR_TYPES; ++i)
467 symbols__delete(&dso->symbols[i]); 497 symbols__delete(&dso->symbols[i]);
468 if (dso->sname_alloc) 498
499 if (dso->short_name_allocated) {
469 free((char *)dso->short_name); 500 free((char *)dso->short_name);
470 if (dso->lname_alloc) 501 dso->short_name = NULL;
471 free(dso->long_name); 502 dso->short_name_allocated = false;
503 }
504
505 if (dso->long_name_allocated) {
506 free((char *)dso->long_name);
507 dso->long_name = NULL;
508 dso->long_name_allocated = false;
509 }
510
472 dso_cache__free(&dso->cache); 511 dso_cache__free(&dso->cache);
473 dso__free_a2l(dso); 512 dso__free_a2l(dso);
474 free(dso->symsrc_filename); 513 free(dso->symsrc_filename);
514 dso->symsrc_filename = NULL;
475 free(dso); 515 free(dso);
476} 516}
477 517
@@ -546,7 +586,7 @@ void dsos__add(struct list_head *head, struct dso *dso)
546 list_add_tail(&dso->node, head); 586 list_add_tail(&dso->node, head);
547} 587}
548 588
549struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short) 589struct dso *dsos__find(const struct list_head *head, const char *name, bool cmp_short)
550{ 590{
551 struct dso *pos; 591 struct dso *pos;
552 592
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 384f2d97e38e..e1cc50698137 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -89,14 +89,14 @@ struct dso {
89 u8 has_srcline:1; 89 u8 has_srcline:1;
90 u8 hit:1; 90 u8 hit:1;
91 u8 annotate_warned:1; 91 u8 annotate_warned:1;
92 u8 sname_alloc:1; 92 u8 short_name_allocated:1;
93 u8 lname_alloc:1; 93 u8 long_name_allocated:1;
94 u8 sorted_by_name; 94 u8 sorted_by_name;
95 u8 loaded; 95 u8 loaded;
96 u8 rel; 96 u8 rel;
97 u8 build_id[BUILD_ID_SIZE]; 97 u8 build_id[BUILD_ID_SIZE];
98 const char *short_name; 98 const char *short_name;
99 char *long_name; 99 const char *long_name;
100 u16 long_name_len; 100 u16 long_name_len;
101 u16 short_name_len; 101 u16 short_name_len;
102 char name[0]; 102 char name[0];
@@ -110,8 +110,8 @@ static inline void dso__set_loaded(struct dso *dso, enum map_type type)
110struct dso *dso__new(const char *name); 110struct dso *dso__new(const char *name);
111void dso__delete(struct dso *dso); 111void dso__delete(struct dso *dso);
112 112
113void dso__set_short_name(struct dso *dso, const char *name); 113void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated);
114void dso__set_long_name(struct dso *dso, char *name); 114void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated);
115 115
116int dso__name_len(const struct dso *dso); 116int dso__name_len(const struct dso *dso);
117 117
@@ -128,8 +128,8 @@ void dso__read_running_kernel_build_id(struct dso *dso,
128int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); 128int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
129 129
130char dso__symtab_origin(const struct dso *dso); 130char dso__symtab_origin(const struct dso *dso);
131int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, 131int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
132 char *root_dir, char *file, size_t size); 132 char *root_dir, char *filename, size_t size);
133 133
134int dso__data_fd(struct dso *dso, struct machine *machine); 134int dso__data_fd(struct dso *dso, struct machine *machine);
135ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, 135ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
@@ -143,7 +143,7 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
143 const char *short_name, int dso_type); 143 const char *short_name, int dso_type);
144 144
145void dsos__add(struct list_head *head, struct dso *dso); 145void dsos__add(struct list_head *head, struct dso *dso);
146struct dso *dsos__find(struct list_head *head, const char *name, 146struct dso *dsos__find(const struct list_head *head, const char *name,
147 bool cmp_short); 147 bool cmp_short);
148struct dso *__dsos__findnew(struct list_head *head, const char *name); 148struct dso *__dsos__findnew(struct list_head *head, const char *name);
149bool __dsos__read_build_ids(struct list_head *head, bool with_hits); 149bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 7bb6ee1ca19f..af250556b33f 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -732,11 +732,13 @@ static long parse_pages_arg(const char *str, unsigned long min,
732 return -EINVAL; 732 return -EINVAL;
733 } 733 }
734 734
735 if ((pages == 0) && (min == 0)) { 735 if (pages == 0 && min == 0) {
736 /* leave number of pages at 0 */ 736 /* leave number of pages at 0 */
737 } else if (pages < (1UL << 31) && !is_power_of_2(pages)) { 737 } else if (!is_power_of_2(pages)) {
738 /* round pages up to next power of 2 */ 738 /* round pages up to next power of 2 */
739 pages = next_pow2(pages); 739 pages = next_pow2_l(pages);
740 if (!pages)
741 return -EINVAL;
740 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", 742 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
741 pages * page_size, pages); 743 pages * page_size, pages);
742 } 744 }
@@ -754,7 +756,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
754 unsigned long max = UINT_MAX; 756 unsigned long max = UINT_MAX;
755 long pages; 757 long pages;
756 758
757 if (max < SIZE_MAX / page_size) 759 if (max > SIZE_MAX / page_size)
758 max = SIZE_MAX / page_size; 760 max = SIZE_MAX / page_size;
759 761
760 pages = parse_pages_arg(str, 1, max); 762 pages = parse_pages_arg(str, 1, max);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 125cdc9250ee..0bb830f6b49c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -177,7 +177,7 @@ perf_header__set_cmdline(int argc, const char **argv)
177 continue; \ 177 continue; \
178 else 178 else
179 179
180static int write_buildid(char *name, size_t name_len, u8 *build_id, 180static int write_buildid(const char *name, size_t name_len, u8 *build_id,
181 pid_t pid, u16 misc, int fd) 181 pid_t pid, u16 misc, int fd)
182{ 182{
183 int err; 183 int err;
@@ -209,7 +209,7 @@ static int __dsos__write_buildid_table(struct list_head *head,
209 209
210 dsos__for_each_with_build_id(pos, head) { 210 dsos__for_each_with_build_id(pos, head) {
211 int err; 211 int err;
212 char *name; 212 const char *name;
213 size_t name_len; 213 size_t name_len;
214 214
215 if (!pos->hit) 215 if (!pos->hit)
@@ -387,7 +387,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine,
387{ 387{
388 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; 388 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
389 bool is_vdso = is_vdso_map(dso->short_name); 389 bool is_vdso = is_vdso_map(dso->short_name);
390 char *name = dso->long_name; 390 const char *name = dso->long_name;
391 char nm[PATH_MAX]; 391 char nm[PATH_MAX];
392 392
393 if (dso__is_kcore(dso)) { 393 if (dso__is_kcore(dso)) {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index bac817ab2068..751454bcde69 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -763,8 +763,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
763 ret = -1; 763 ret = -1;
764 goto out; 764 goto out;
765 } 765 }
766 dso__set_long_name(map->dso, long_name); 766 dso__set_long_name(map->dso, long_name, true);
767 map->dso->lname_alloc = 1;
768 dso__kernel_module_get_build_id(map->dso, ""); 767 dso__kernel_module_get_build_id(map->dso, "");
769 } 768 }
770 } 769 }
@@ -935,8 +934,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
935 if (name == NULL) 934 if (name == NULL)
936 goto out_problem; 935 goto out_problem;
937 936
938 map->dso->short_name = name; 937 dso__set_short_name(map->dso, name, true);
939 map->dso->sname_alloc = 1;
940 map->end = map->start + event->mmap.len; 938 map->end = map->start + event->mmap.len;
941 } else if (is_kernel_mmap) { 939 } else if (is_kernel_mmap) {
942 const char *symbol_name = (event->mmap.filename + 940 const char *symbol_name = (event->mmap.filename +
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index ef5bc913ca7a..9b9bd719aa19 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -11,6 +11,7 @@
11#include "strlist.h" 11#include "strlist.h"
12#include "vdso.h" 12#include "vdso.h"
13#include "build-id.h" 13#include "build-id.h"
14#include "util.h"
14#include <linux/string.h> 15#include <linux/string.h>
15 16
16const char *map_type__name[MAP__NR_TYPES] = { 17const char *map_type__name[MAP__NR_TYPES] = {
@@ -252,6 +253,22 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
252 return fprintf(fp, "%s", dsoname); 253 return fprintf(fp, "%s", dsoname);
253} 254}
254 255
256int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
257 FILE *fp)
258{
259 char *srcline;
260 int ret = 0;
261
262 if (map && map->dso) {
263 srcline = get_srcline(map->dso,
264 map__rip_2objdump(map, addr));
265 if (srcline != SRCLINE_UNKNOWN)
266 ret = fprintf(fp, "%s%s", prefix, srcline);
267 free_srcline(srcline);
268 }
269 return ret;
270}
271
255/** 272/**
256 * map__rip_2objdump - convert symbol start address to objdump address. 273 * map__rip_2objdump - convert symbol start address to objdump address.
257 * @map: memory map 274 * @map: memory map
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index e4e259c3ba16..18068c6b71c1 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -103,6 +103,8 @@ struct map *map__clone(struct map *map);
103int map__overlap(struct map *l, struct map *r); 103int map__overlap(struct map *l, struct map *r);
104size_t map__fprintf(struct map *map, FILE *fp); 104size_t map__fprintf(struct map *map, FILE *fp);
105size_t map__fprintf_dsoname(struct map *map, FILE *fp); 105size_t map__fprintf_dsoname(struct map *map, FILE *fp);
106int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
107 FILE *fp);
106 108
107int map__load(struct map *map, symbol_filter_t filter); 109int map__load(struct map *map, symbol_filter_t filter);
108struct symbol *map__find_symbol(struct map *map, 110struct symbol *map__find_symbol(struct map *map,
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9c6989ca2bea..d7cff57945c2 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -154,7 +154,7 @@ static struct dso *kernel_get_module_dso(const char *module)
154 154
155 vmlinux_name = symbol_conf.vmlinux_name; 155 vmlinux_name = symbol_conf.vmlinux_name;
156 if (vmlinux_name) { 156 if (vmlinux_name) {
157 if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0) 157 if (dso__load_vmlinux(dso, map, vmlinux_name, false, NULL) <= 0)
158 return NULL; 158 return NULL;
159 } else { 159 } else {
160 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { 160 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8a7da6f4a569..e748f29c53cf 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1497,6 +1497,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1497 int print_dso = print_opts & PRINT_IP_OPT_DSO; 1497 int print_dso = print_opts & PRINT_IP_OPT_DSO;
1498 int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET; 1498 int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
1499 int print_oneline = print_opts & PRINT_IP_OPT_ONELINE; 1499 int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
1500 int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
1500 char s = print_oneline ? ' ' : '\t'; 1501 char s = print_oneline ? ' ' : '\t';
1501 1502
1502 if (symbol_conf.use_callchain && sample->callchain) { 1503 if (symbol_conf.use_callchain && sample->callchain) {
@@ -1515,6 +1516,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1515 node_al = *al; 1516 node_al = *al;
1516 1517
1517 while (stack_depth) { 1518 while (stack_depth) {
1519 u64 addr = 0;
1520
1518 node = callchain_cursor_current(&callchain_cursor); 1521 node = callchain_cursor_current(&callchain_cursor);
1519 if (!node) 1522 if (!node)
1520 break; 1523 break;
@@ -1525,10 +1528,13 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1525 if (print_ip) 1528 if (print_ip)
1526 printf("%c%16" PRIx64, s, node->ip); 1529 printf("%c%16" PRIx64, s, node->ip);
1527 1530
1531 if (node->map)
1532 addr = node->map->map_ip(node->map, node->ip);
1533
1528 if (print_sym) { 1534 if (print_sym) {
1529 printf(" "); 1535 printf(" ");
1530 if (print_symoffset) { 1536 if (print_symoffset) {
1531 node_al.addr = node->ip; 1537 node_al.addr = addr;
1532 node_al.map = node->map; 1538 node_al.map = node->map;
1533 symbol__fprintf_symname_offs(node->sym, &node_al, stdout); 1539 symbol__fprintf_symname_offs(node->sym, &node_al, stdout);
1534 } else 1540 } else
@@ -1541,6 +1547,10 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1541 printf(")"); 1547 printf(")");
1542 } 1548 }
1543 1549
1550 if (print_srcline)
1551 map__fprintf_srcline(node->map, addr, "\n ",
1552 stdout);
1553
1544 if (!print_oneline) 1554 if (!print_oneline)
1545 printf("\n"); 1555 printf("\n");
1546 1556
@@ -1570,6 +1580,9 @@ next:
1570 map__fprintf_dsoname(al->map, stdout); 1580 map__fprintf_dsoname(al->map, stdout);
1571 printf(")"); 1581 printf(")");
1572 } 1582 }
1583
1584 if (print_srcline)
1585 map__fprintf_srcline(al->map, al->addr, "\n ", stdout);
1573 } 1586 }
1574} 1587}
1575 1588
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 004d3e8116aa..2a3955ea4fd8 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -45,6 +45,7 @@ struct perf_session {
45#define PRINT_IP_OPT_DSO (1<<2) 45#define PRINT_IP_OPT_DSO (1<<2)
46#define PRINT_IP_OPT_SYMOFFSET (1<<3) 46#define PRINT_IP_OPT_SYMOFFSET (1<<3)
47#define PRINT_IP_OPT_ONELINE (1<<4) 47#define PRINT_IP_OPT_ONELINE (1<<4)
48#define PRINT_IP_OPT_SRCLINE (1<<5)
48 49
49struct perf_tool; 50struct perf_tool;
50 51
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 0c075560ad46..58b2bd8f38c9 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -255,7 +255,7 @@ char *get_srcline(struct dso *dso, unsigned long addr)
255 char *file = NULL; 255 char *file = NULL;
256 unsigned line = 0; 256 unsigned line = 0;
257 char *srcline; 257 char *srcline;
258 char *dso_name; 258 const char *dso_name;
259 259
260 if (!dso->has_srcline) 260 if (!dso->has_srcline)
261 return SRCLINE_UNKNOWN; 261 return SRCLINE_UNKNOWN;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index de87dbac50a0..e377c2e96191 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1159,7 +1159,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1159 dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE; 1159 dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
1160 else 1160 else
1161 dso->data_type = DSO_BINARY_TYPE__KCORE; 1161 dso->data_type = DSO_BINARY_TYPE__KCORE;
1162 dso__set_long_name(dso, strdup(kcore_filename)); 1162 dso__set_long_name(dso, strdup(kcore_filename), true);
1163 1163
1164 close(fd); 1164 close(fd);
1165 1165
@@ -1408,7 +1408,8 @@ struct map *map_groups__find_by_name(struct map_groups *mg,
1408} 1408}
1409 1409
1410int dso__load_vmlinux(struct dso *dso, struct map *map, 1410int dso__load_vmlinux(struct dso *dso, struct map *map,
1411 const char *vmlinux, symbol_filter_t filter) 1411 const char *vmlinux, bool vmlinux_allocated,
1412 symbol_filter_t filter)
1412{ 1413{
1413 int err = -1; 1414 int err = -1;
1414 struct symsrc ss; 1415 struct symsrc ss;
@@ -1437,7 +1438,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
1437 dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX; 1438 dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1438 else 1439 else
1439 dso->data_type = DSO_BINARY_TYPE__VMLINUX; 1440 dso->data_type = DSO_BINARY_TYPE__VMLINUX;
1440 dso__set_long_name(dso, (char *)vmlinux); 1441 dso__set_long_name(dso, vmlinux, vmlinux_allocated);
1441 dso__set_loaded(dso, map->type); 1442 dso__set_loaded(dso, map->type);
1442 pr_debug("Using %s for symbols\n", symfs_vmlinux); 1443 pr_debug("Using %s for symbols\n", symfs_vmlinux);
1443 } 1444 }
@@ -1456,21 +1457,16 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1456 1457
1457 filename = dso__build_id_filename(dso, NULL, 0); 1458 filename = dso__build_id_filename(dso, NULL, 0);
1458 if (filename != NULL) { 1459 if (filename != NULL) {
1459 err = dso__load_vmlinux(dso, map, filename, filter); 1460 err = dso__load_vmlinux(dso, map, filename, true, filter);
1460 if (err > 0) { 1461 if (err > 0)
1461 dso->lname_alloc = 1;
1462 goto out; 1462 goto out;
1463 }
1464 free(filename); 1463 free(filename);
1465 } 1464 }
1466 1465
1467 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1466 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1468 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter); 1467 err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
1469 if (err > 0) { 1468 if (err > 0)
1470 dso__set_long_name(dso, strdup(vmlinux_path[i]));
1471 dso->lname_alloc = 1;
1472 break; 1469 break;
1473 }
1474 } 1470 }
1475out: 1471out:
1476 return err; 1472 return err;
@@ -1607,15 +1603,8 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1607 } 1603 }
1608 1604
1609 if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) { 1605 if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
1610 err = dso__load_vmlinux(dso, map, 1606 return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name,
1611 symbol_conf.vmlinux_name, filter); 1607 false, filter);
1612 if (err > 0) {
1613 dso__set_long_name(dso,
1614 strdup(symbol_conf.vmlinux_name));
1615 dso->lname_alloc = 1;
1616 return err;
1617 }
1618 return err;
1619 } 1608 }
1620 1609
1621 if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) { 1610 if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
@@ -1641,7 +1630,7 @@ do_kallsyms:
1641 free(kallsyms_allocated_filename); 1630 free(kallsyms_allocated_filename);
1642 1631
1643 if (err > 0 && !dso__is_kcore(dso)) { 1632 if (err > 0 && !dso__is_kcore(dso)) {
1644 dso__set_long_name(dso, strdup("[kernel.kallsyms]")); 1633 dso__set_long_name(dso, "[kernel.kallsyms]", false);
1645 map__fixup_start(map); 1634 map__fixup_start(map);
1646 map__fixup_end(map); 1635 map__fixup_end(map);
1647 } 1636 }
@@ -1671,7 +1660,8 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1671 */ 1660 */
1672 if (symbol_conf.default_guest_vmlinux_name != NULL) { 1661 if (symbol_conf.default_guest_vmlinux_name != NULL) {
1673 err = dso__load_vmlinux(dso, map, 1662 err = dso__load_vmlinux(dso, map,
1674 symbol_conf.default_guest_vmlinux_name, filter); 1663 symbol_conf.default_guest_vmlinux_name,
1664 false, filter);
1675 return err; 1665 return err;
1676 } 1666 }
1677 1667
@@ -1688,7 +1678,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1688 pr_debug("Using %s for symbols\n", kallsyms_filename); 1678 pr_debug("Using %s for symbols\n", kallsyms_filename);
1689 if (err > 0 && !dso__is_kcore(dso)) { 1679 if (err > 0 && !dso__is_kcore(dso)) {
1690 machine__mmap_name(machine, path, sizeof(path)); 1680 machine__mmap_name(machine, path, sizeof(path));
1691 dso__set_long_name(dso, strdup(path)); 1681 dso__set_long_name(dso, strdup(path), true);
1692 map__fixup_start(map); 1682 map__fixup_start(map);
1693 map__fixup_end(map); 1683 map__fixup_end(map);
1694 } 1684 }
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index f1031a1358a1..6de9c2b8a601 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -206,7 +206,8 @@ bool symsrc__possibly_runtime(struct symsrc *ss);
206 206
207int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter); 207int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
208int dso__load_vmlinux(struct dso *dso, struct map *map, 208int dso__load_vmlinux(struct dso *dso, struct map *map,
209 const char *vmlinux, symbol_filter_t filter); 209 const char *vmlinux, bool vmlinux_allocated,
210 symbol_filter_t filter);
210int dso__load_vmlinux_path(struct dso *dso, struct map *map, 211int dso__load_vmlinux_path(struct dso *dso, struct map *map,
211 symbol_filter_t filter); 212 symbol_filter_t filter);
212int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, 213int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index bae8756a4eb1..4a57609c0b43 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -482,3 +482,17 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep)
482 close(fd); 482 close(fd);
483 return err; 483 return err;
484} 484}
485
486const char *get_filename_for_perf_kvm(void)
487{
488 const char *filename;
489
490 if (perf_host && !perf_guest)
491 filename = strdup("perf.data.host");
492 else if (!perf_host && perf_guest)
493 filename = strdup("perf.data.guest");
494 else
495 filename = strdup("perf.data.kvm");
496
497 return filename;
498}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index adb39f251f90..0171213d1d4d 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -73,6 +73,7 @@
73#include <sys/ttydefaults.h> 73#include <sys/ttydefaults.h>
74#include <lk/debugfs.h> 74#include <lk/debugfs.h>
75#include <termios.h> 75#include <termios.h>
76#include <linux/bitops.h>
76 77
77extern const char *graph_line; 78extern const char *graph_line;
78extern const char *graph_dotted_line; 79extern const char *graph_dotted_line;
@@ -281,6 +282,17 @@ static inline unsigned next_pow2(unsigned x)
281 return 1ULL << (32 - __builtin_clz(x - 1)); 282 return 1ULL << (32 - __builtin_clz(x - 1));
282} 283}
283 284
285static inline unsigned long next_pow2_l(unsigned long x)
286{
287#if BITS_PER_LONG == 64
288 if (x <= (1UL << 31))
289 return next_pow2(x);
290 return (unsigned long)next_pow2(x >> 32) << 32;
291#else
292 return next_pow2(x);
293#endif
294}
295
284size_t hex_width(u64 v); 296size_t hex_width(u64 v);
285int hex2u64(const char *ptr, u64 *val); 297int hex2u64(const char *ptr, u64 *val);
286 298
@@ -309,4 +321,6 @@ void free_srcline(char *srcline);
309 321
310int filename__read_int(const char *filename, int *value); 322int filename__read_int(const char *filename, int *value);
311int filename__read_str(const char *filename, char **buf, size_t *sizep); 323int filename__read_str(const char *filename, char **buf, size_t *sizep);
324
325const char *get_filename_for_perf_kvm(void);
312#endif /* GIT_COMPAT_UTIL_H */ 326#endif /* GIT_COMPAT_UTIL_H */
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 39159822d58f..0ddb3b8a89ec 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -103,7 +103,7 @@ struct dso *vdso__dso_findnew(struct list_head *head)
103 dso = dso__new(VDSO__MAP_NAME); 103 dso = dso__new(VDSO__MAP_NAME);
104 if (dso != NULL) { 104 if (dso != NULL) {
105 dsos__add(head, dso); 105 dsos__add(head, dso);
106 dso__set_long_name(dso, file); 106 dso__set_long_name(dso, file, false);
107 } 107 }
108 } 108 }
109 109