Эх сурвалжийг харах

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>
Ingo Molnar 11 жил өмнө
parent
commit
813932149e

+ 18 - 10
tools/lib/traceevent/event-parse.c

@@ -2710,7 +2710,6 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
 	struct print_arg *farg;
 	struct print_arg *farg;
 	enum event_type type;
 	enum event_type type;
 	char *token;
 	char *token;
-	const char *test;
 	int i;
 	int i;
 
 
 	arg->type = PRINT_FUNC;
 	arg->type = PRINT_FUNC;
@@ -2727,15 +2726,19 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
 		}
 		}
 
 
 		type = process_arg(event, farg, &token);
 		type = process_arg(event, farg, &token);
-		if (i < (func->nr_args - 1))
-			test = ",";
-		else
-			test = ")";
-
-		if (test_type_token(type, token, EVENT_DELIM, test)) {
-			free_arg(farg);
-			free_token(token);
-			return EVENT_ERROR;
+		if (i < (func->nr_args - 1)) {
+			if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
+				warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
+					func->name, func->nr_args,
+					event->name, i + 1);
+				goto err;
+			}
+		} else {
+			if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
+				warning("Error: function '%s()' only expects %d arguments but event %s has more",
+					func->name, func->nr_args, event->name);
+				goto err;
+			}
 		}
 		}
 
 
 		*next_arg = farg;
 		*next_arg = farg;
@@ -2747,6 +2750,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
 	*tok = token;
 	*tok = token;
 
 
 	return type;
 	return type;
+
+err:
+	free_arg(farg);
+	free_token(token);
+	return EVENT_ERROR;
 }
 }
 
 
 static enum event_type
 static enum event_type

+ 1 - 1
tools/lib/traceevent/event-parse.h

@@ -860,7 +860,7 @@ int pevent_event_filtered(struct event_filter *filter,
 
 
 void pevent_filter_reset(struct event_filter *filter);
 void pevent_filter_reset(struct event_filter *filter);
 
 
-void pevent_filter_clear_trivial(struct event_filter *filter,
+int pevent_filter_clear_trivial(struct event_filter *filter,
 				 enum filter_trivial_type type);
 				 enum filter_trivial_type type);
 
 
 void pevent_filter_free(struct event_filter *filter);
 void pevent_filter_free(struct event_filter *filter);

+ 44 - 13
tools/lib/traceevent/parse-filter.c

@@ -182,7 +182,10 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent)
 {
 {
 	struct event_filter *filter;
 	struct event_filter *filter;
 
 
-	filter = malloc_or_die(sizeof(*filter));
+	filter = malloc(sizeof(*filter));
+	if (filter == NULL)
+		return NULL;
+
 	memset(filter, 0, sizeof(*filter));
 	memset(filter, 0, sizeof(*filter));
 	filter->pevent = pevent;
 	filter->pevent = pevent;
 	pevent_ref(pevent);
 	pevent_ref(pevent);
@@ -242,15 +245,19 @@ static void free_arg(struct filter_arg *arg)
 	free(arg);
 	free(arg);
 }
 }
 
 
-static void add_event(struct event_list **events,
+static int add_event(struct event_list **events,
 		      struct event_format *event)
 		      struct event_format *event)
 {
 {
 	struct event_list *list;
 	struct event_list *list;
 
 
-	list = malloc_or_die(sizeof(*list));
+	list = malloc(sizeof(*list));
+	if (list == NULL)
+		return -1;
+
 	list->next = *events;
 	list->next = *events;
 	*events = list;
 	*events = list;
 	list->event = event;
 	list->event = event;
+	return 0;
 }
 }
 
 
 static int event_match(struct event_format *event,
 static int event_match(struct event_format *event,
@@ -273,6 +280,7 @@ find_event(struct pevent *pevent, struct event_list **events,
 	regex_t ereg;
 	regex_t ereg;
 	regex_t sreg;
 	regex_t sreg;
 	int match = 0;
 	int match = 0;
+	int fail = 0;
 	char *reg;
 	char *reg;
 	int ret;
 	int ret;
 	int i;
 	int i;
@@ -307,7 +315,10 @@ find_event(struct pevent *pevent, struct event_list **events,
 		event = pevent->events[i];
 		event = pevent->events[i];
 		if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
 		if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
 			match = 1;
 			match = 1;
-			add_event(events, event);
+			if (add_event(events, event) < 0) {
+				fail = 1;
+				break;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -317,6 +328,8 @@ find_event(struct pevent *pevent, struct event_list **events,
 
 
 	if (!match)
 	if (!match)
 		return -1;
 		return -1;
+	if (fail)
+		return -2;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -349,8 +362,11 @@ create_arg_item(struct event_format *event, const char *token,
 		arg->value.type =
 		arg->value.type =
 			type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
 			type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
 		arg->value.str = strdup(token);
 		arg->value.str = strdup(token);
-		if (!arg->value.str)
-			die("malloc string");
+		if (!arg->value.str) {
+			free_arg(arg);
+			show_error(error_str, "failed to allocate string filter arg");
+			return NULL;
+		}
 		break;
 		break;
 	case EVENT_ITEM:
 	case EVENT_ITEM:
 		/* if it is a number, then convert it */
 		/* if it is a number, then convert it */
@@ -1210,7 +1226,13 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
 		else
 		else
 			len = strlen(filter_str);
 			len = strlen(filter_str);
 
 
-		this_event = malloc_or_die(len + 1);
+		this_event = malloc(len + 1);
+		if (this_event == NULL) {
+			show_error(error_str, "Memory allocation failure");
+			/* This can only happen when events is NULL, but still */
+			free_events(events);
+			return -1;
+		}
 		memcpy(this_event, filter_str, len);
 		memcpy(this_event, filter_str, len);
 		this_event[len] = 0;
 		this_event[len] = 0;
 
 
@@ -1482,8 +1504,10 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source
  * @type: remove only true, false, or both
  * @type: remove only true, false, or both
  *
  *
  * Removes filters that only contain a TRUE or FALES boolean arg.
  * Removes filters that only contain a TRUE or FALES boolean arg.
+ *
+ * Returns 0 on success and -1 if there was a problem.
  */
  */
-void pevent_filter_clear_trivial(struct event_filter *filter,
+int pevent_filter_clear_trivial(struct event_filter *filter,
 				 enum filter_trivial_type type)
 				 enum filter_trivial_type type)
 {
 {
 	struct filter_type *filter_type;
 	struct filter_type *filter_type;
@@ -1492,13 +1516,15 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
 	int i;
 	int i;
 
 
 	if (!filter->filters)
 	if (!filter->filters)
-		return;
+		return 0;
 
 
 	/*
 	/*
 	 * Two steps, first get all ids with trivial filters.
 	 * Two steps, first get all ids with trivial filters.
 	 *  then remove those ids.
 	 *  then remove those ids.
 	 */
 	 */
 	for (i = 0; i < filter->filters; i++) {
 	for (i = 0; i < filter->filters; i++) {
+		int *new_ids;
+
 		filter_type = &filter->event_filters[i];
 		filter_type = &filter->event_filters[i];
 		if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
 		if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
 			continue;
 			continue;
@@ -1513,19 +1539,24 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
 			break;
 			break;
 		}
 		}
 
 
-		ids = realloc(ids, sizeof(*ids) * (count + 1));
-		if (!ids)
-			die("Can't allocate ids");
+		new_ids = realloc(ids, sizeof(*ids) * (count + 1));
+		if (!new_ids) {
+			free(ids);
+			return -1;
+		}
+
+		ids = new_ids;
 		ids[count++] = filter_type->event_id;
 		ids[count++] = filter_type->event_id;
 	}
 	}
 
 
 	if (!count)
 	if (!count)
-		return;
+		return 0;
 
 
 	for (i = 0; i < count; i++)
 	for (i = 0; i < count; i++)
 		pevent_filter_remove_event(filter, ids[i]);
 		pevent_filter_remove_event(filter, ids[i]);
 
 
 	free(ids);
 	free(ids);
+	return 0;
 }
 }
 
 
 /**
 /**

+ 3 - 3
tools/perf/Documentation/perf-archive.txt

@@ -12,9 +12,9 @@ SYNOPSIS
 
 
 DESCRIPTION
 DESCRIPTION
 -----------
 -----------
-This command runs runs perf-buildid-list --with-hits, and collects the files
-with the buildids found so that analysis of perf.data contents can be possible
-on another machine.
+This command runs perf-buildid-list --with-hits, and collects the files with the
+buildids found so that analysis of perf.data contents can be possible on another
+machine.
 
 
 
 
 SEE ALSO
 SEE ALSO

+ 5 - 2
tools/perf/Documentation/perf-kvm.txt

@@ -10,9 +10,9 @@ SYNOPSIS
 [verse]
 [verse]
 'perf kvm' [--host] [--guest] [--guestmount=<path>
 'perf kvm' [--host] [--guest] [--guestmount=<path>
 	[--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
 	[--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
-	{top|record|report|diff|buildid-list}
+	{top|record|report|diff|buildid-list} [<options>]
 'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
 'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
-	| --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat}
+	| --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat} [<options>]
 'perf kvm stat [record|report|live] [<options>]
 'perf kvm stat [record|report|live] [<options>]
 
 
 DESCRIPTION
 DESCRIPTION
@@ -93,6 +93,9 @@ OPTIONS
 	kernel module information. Users copy it out from guest os.
 	kernel module information. Users copy it out from guest os.
 --guestvmlinux=<path>::
 --guestvmlinux=<path>::
 	Guest os kernel vmlinux.
 	Guest os kernel vmlinux.
+-v::
+--verbose::
+	Be more verbose (show counter open errors, etc).
 
 
 STAT REPORT OPTIONS
 STAT REPORT OPTIONS
 -------------------
 -------------------

+ 9 - 0
tools/perf/Documentation/perf-report.txt

@@ -237,6 +237,15 @@ OPTIONS
 	Do not show entries which have an overhead under that percent.
 	Do not show entries which have an overhead under that percent.
 	(Default: 0).
 	(Default: 0).
 
 
+--header::
+	Show header information in the perf.data file.  This includes
+	various information like hostname, OS and perf version, cpu/mem
+	info, perf command line, event list and so on.  Currently only
+	--stdio output supports this feature.
+
+--header-only::
+	Show only perf.data header (forces --stdio).
+
 SEE ALSO
 SEE ALSO
 --------
 --------
 linkperf:perf-stat[1], linkperf:perf-annotate[1]
 linkperf:perf-stat[1], linkperf:perf-annotate[1]

+ 7 - 1
tools/perf/Documentation/perf-script.txt

@@ -115,7 +115,7 @@ OPTIONS
 -f::
 -f::
 --fields::
 --fields::
         Comma separated list of fields to print. Options are:
         Comma separated list of fields to print. Options are:
-        comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff.
+        comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline.
         Field list can be prepended with the type, trace, sw or hw,
         Field list can be prepended with the type, trace, sw or hw,
         to indicate to which event type the field list applies.
         to indicate to which event type the field list applies.
         e.g., -f sw:comm,tid,time,ip,sym  and -f trace:time,cpu,trace
         e.g., -f sw:comm,tid,time,ip,sym  and -f trace:time,cpu,trace
@@ -209,6 +209,12 @@ OPTIONS
 --show-mmap-events
 --show-mmap-events
 	Display mmap related events (e.g. MMAP, MMAP2).
 	Display mmap related events (e.g. MMAP, MMAP2).
 
 
+--header
+	Show perf.data header.
+
+--header-only
+	Show only perf.data header.
+
 SEE ALSO
 SEE ALSO
 --------
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
 linkperf:perf-record[1], linkperf:perf-script-perl[1],

+ 1 - 1
tools/perf/builtin-annotate.c

@@ -373,7 +373,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
 
 
 	if (argc) {
 	if (argc) {
 		/*
 		/*
-		 * Special case: if there's an argument left then assume tha
+		 * Special case: if there's an argument left then assume that
 		 * it's a symbol filter:
 		 * it's a symbol filter:
 		 */
 		 */
 		if (argc > 1)
 		if (argc > 1)

+ 1 - 2
tools/perf/builtin-diff.c

@@ -1000,8 +1000,7 @@ static int data_init(int argc, const char **argv)
 			data__files_cnt = argc;
 			data__files_cnt = argc;
 			use_default = false;
 			use_default = false;
 		}
 		}
-	} else if (symbol_conf.default_guest_vmlinux_name ||
-		   symbol_conf.default_guest_kallsyms) {
+	} else if (perf_guest) {
 		defaults[0] = "perf.data.host";
 		defaults[0] = "perf.data.host";
 		defaults[1] = "perf.data.guest";
 		defaults[1] = "perf.data.guest";
 	}
 	}

+ 4 - 7
tools/perf/builtin-kvm.c

@@ -1232,7 +1232,7 @@ static int read_events(struct perf_kvm_stat *kvm)
 		.ordered_samples	= true,
 		.ordered_samples	= true,
 	};
 	};
 	struct perf_data_file file = {
 	struct perf_data_file file = {
-		.path = input_name,
+		.path = kvm->file_name,
 		.mode = PERF_DATA_MODE_READ,
 		.mode = PERF_DATA_MODE_READ,
 	};
 	};
 
 
@@ -1690,6 +1690,8 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
 			   "file", "file saving guest os /proc/kallsyms"),
 			   "file", "file saving guest os /proc/kallsyms"),
 		OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
 		OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
 			   "file", "file saving guest os /proc/modules"),
 			   "file", "file saving guest os /proc/modules"),
+		OPT_INCR('v', "verbose", &verbose,
+			    "be more verbose (show counter open errors, etc)"),
 		OPT_END()
 		OPT_END()
 	};
 	};
 
 
@@ -1711,12 +1713,7 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
 		perf_guest = 1;
 		perf_guest = 1;
 
 
 	if (!file_name) {
 	if (!file_name) {
-		if (perf_host && !perf_guest)
-			file_name = strdup("perf.data.host");
-		else if (!perf_host && perf_guest)
-			file_name = strdup("perf.data.guest");
-		else
-			file_name = strdup("perf.data.kvm");
+		file_name = get_filename_for_perf_kvm();
 
 
 		if (!file_name) {
 		if (!file_name) {
 			pr_err("Failed to allocate memory for filename\n");
 			pr_err("Failed to allocate memory for filename\n");

+ 1 - 1
tools/perf/builtin-record.c

@@ -224,7 +224,7 @@ try_again:
 			       "Consider increasing "
 			       "Consider increasing "
 			       "/proc/sys/kernel/perf_event_mlock_kb,\n"
 			       "/proc/sys/kernel/perf_event_mlock_kb,\n"
 			       "or try again with a smaller value of -m/--mmap_pages.\n"
 			       "or try again with a smaller value of -m/--mmap_pages.\n"
-			       "(current value: %d)\n", opts->mmap_pages);
+			       "(current value: %u)\n", opts->mmap_pages);
 			rc = -errno;
 			rc = -errno;
 		} else {
 		} else {
 			pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
 			pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));

+ 19 - 3
tools/perf/builtin-report.c

@@ -49,6 +49,8 @@ struct perf_report {
 	bool			show_threads;
 	bool			show_threads;
 	bool			inverted_callchain;
 	bool			inverted_callchain;
 	bool			mem_mode;
 	bool			mem_mode;
+	bool			header;
+	bool			header_only;
 	int			max_stack;
 	int			max_stack;
 	struct perf_read_values	show_threads_values;
 	struct perf_read_values	show_threads_values;
 	const char		*pretty_printing_style;
 	const char		*pretty_printing_style;
@@ -514,9 +516,6 @@ static int __cmd_report(struct perf_report *rep)
 			return ret;
 			return ret;
 	}
 	}
 
 
-	if (use_browser <= 0)
-		perf_session__fprintf_info(session, stdout, rep->show_full_info);
-
 	if (rep->show_threads)
 	if (rep->show_threads)
 		perf_read_values_init(&rep->show_threads_values);
 		perf_read_values_init(&rep->show_threads_values);
 
 
@@ -820,6 +819,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
 	OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
 	OPT_BOOLEAN(0, "stdio", &report.use_stdio,
 	OPT_BOOLEAN(0, "stdio", &report.use_stdio,
 		    "Use the stdio interface"),
 		    "Use the stdio interface"),
+	OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
+	OPT_BOOLEAN(0, "header-only", &report.header_only,
+		    "Show only data header."),
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
 		   "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
 		   " dso_to, dso_from, symbol_to, symbol_from, mispredict,"
 		   " dso_to, dso_from, symbol_to, symbol_from, mispredict,"
@@ -963,6 +965,10 @@ repeat:
 			goto error;
 			goto error;
 	}
 	}
 
 
+	/* Force tty output for header output. */
+	if (report.header || report.header_only)
+		use_browser = 0;
+
 	if (strcmp(input_name, "-") != 0)
 	if (strcmp(input_name, "-") != 0)
 		setup_browser(true);
 		setup_browser(true);
 	else {
 	else {
@@ -970,6 +976,16 @@ repeat:
 		perf_hpp__init();
 		perf_hpp__init();
 	}
 	}
 
 
+	if (report.header || report.header_only) {
+		perf_session__fprintf_info(session, stdout,
+					   report.show_full_info);
+		if (report.header_only)
+			return 0;
+	} else if (use_browser == 0) {
+		fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
+		      stdout);
+	}
+
 	/*
 	/*
 	 * Only in the TUI browser we are doing integrated annotation,
 	 * Only in the TUI browser we are doing integrated annotation,
 	 * so don't allocate extra space that won't be used in the stdio
 	 * so don't allocate extra space that won't be used in the stdio

+ 20 - 3
tools/perf/builtin-script.c

@@ -43,6 +43,7 @@ enum perf_output_field {
 	PERF_OUTPUT_DSO             = 1U << 9,
 	PERF_OUTPUT_DSO             = 1U << 9,
 	PERF_OUTPUT_ADDR            = 1U << 10,
 	PERF_OUTPUT_ADDR            = 1U << 10,
 	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
 	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
+	PERF_OUTPUT_SRCLINE         = 1U << 12,
 };
 };
 
 
 struct output_option {
 struct output_option {
@@ -61,6 +62,7 @@ struct output_option {
 	{.str = "dso",   .field = PERF_OUTPUT_DSO},
 	{.str = "dso",   .field = PERF_OUTPUT_DSO},
 	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
 	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
 	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
 	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
+	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
 };
 };
 
 
 /* default set to maintain compatibility with current format */
 /* default set to maintain compatibility with current format */
@@ -210,6 +212,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
 		       "to DSO.\n");
 		       "to DSO.\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
+	if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
+		pr_err("Display of source line number requested but sample IP is not\n"
+		       "selected. Hence, no address to lookup the source line number.\n");
+		return -EINVAL;
+	}
 
 
 	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
 	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
 		perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
 		perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
@@ -245,6 +252,9 @@ static void set_print_ip_opts(struct perf_event_attr *attr)
 
 
 	if (PRINT_FIELD(SYMOFFSET))
 	if (PRINT_FIELD(SYMOFFSET))
 		output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
 		output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
+
+	if (PRINT_FIELD(SRCLINE))
+		output[type].print_ip_opts |= PRINT_IP_OPT_SRCLINE;
 }
 }
 
 
 /*
 /*
@@ -1484,6 +1494,8 @@ static int have_cmd(int argc, const char **argv)
 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 {
 	bool show_full_info = false;
 	bool show_full_info = false;
+	bool header = false;
+	bool header_only = false;
 	char *rec_script_path = NULL;
 	char *rec_script_path = NULL;
 	char *rep_script_path = NULL;
 	char *rep_script_path = NULL;
 	struct perf_session *session;
 	struct perf_session *session;
@@ -1522,6 +1534,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
 	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
 	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
 		   "do various checks like samples ordering and lost events"),
 		   "do various checks like samples ordering and lost events"),
+	OPT_BOOLEAN(0, "header", &header, "Show data header."),
+	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
 	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
 	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
 		   "file", "vmlinux pathname"),
 		   "file", "vmlinux pathname"),
 	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
 	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)
 	if (session == NULL)
 	if (session == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+	if (header || header_only) {
+		perf_session__fprintf_info(session, stdout, show_full_info);
+		if (header_only)
+			return 0;
+	}
+
 	script.session = session;
 	script.session = session;
 
 
 	if (cpu_list) {
 	if (cpu_list) {
@@ -1745,9 +1765,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 			return -1;
 			return -1;
 	}
 	}
 
 
-	if (!script_name && !generate_script_lang)
-		perf_session__fprintf_info(session, stdout, show_full_info);
-
 	if (!no_callchain)
 	if (!no_callchain)
 		symbol_conf.use_callchain = true;
 		symbol_conf.use_callchain = true;
 	else
 	else

+ 29 - 3
tools/perf/builtin-trace.c

@@ -12,6 +12,7 @@
 #include "util/thread_map.h"
 #include "util/thread_map.h"
 #include "util/stat.h"
 #include "util/stat.h"
 #include "trace-event.h"
 #include "trace-event.h"
+#include "util/parse-events.h"
 
 
 #include <libaudit.h>
 #include <libaudit.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -173,6 +174,10 @@ static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void
 {
 {
 	struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
 	struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
 
 
+	/* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */
+	if (evsel == NULL)
+		evsel = perf_evsel__newtp("syscalls", direction);
+
 	if (evsel) {
 	if (evsel) {
 		if (perf_evsel__init_syscall_tp(evsel, handler))
 		if (perf_evsel__init_syscall_tp(evsel, handler))
 			goto out_delete;
 			goto out_delete;
@@ -1765,8 +1770,10 @@ static int trace__process_sample(struct perf_tool *tool,
 	if (!trace->full_time && trace->base_time == 0)
 	if (!trace->full_time && trace->base_time == 0)
 		trace->base_time = sample->time;
 		trace->base_time = sample->time;
 
 
-	if (handler)
+	if (handler) {
+		++trace->nr_events;
 		handler(trace, evsel, sample);
 		handler(trace, evsel, sample);
+	}
 
 
 	return err;
 	return err;
 }
 }
@@ -1801,10 +1808,11 @@ static int trace__record(int argc, const char **argv)
 		"-R",
 		"-R",
 		"-m", "1024",
 		"-m", "1024",
 		"-c", "1",
 		"-c", "1",
-		"-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit",
+		"-e",
 	};
 	};
 
 
-	rec_argc = ARRAY_SIZE(record_args) + argc;
+	/* +1 is for the event string below */
+	rec_argc = ARRAY_SIZE(record_args) + 1 + argc;
 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
 
 
 	if (rec_argv == NULL)
 	if (rec_argv == NULL)
@@ -1813,6 +1821,17 @@ static int trace__record(int argc, const char **argv)
 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
 		rec_argv[i] = record_args[i];
 		rec_argv[i] = record_args[i];
 
 
+	/* event string may be different for older kernels - e.g., RHEL6 */
+	if (is_valid_tracepoint("raw_syscalls:sys_enter"))
+		rec_argv[i] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit";
+	else if (is_valid_tracepoint("syscalls:sys_enter"))
+		rec_argv[i] = "syscalls:sys_enter,syscalls:sys_exit";
+	else {
+		pr_err("Neither raw_syscalls nor syscalls events exist.\n");
+		return -1;
+	}
+	i++;
+
 	for (j = 0; j < (unsigned int)argc; j++, i++)
 	for (j = 0; j < (unsigned int)argc; j++, i++)
 		rec_argv[i] = argv[j];
 		rec_argv[i] = argv[j];
 
 
@@ -2048,6 +2067,10 @@ static int trace__replay(struct trace *trace)
 
 
 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
 						     "raw_syscalls:sys_enter");
 						     "raw_syscalls:sys_enter");
+	/* older kernels have syscalls tp versus raw_syscalls */
+	if (evsel == NULL)
+		evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
+							     "syscalls:sys_enter");
 	if (evsel == NULL) {
 	if (evsel == NULL) {
 		pr_err("Data file does not have raw_syscalls:sys_enter event\n");
 		pr_err("Data file does not have raw_syscalls:sys_enter event\n");
 		goto out;
 		goto out;
@@ -2061,6 +2084,9 @@ static int trace__replay(struct trace *trace)
 
 
 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
 						     "raw_syscalls:sys_exit");
 						     "raw_syscalls:sys_exit");
+	if (evsel == NULL)
+		evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
+							     "syscalls:sys_exit");
 	if (evsel == NULL) {
 	if (evsel == NULL) {
 		pr_err("Data file does not have raw_syscalls:sys_exit event\n");
 		pr_err("Data file does not have raw_syscalls:sys_exit event\n");
 		goto out;
 		goto out;

+ 30 - 22
tools/perf/config/Makefile

@@ -36,6 +36,30 @@ ifeq ($(ARCH),arm)
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
 endif
 endif
 
 
+ifeq ($(LIBUNWIND_LIBS),)
+  NO_LIBUNWIND := 1
+else
+  #
+  # For linking with debug library, run like:
+  #
+  #   make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+  #
+  ifdef LIBUNWIND_DIR
+    LIBUNWIND_CFLAGS  = -I$(LIBUNWIND_DIR)/include
+    LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib
+  endif
+  LIBUNWIND_LDFLAGS += $(LIBUNWIND_LIBS)
+
+  # Set per-feature check compilation flags
+  FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS)
+  FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS)
+  FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS)
+  FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS)
+  #  and the flags for the test-all case
+  FEATURE_CHECK_CFLAGS-all += $(LIBUNWIND_CFLAGS)
+  FEATURE_CHECK_LDFLAGS-all += $(LIBUNWIND_LDFLAGS)
+endif
+
 ifeq ($(NO_PERF_REGS),0)
 ifeq ($(NO_PERF_REGS),0)
   CFLAGS += -DHAVE_PERF_REGS_SUPPORT
   CFLAGS += -DHAVE_PERF_REGS_SUPPORT
 endif
 endif
@@ -102,7 +126,7 @@ endif
 
 
 feature_check = $(eval $(feature_check_code))
 feature_check = $(eval $(feature_check_code))
 define feature_check_code
 define feature_check_code
-  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)
+  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)
 endef
 endef
 
 
 feature_set = $(eval $(feature_set_code))
 feature_set = $(eval $(feature_set_code))
@@ -305,21 +329,7 @@ ifndef NO_LIBELF
   endif # NO_DWARF
   endif # NO_DWARF
 endif # NO_LIBELF
 endif # NO_LIBELF
 
 
-ifeq ($(LIBUNWIND_LIBS),)
-  NO_LIBUNWIND := 1
-endif
-
 ifndef NO_LIBUNWIND
 ifndef NO_LIBUNWIND
-  #
-  # For linking with debug library, run like:
-  #
-  #   make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
-  #
-  ifdef LIBUNWIND_DIR
-    LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
-    LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
-  endif
-
   ifneq ($(feature-libunwind), 1)
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
     msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
     NO_LIBUNWIND := 1
     NO_LIBUNWIND := 1
@@ -334,14 +344,12 @@ ifndef NO_LIBUNWIND
       # non-ARM has no dwarf_find_debug_frame() function:
       # non-ARM has no dwarf_find_debug_frame() function:
       CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
       CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
     endif
     endif
-  endif
-endif
 
 
-ifndef NO_LIBUNWIND
-  CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
-  EXTLIBS += $(LIBUNWIND_LIBS)
-  CFLAGS += $(LIBUNWIND_CFLAGS)
-  LDFLAGS += $(LIBUNWIND_LDFLAGS)
+    CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
+    EXTLIBS += $(LIBUNWIND_LIBS)
+    CFLAGS += $(LIBUNWIND_CFLAGS)
+    LDFLAGS += $(LIBUNWIND_LDFLAGS)
+  endif # ifneq ($(feature-libunwind), 1)
 endif
 endif
 
 
 ifndef NO_LIBAUDIT
 ifndef NO_LIBAUDIT

+ 4 - 4
tools/perf/config/feature-checks/Makefile

@@ -32,12 +32,12 @@ CC := $(CC) -MD
 
 
 all: $(FILES)
 all: $(FILES)
 
 
-BUILD = $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT)$@ $@.c
+BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS)
 
 
 ###############################
 ###############################
 
 
 test-all:
 test-all:
-	$(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
+	$(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
 
 
 test-hello:
 test-hello:
 	$(BUILD)
 	$(BUILD)
@@ -70,10 +70,10 @@ test-libnuma:
 	$(BUILD) -lnuma
 	$(BUILD) -lnuma
 
 
 test-libunwind:
 test-libunwind:
-	$(BUILD) $(LIBUNWIND_LIBS) -lelf
+	$(BUILD) -lelf
 
 
 test-libunwind-debug-frame:
 test-libunwind-debug-frame:
-	$(BUILD) $(LIBUNWIND_LIBS) -lelf
+	$(BUILD) -lelf
 
 
 test-libaudit:
 test-libaudit:
 	$(BUILD) -laudit
 	$(BUILD) -laudit

+ 1 - 1
tools/perf/util/annotate.c

@@ -900,7 +900,7 @@ fallback:
 		 * cache, or is just a kallsyms file, well, lets hope that this
 		 * cache, or is just a kallsyms file, well, lets hope that this
 		 * DSO is the same as when 'perf record' ran.
 		 * DSO is the same as when 'perf record' ran.
 		 */
 		 */
-		filename = dso->long_name;
+		filename = (char *)dso->long_name;
 		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
 		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
 			 symbol_conf.symfs, filename);
 			 symbol_conf.symfs, filename);
 		free_filename = false;
 		free_filename = false;

+ 1 - 1
tools/perf/util/build-id.c

@@ -89,7 +89,7 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
 	return raw - build_id;
 	return raw - build_id;
 }
 }
 
 
-char *dso__build_id_filename(struct dso *dso, char *bf, size_t size)
+char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
 {
 {
 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 
 

+ 1 - 1
tools/perf/util/build-id.h

@@ -10,7 +10,7 @@ extern struct perf_tool build_id__mark_dso_hit_ops;
 struct dso;
 struct dso;
 
 
 int build_id__sprintf(const u8 *build_id, int len, char *bf);
 int build_id__sprintf(const u8 *build_id, int len, char *bf);
-char *dso__build_id_filename(struct dso *dso, char *bf, size_t size);
+char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
 
 
 int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
 int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
 			   struct perf_sample *sample, struct perf_evsel *evsel,
 			   struct perf_sample *sample, struct perf_evsel *evsel,

+ 76 - 36
tools/perf/util/dso.c

@@ -28,8 +28,8 @@ char dso__symtab_origin(const struct dso *dso)
 	return origin[dso->symtab_type];
 	return origin[dso->symtab_type];
 }
 }
 
 
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
-			  char *root_dir, char *file, size_t size)
+int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
+			  char *root_dir, char *filename, size_t size)
 {
 {
 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 	int ret = 0;
 	int ret = 0;
@@ -38,36 +38,36 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
 	case DSO_BINARY_TYPE__DEBUGLINK: {
 	case DSO_BINARY_TYPE__DEBUGLINK: {
 		char *debuglink;
 		char *debuglink;
 
 
-		strncpy(file, dso->long_name, size);
-		debuglink = file + dso->long_name_len;
-		while (debuglink != file && *debuglink != '/')
+		strncpy(filename, dso->long_name, size);
+		debuglink = filename + dso->long_name_len;
+		while (debuglink != filename && *debuglink != '/')
 			debuglink--;
 			debuglink--;
 		if (*debuglink == '/')
 		if (*debuglink == '/')
 			debuglink++;
 			debuglink++;
 		filename__read_debuglink(dso->long_name, debuglink,
 		filename__read_debuglink(dso->long_name, debuglink,
-					 size - (debuglink - file));
+					 size - (debuglink - filename));
 		}
 		}
 		break;
 		break;
 	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
 	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
 		/* skip the locally configured cache if a symfs is given */
 		/* skip the locally configured cache if a symfs is given */
 		if (symbol_conf.symfs[0] ||
 		if (symbol_conf.symfs[0] ||
-		    (dso__build_id_filename(dso, file, size) == NULL))
+		    (dso__build_id_filename(dso, filename, size) == NULL))
 			ret = -1;
 			ret = -1;
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
-		snprintf(file, size, "%s/usr/lib/debug%s.debug",
+		snprintf(filename, size, "%s/usr/lib/debug%s.debug",
 			 symbol_conf.symfs, dso->long_name);
 			 symbol_conf.symfs, dso->long_name);
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
-		snprintf(file, size, "%s/usr/lib/debug%s",
+		snprintf(filename, size, "%s/usr/lib/debug%s",
 			 symbol_conf.symfs, dso->long_name);
 			 symbol_conf.symfs, dso->long_name);
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
 	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
 	{
 	{
-		char *last_slash;
+		const char *last_slash;
 		size_t len;
 		size_t len;
 		size_t dir_size;
 		size_t dir_size;
 
 
@@ -75,14 +75,14 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
 		while (last_slash != dso->long_name && *last_slash != '/')
 		while (last_slash != dso->long_name && *last_slash != '/')
 			last_slash--;
 			last_slash--;
 
 
-		len = scnprintf(file, size, "%s", symbol_conf.symfs);
+		len = scnprintf(filename, size, "%s", symbol_conf.symfs);
 		dir_size = last_slash - dso->long_name + 2;
 		dir_size = last_slash - dso->long_name + 2;
 		if (dir_size > (size - len)) {
 		if (dir_size > (size - len)) {
 			ret = -1;
 			ret = -1;
 			break;
 			break;
 		}
 		}
-		len += scnprintf(file + len, dir_size, "%s",  dso->long_name);
-		len += scnprintf(file + len , size - len, ".debug%s",
+		len += scnprintf(filename + len, dir_size, "%s",  dso->long_name);
+		len += scnprintf(filename + len , size - len, ".debug%s",
 								last_slash);
 								last_slash);
 		break;
 		break;
 	}
 	}
@@ -96,7 +96,7 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
 		build_id__sprintf(dso->build_id,
 		build_id__sprintf(dso->build_id,
 				  sizeof(dso->build_id),
 				  sizeof(dso->build_id),
 				  build_id_hex);
 				  build_id_hex);
-		snprintf(file, size,
+		snprintf(filename, size,
 			 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
 			 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
 			 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
 			 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
 		break;
 		break;
@@ -104,23 +104,23 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
 	case DSO_BINARY_TYPE__VMLINUX:
 	case DSO_BINARY_TYPE__VMLINUX:
 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
-		snprintf(file, size, "%s%s",
+		snprintf(filename, size, "%s%s",
 			 symbol_conf.symfs, dso->long_name);
 			 symbol_conf.symfs, dso->long_name);
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__GUEST_KMODULE:
 	case DSO_BINARY_TYPE__GUEST_KMODULE:
-		snprintf(file, size, "%s%s%s", symbol_conf.symfs,
+		snprintf(filename, size, "%s%s%s", symbol_conf.symfs,
 			 root_dir, dso->long_name);
 			 root_dir, dso->long_name);
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
-		snprintf(file, size, "%s%s", symbol_conf.symfs,
+		snprintf(filename, size, "%s%s", symbol_conf.symfs,
 			 dso->long_name);
 			 dso->long_name);
 		break;
 		break;
 
 
 	case DSO_BINARY_TYPE__KCORE:
 	case DSO_BINARY_TYPE__KCORE:
 	case DSO_BINARY_TYPE__GUEST_KCORE:
 	case DSO_BINARY_TYPE__GUEST_KCORE:
-		snprintf(file, size, "%s", dso->long_name);
+		snprintf(filename, size, "%s", dso->long_name);
 		break;
 		break;
 
 
 	default:
 	default:
@@ -200,11 +200,10 @@ dso_cache__free(struct rb_root *root)
 	}
 	}
 }
 }
 
 
-static struct dso_cache*
-dso_cache__find(struct rb_root *root, u64 offset)
+static struct dso_cache *dso_cache__find(const struct rb_root *root, u64 offset)
 {
 {
-	struct rb_node **p = &root->rb_node;
-	struct rb_node *parent = NULL;
+	struct rb_node * const *p = &root->rb_node;
+	const struct rb_node *parent = NULL;
 	struct dso_cache *cache;
 	struct dso_cache *cache;
 
 
 	while (*p != NULL) {
 	while (*p != NULL) {
@@ -379,32 +378,63 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
 	 * processing we had no idea this was the kernel dso.
 	 * processing we had no idea this was the kernel dso.
 	 */
 	 */
 	if (dso != NULL) {
 	if (dso != NULL) {
-		dso__set_short_name(dso, short_name);
+		dso__set_short_name(dso, short_name, false);
 		dso->kernel = dso_type;
 		dso->kernel = dso_type;
 	}
 	}
 
 
 	return dso;
 	return dso;
 }
 }
 
 
-void dso__set_long_name(struct dso *dso, char *name)
+void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
 {
 {
 	if (name == NULL)
 	if (name == NULL)
 		return;
 		return;
-	dso->long_name = name;
-	dso->long_name_len = strlen(name);
+
+	if (dso->long_name_allocated)
+		free((char *)dso->long_name);
+
+	dso->long_name		 = name;
+	dso->long_name_len	 = strlen(name);
+	dso->long_name_allocated = name_allocated;
 }
 }
 
 
-void dso__set_short_name(struct dso *dso, const char *name)
+void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
 {
 {
 	if (name == NULL)
 	if (name == NULL)
 		return;
 		return;
-	dso->short_name = name;
-	dso->short_name_len = strlen(name);
+
+	if (dso->short_name_allocated)
+		free((char *)dso->short_name);
+
+	dso->short_name		  = name;
+	dso->short_name_len	  = strlen(name);
+	dso->short_name_allocated = name_allocated;
 }
 }
 
 
 static void dso__set_basename(struct dso *dso)
 static void dso__set_basename(struct dso *dso)
 {
 {
-	dso__set_short_name(dso, basename(dso->long_name));
+       /*
+        * basename() may modify path buffer, so we must pass
+        * a copy.
+        */
+       char *base, *lname = strdup(dso->long_name);
+
+       if (!lname)
+               return;
+
+       /*
+        * basename() may return a pointer to internal
+        * storage which is reused in subsequent calls
+        * so copy the result.
+        */
+       base = strdup(basename(lname));
+
+       free(lname);
+
+       if (!base)
+               return;
+
+       dso__set_short_name(dso, base, true);
 }
 }
 
 
 int dso__name_len(const struct dso *dso)
 int dso__name_len(const struct dso *dso)
@@ -439,8 +469,8 @@ struct dso *dso__new(const char *name)
 	if (dso != NULL) {
 	if (dso != NULL) {
 		int i;
 		int i;
 		strcpy(dso->name, name);
 		strcpy(dso->name, name);
-		dso__set_long_name(dso, dso->name);
-		dso__set_short_name(dso, dso->name);
+		dso__set_long_name(dso, dso->name, false);
+		dso__set_short_name(dso, dso->name, false);
 		for (i = 0; i < MAP__NR_TYPES; ++i)
 		for (i = 0; i < MAP__NR_TYPES; ++i)
 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
 		dso->cache = RB_ROOT;
 		dso->cache = RB_ROOT;
@@ -465,13 +495,23 @@ void dso__delete(struct dso *dso)
 	int i;
 	int i;
 	for (i = 0; i < MAP__NR_TYPES; ++i)
 	for (i = 0; i < MAP__NR_TYPES; ++i)
 		symbols__delete(&dso->symbols[i]);
 		symbols__delete(&dso->symbols[i]);
-	if (dso->sname_alloc)
+
+	if (dso->short_name_allocated) {
 		free((char *)dso->short_name);
 		free((char *)dso->short_name);
-	if (dso->lname_alloc)
-		free(dso->long_name);
+		dso->short_name		  = NULL;
+		dso->short_name_allocated = false;
+	}
+
+	if (dso->long_name_allocated) {
+		free((char *)dso->long_name);
+		dso->long_name		 = NULL;
+		dso->long_name_allocated = false;
+	}
+
 	dso_cache__free(&dso->cache);
 	dso_cache__free(&dso->cache);
 	dso__free_a2l(dso);
 	dso__free_a2l(dso);
 	free(dso->symsrc_filename);
 	free(dso->symsrc_filename);
+	dso->symsrc_filename = NULL;
 	free(dso);
 	free(dso);
 }
 }
 
 
@@ -546,7 +586,7 @@ void dsos__add(struct list_head *head, struct dso *dso)
 	list_add_tail(&dso->node, head);
 	list_add_tail(&dso->node, head);
 }
 }
 
 
-struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
+struct dso *dsos__find(const struct list_head *head, const char *name, bool cmp_short)
 {
 {
 	struct dso *pos;
 	struct dso *pos;
 
 

+ 8 - 8
tools/perf/util/dso.h

@@ -89,14 +89,14 @@ struct dso {
 	u8		 has_srcline:1;
 	u8		 has_srcline:1;
 	u8		 hit:1;
 	u8		 hit:1;
 	u8		 annotate_warned:1;
 	u8		 annotate_warned:1;
-	u8		 sname_alloc:1;
-	u8		 lname_alloc:1;
+	u8		 short_name_allocated:1;
+	u8		 long_name_allocated:1;
 	u8		 sorted_by_name;
 	u8		 sorted_by_name;
 	u8		 loaded;
 	u8		 loaded;
 	u8		 rel;
 	u8		 rel;
 	u8		 build_id[BUILD_ID_SIZE];
 	u8		 build_id[BUILD_ID_SIZE];
 	const char	 *short_name;
 	const char	 *short_name;
-	char		 *long_name;
+	const char	 *long_name;
 	u16		 long_name_len;
 	u16		 long_name_len;
 	u16		 short_name_len;
 	u16		 short_name_len;
 	char		 name[0];
 	char		 name[0];
@@ -110,8 +110,8 @@ static inline void dso__set_loaded(struct dso *dso, enum map_type type)
 struct dso *dso__new(const char *name);
 struct dso *dso__new(const char *name);
 void dso__delete(struct dso *dso);
 void dso__delete(struct dso *dso);
 
 
-void dso__set_short_name(struct dso *dso, const char *name);
-void dso__set_long_name(struct dso *dso, char *name);
+void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated);
+void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated);
 
 
 int dso__name_len(const struct dso *dso);
 int dso__name_len(const struct dso *dso);
 
 
@@ -128,8 +128,8 @@ void dso__read_running_kernel_build_id(struct dso *dso,
 int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
 int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
 
 
 char dso__symtab_origin(const struct dso *dso);
 char dso__symtab_origin(const struct dso *dso);
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
-			  char *root_dir, char *file, size_t size);
+int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type,
+			  char *root_dir, char *filename, size_t size);
 
 
 int dso__data_fd(struct dso *dso, struct machine *machine);
 int dso__data_fd(struct dso *dso, struct machine *machine);
 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
 ssize_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,
 				const char *short_name, int dso_type);
 				const char *short_name, int dso_type);
 
 
 void dsos__add(struct list_head *head, struct dso *dso);
 void dsos__add(struct list_head *head, struct dso *dso);
-struct dso *dsos__find(struct list_head *head, const char *name,
+struct dso *dsos__find(const struct list_head *head, const char *name,
 		       bool cmp_short);
 		       bool cmp_short);
 struct dso *__dsos__findnew(struct list_head *head, const char *name);
 struct dso *__dsos__findnew(struct list_head *head, const char *name);
 bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
 bool __dsos__read_build_ids(struct list_head *head, bool with_hits);

+ 6 - 4
tools/perf/util/evlist.c

@@ -732,11 +732,13 @@ static long parse_pages_arg(const char *str, unsigned long min,
 			return -EINVAL;
 			return -EINVAL;
 	}
 	}
 
 
-	if ((pages == 0) && (min == 0)) {
+	if (pages == 0 && min == 0) {
 		/* leave number of pages at 0 */
 		/* leave number of pages at 0 */
-	} else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
+	} else if (!is_power_of_2(pages)) {
 		/* round pages up to next power of 2 */
 		/* round pages up to next power of 2 */
-		pages = next_pow2(pages);
+		pages = next_pow2_l(pages);
+		if (!pages)
+			return -EINVAL;
 		pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
 		pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
 			pages * page_size, pages);
 			pages * page_size, pages);
 	}
 	}
@@ -754,7 +756,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
 	unsigned long max = UINT_MAX;
 	unsigned long max = UINT_MAX;
 	long pages;
 	long pages;
 
 
-	if (max < SIZE_MAX / page_size)
+	if (max > SIZE_MAX / page_size)
 		max = SIZE_MAX / page_size;
 		max = SIZE_MAX / page_size;
 
 
 	pages = parse_pages_arg(str, 1, max);
 	pages = parse_pages_arg(str, 1, max);

+ 3 - 3
tools/perf/util/header.c

@@ -177,7 +177,7 @@ perf_header__set_cmdline(int argc, const char **argv)
 			continue;		\
 			continue;		\
 		else
 		else
 
 
-static int write_buildid(char *name, size_t name_len, u8 *build_id,
+static int write_buildid(const char *name, size_t name_len, u8 *build_id,
 			 pid_t pid, u16 misc, int fd)
 			 pid_t pid, u16 misc, int fd)
 {
 {
 	int err;
 	int err;
@@ -209,7 +209,7 @@ static int __dsos__write_buildid_table(struct list_head *head,
 
 
 	dsos__for_each_with_build_id(pos, head) {
 	dsos__for_each_with_build_id(pos, head) {
 		int err;
 		int err;
-		char  *name;
+		const char *name;
 		size_t name_len;
 		size_t name_len;
 
 
 		if (!pos->hit)
 		if (!pos->hit)
@@ -387,7 +387,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine,
 {
 {
 	bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
 	bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
 	bool is_vdso = is_vdso_map(dso->short_name);
 	bool is_vdso = is_vdso_map(dso->short_name);
-	char *name = dso->long_name;
+	const char *name = dso->long_name;
 	char nm[PATH_MAX];
 	char nm[PATH_MAX];
 
 
 	if (dso__is_kcore(dso)) {
 	if (dso__is_kcore(dso)) {

+ 2 - 4
tools/perf/util/machine.c

@@ -763,8 +763,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
 				ret = -1;
 				ret = -1;
 				goto out;
 				goto out;
 			}
 			}
-			dso__set_long_name(map->dso, long_name);
-			map->dso->lname_alloc = 1;
+			dso__set_long_name(map->dso, long_name, true);
 			dso__kernel_module_get_build_id(map->dso, "");
 			dso__kernel_module_get_build_id(map->dso, "");
 		}
 		}
 	}
 	}
@@ -935,8 +934,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
 		if (name == NULL)
 		if (name == NULL)
 			goto out_problem;
 			goto out_problem;
 
 
-		map->dso->short_name = name;
-		map->dso->sname_alloc = 1;
+		dso__set_short_name(map->dso, name, true);
 		map->end = map->start + event->mmap.len;
 		map->end = map->start + event->mmap.len;
 	} else if (is_kernel_mmap) {
 	} else if (is_kernel_mmap) {
 		const char *symbol_name = (event->mmap.filename +
 		const char *symbol_name = (event->mmap.filename +

+ 17 - 0
tools/perf/util/map.c

@@ -11,6 +11,7 @@
 #include "strlist.h"
 #include "strlist.h"
 #include "vdso.h"
 #include "vdso.h"
 #include "build-id.h"
 #include "build-id.h"
+#include "util.h"
 #include <linux/string.h>
 #include <linux/string.h>
 
 
 const char *map_type__name[MAP__NR_TYPES] = {
 const char *map_type__name[MAP__NR_TYPES] = {
@@ -252,6 +253,22 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
 	return fprintf(fp, "%s", dsoname);
 	return fprintf(fp, "%s", dsoname);
 }
 }
 
 
+int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
+			 FILE *fp)
+{
+	char *srcline;
+	int ret = 0;
+
+	if (map && map->dso) {
+		srcline = get_srcline(map->dso,
+				      map__rip_2objdump(map, addr));
+		if (srcline != SRCLINE_UNKNOWN)
+			ret = fprintf(fp, "%s%s", prefix, srcline);
+		free_srcline(srcline);
+	}
+	return ret;
+}
+
 /**
 /**
  * map__rip_2objdump - convert symbol start address to objdump address.
  * map__rip_2objdump - convert symbol start address to objdump address.
  * @map: memory map
  * @map: memory map

+ 2 - 0
tools/perf/util/map.h

@@ -103,6 +103,8 @@ struct map *map__clone(struct map *map);
 int map__overlap(struct map *l, struct map *r);
 int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *map, FILE *fp);
 size_t map__fprintf(struct map *map, FILE *fp);
 size_t map__fprintf_dsoname(struct map *map, FILE *fp);
 size_t map__fprintf_dsoname(struct map *map, FILE *fp);
+int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
+			 FILE *fp);
 
 
 int map__load(struct map *map, symbol_filter_t filter);
 int map__load(struct map *map, symbol_filter_t filter);
 struct symbol *map__find_symbol(struct map *map,
 struct symbol *map__find_symbol(struct map *map,

+ 1 - 1
tools/perf/util/probe-event.c

@@ -154,7 +154,7 @@ static struct dso *kernel_get_module_dso(const char *module)
 
 
 	vmlinux_name = symbol_conf.vmlinux_name;
 	vmlinux_name = symbol_conf.vmlinux_name;
 	if (vmlinux_name) {
 	if (vmlinux_name) {
-		if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
+		if (dso__load_vmlinux(dso, map, vmlinux_name, false, NULL) <= 0)
 			return NULL;
 			return NULL;
 	} else {
 	} else {
 		if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
 		if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {

+ 14 - 1
tools/perf/util/session.c

@@ -1497,6 +1497,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 	int print_dso = print_opts & PRINT_IP_OPT_DSO;
 	int print_dso = print_opts & PRINT_IP_OPT_DSO;
 	int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
 	int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
 	int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
 	int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
+	int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
 	char s = print_oneline ? ' ' : '\t';
 	char s = print_oneline ? ' ' : '\t';
 
 
 	if (symbol_conf.use_callchain && sample->callchain) {
 	if (symbol_conf.use_callchain && sample->callchain) {
@@ -1515,6 +1516,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			node_al = *al;
 			node_al = *al;
 
 
 		while (stack_depth) {
 		while (stack_depth) {
+			u64 addr = 0;
+
 			node = callchain_cursor_current(&callchain_cursor);
 			node = callchain_cursor_current(&callchain_cursor);
 			if (!node)
 			if (!node)
 				break;
 				break;
@@ -1525,10 +1528,13 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			if (print_ip)
 			if (print_ip)
 				printf("%c%16" PRIx64, s, node->ip);
 				printf("%c%16" PRIx64, s, node->ip);
 
 
+			if (node->map)
+				addr = node->map->map_ip(node->map, node->ip);
+
 			if (print_sym) {
 			if (print_sym) {
 				printf(" ");
 				printf(" ");
 				if (print_symoffset) {
 				if (print_symoffset) {
-					node_al.addr = node->ip;
+					node_al.addr = addr;
 					node_al.map  = node->map;
 					node_al.map  = node->map;
 					symbol__fprintf_symname_offs(node->sym, &node_al, stdout);
 					symbol__fprintf_symname_offs(node->sym, &node_al, stdout);
 				} else
 				} else
@@ -1541,6 +1547,10 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 				printf(")");
 				printf(")");
 			}
 			}
 
 
+			if (print_srcline)
+				map__fprintf_srcline(node->map, addr, "\n  ",
+						     stdout);
+
 			if (!print_oneline)
 			if (!print_oneline)
 				printf("\n");
 				printf("\n");
 
 
@@ -1570,6 +1580,9 @@ next:
 			map__fprintf_dsoname(al->map, stdout);
 			map__fprintf_dsoname(al->map, stdout);
 			printf(")");
 			printf(")");
 		}
 		}
+
+		if (print_srcline)
+			map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
 	}
 	}
 }
 }
 
 

+ 1 - 0
tools/perf/util/session.h

@@ -45,6 +45,7 @@ struct perf_session {
 #define PRINT_IP_OPT_DSO		(1<<2)
 #define PRINT_IP_OPT_DSO		(1<<2)
 #define PRINT_IP_OPT_SYMOFFSET	(1<<3)
 #define PRINT_IP_OPT_SYMOFFSET	(1<<3)
 #define PRINT_IP_OPT_ONELINE	(1<<4)
 #define PRINT_IP_OPT_ONELINE	(1<<4)
+#define PRINT_IP_OPT_SRCLINE	(1<<5)
 
 
 struct perf_tool;
 struct perf_tool;
 
 

+ 1 - 1
tools/perf/util/srcline.c

@@ -255,7 +255,7 @@ char *get_srcline(struct dso *dso, unsigned long addr)
 	char *file = NULL;
 	char *file = NULL;
 	unsigned line = 0;
 	unsigned line = 0;
 	char *srcline;
 	char *srcline;
-	char *dso_name;
+	const char *dso_name;
 
 
 	if (!dso->has_srcline)
 	if (!dso->has_srcline)
 		return SRCLINE_UNKNOWN;
 		return SRCLINE_UNKNOWN;

+ 14 - 24
tools/perf/util/symbol.c

@@ -1159,7 +1159,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 		dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
 		dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
 	else
 	else
 		dso->data_type = DSO_BINARY_TYPE__KCORE;
 		dso->data_type = DSO_BINARY_TYPE__KCORE;
-	dso__set_long_name(dso, strdup(kcore_filename));
+	dso__set_long_name(dso, strdup(kcore_filename), true);
 
 
 	close(fd);
 	close(fd);
 
 
@@ -1408,7 +1408,8 @@ struct map *map_groups__find_by_name(struct map_groups *mg,
 }
 }
 
 
 int dso__load_vmlinux(struct dso *dso, struct map *map,
 int dso__load_vmlinux(struct dso *dso, struct map *map,
-		      const char *vmlinux, symbol_filter_t filter)
+		      const char *vmlinux, bool vmlinux_allocated,
+		      symbol_filter_t filter)
 {
 {
 	int err = -1;
 	int err = -1;
 	struct symsrc ss;
 	struct symsrc ss;
@@ -1437,7 +1438,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
 			dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
 			dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
 		else
 		else
 			dso->data_type = DSO_BINARY_TYPE__VMLINUX;
 			dso->data_type = DSO_BINARY_TYPE__VMLINUX;
-		dso__set_long_name(dso, (char *)vmlinux);
+		dso__set_long_name(dso, vmlinux, vmlinux_allocated);
 		dso__set_loaded(dso, map->type);
 		dso__set_loaded(dso, map->type);
 		pr_debug("Using %s for symbols\n", symfs_vmlinux);
 		pr_debug("Using %s for symbols\n", symfs_vmlinux);
 	}
 	}
@@ -1456,21 +1457,16 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
 
 
 	filename = dso__build_id_filename(dso, NULL, 0);
 	filename = dso__build_id_filename(dso, NULL, 0);
 	if (filename != NULL) {
 	if (filename != NULL) {
-		err = dso__load_vmlinux(dso, map, filename, filter);
-		if (err > 0) {
-			dso->lname_alloc = 1;
+		err = dso__load_vmlinux(dso, map, filename, true, filter);
+		if (err > 0)
 			goto out;
 			goto out;
-		}
 		free(filename);
 		free(filename);
 	}
 	}
 
 
 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
-		err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
-		if (err > 0) {
-			dso__set_long_name(dso, strdup(vmlinux_path[i]));
-			dso->lname_alloc = 1;
+		err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
+		if (err > 0)
 			break;
 			break;
-		}
 	}
 	}
 out:
 out:
 	return err;
 	return err;
@@ -1607,15 +1603,8 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
 	}
 	}
 
 
 	if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
 	if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
-		err = dso__load_vmlinux(dso, map,
-					symbol_conf.vmlinux_name, filter);
-		if (err > 0) {
-			dso__set_long_name(dso,
-					   strdup(symbol_conf.vmlinux_name));
-			dso->lname_alloc = 1;
-			return err;
-		}
-		return err;
+		return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name,
+					 false, filter);
 	}
 	}
 
 
 	if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
 	if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
@@ -1641,7 +1630,7 @@ do_kallsyms:
 	free(kallsyms_allocated_filename);
 	free(kallsyms_allocated_filename);
 
 
 	if (err > 0 && !dso__is_kcore(dso)) {
 	if (err > 0 && !dso__is_kcore(dso)) {
-		dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
+		dso__set_long_name(dso, "[kernel.kallsyms]", false);
 		map__fixup_start(map);
 		map__fixup_start(map);
 		map__fixup_end(map);
 		map__fixup_end(map);
 	}
 	}
@@ -1671,7 +1660,8 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
 		 */
 		 */
 		if (symbol_conf.default_guest_vmlinux_name != NULL) {
 		if (symbol_conf.default_guest_vmlinux_name != NULL) {
 			err = dso__load_vmlinux(dso, map,
 			err = dso__load_vmlinux(dso, map,
-				symbol_conf.default_guest_vmlinux_name, filter);
+						symbol_conf.default_guest_vmlinux_name,
+						false, filter);
 			return err;
 			return err;
 		}
 		}
 
 
@@ -1688,7 +1678,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
 		pr_debug("Using %s for symbols\n", kallsyms_filename);
 		pr_debug("Using %s for symbols\n", kallsyms_filename);
 	if (err > 0 && !dso__is_kcore(dso)) {
 	if (err > 0 && !dso__is_kcore(dso)) {
 		machine__mmap_name(machine, path, sizeof(path));
 		machine__mmap_name(machine, path, sizeof(path));
-		dso__set_long_name(dso, strdup(path));
+		dso__set_long_name(dso, strdup(path), true);
 		map__fixup_start(map);
 		map__fixup_start(map);
 		map__fixup_end(map);
 		map__fixup_end(map);
 	}
 	}

+ 2 - 1
tools/perf/util/symbol.h

@@ -206,7 +206,8 @@ bool symsrc__possibly_runtime(struct symsrc *ss);
 
 
 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
 int dso__load_vmlinux(struct dso *dso, struct map *map,
 int dso__load_vmlinux(struct dso *dso, struct map *map,
-		      const char *vmlinux, symbol_filter_t filter);
+		      const char *vmlinux, bool vmlinux_allocated,
+		      symbol_filter_t filter);
 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
 			   symbol_filter_t filter);
 			   symbol_filter_t filter);
 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,

+ 14 - 0
tools/perf/util/util.c

@@ -482,3 +482,17 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep)
 	close(fd);
 	close(fd);
 	return err;
 	return err;
 }
 }
+
+const char *get_filename_for_perf_kvm(void)
+{
+	const char *filename;
+
+	if (perf_host && !perf_guest)
+		filename = strdup("perf.data.host");
+	else if (!perf_host && perf_guest)
+		filename = strdup("perf.data.guest");
+	else
+		filename = strdup("perf.data.kvm");
+
+	return filename;
+}

+ 14 - 0
tools/perf/util/util.h

@@ -73,6 +73,7 @@
 #include <sys/ttydefaults.h>
 #include <sys/ttydefaults.h>
 #include <lk/debugfs.h>
 #include <lk/debugfs.h>
 #include <termios.h>
 #include <termios.h>
+#include <linux/bitops.h>
 
 
 extern const char *graph_line;
 extern const char *graph_line;
 extern const char *graph_dotted_line;
 extern const char *graph_dotted_line;
@@ -281,6 +282,17 @@ static inline unsigned next_pow2(unsigned x)
 	return 1ULL << (32 - __builtin_clz(x - 1));
 	return 1ULL << (32 - __builtin_clz(x - 1));
 }
 }
 
 
+static inline unsigned long next_pow2_l(unsigned long x)
+{
+#if BITS_PER_LONG == 64
+	if (x <= (1UL << 31))
+		return next_pow2(x);
+	return (unsigned long)next_pow2(x >> 32) << 32;
+#else
+	return next_pow2(x);
+#endif
+}
+
 size_t hex_width(u64 v);
 size_t hex_width(u64 v);
 int hex2u64(const char *ptr, u64 *val);
 int hex2u64(const char *ptr, u64 *val);
 
 
@@ -309,4 +321,6 @@ void free_srcline(char *srcline);
 
 
 int filename__read_int(const char *filename, int *value);
 int filename__read_int(const char *filename, int *value);
 int filename__read_str(const char *filename, char **buf, size_t *sizep);
 int filename__read_str(const char *filename, char **buf, size_t *sizep);
+
+const char *get_filename_for_perf_kvm(void);
 #endif /* GIT_COMPAT_UTIL_H */
 #endif /* GIT_COMPAT_UTIL_H */

+ 1 - 1
tools/perf/util/vdso.c

@@ -103,7 +103,7 @@ struct dso *vdso__dso_findnew(struct list_head *head)
 		dso = dso__new(VDSO__MAP_NAME);
 		dso = dso__new(VDSO__MAP_NAME);
 		if (dso != NULL) {
 		if (dso != NULL) {
 			dsos__add(head, dso);
 			dsos__add(head, dso);
-			dso__set_long_name(dso, file);
+			dso__set_long_name(dso, file, false);
 		}
 		}
 	}
 	}