perf symbols: Add the build id cache to the vmlinux path

So that if the kernel DSO has a build id because record inserted it in
the perf.data build id table in the header, or a BUILD_ID event was
inserted in the stream, we first look at the build id cache
($HOME/.debug/).

If we find it there, try to use it, allowing offline annotation in
addition to 'perf report'.

Reported-by: Stephane Eranian <eranian@google.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index aaa51ba..7fd6b15 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1695,9 +1695,20 @@
 			   symbol_filter_t filter)
 {
 	int i, err = 0;
+	char *filename;
 
 	pr_debug("Looking at the vmlinux_path (%d entries long)\n",
-		 vmlinux_path__nr_entries);
+		 vmlinux_path__nr_entries + 1);
+
+	filename = dso__build_id_filename(self, NULL, 0);
+	if (filename != NULL) {
+		err = dso__load_vmlinux(self, map, filename, filter);
+		if (err > 0) {
+			dso__set_long_name(self, filename);
+			goto out;
+		}
+		free(filename);
+	}
 
 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
 		err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
@@ -1706,7 +1717,7 @@
 			break;
 		}
 	}
-
+out:
 	return err;
 }
 
@@ -2102,13 +2113,21 @@
 	return -1;
 }
 
-size_t vmlinux_path__fprintf(FILE *fp)
+size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp)
 {
 	int i;
 	size_t printed = 0;
+	struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso;
+
+	if (kdso->has_build_id) {
+		char filename[PATH_MAX];
+		if (dso__build_id_filename(kdso, filename, sizeof(filename)))
+			printed += fprintf(fp, "[0] %s\n", filename);
+	}
 
 	for (i = 0; i < vmlinux_path__nr_entries; ++i)
-		printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);
+		printed += fprintf(fp, "[%d] %s\n",
+				   i + kdso->has_build_id, vmlinux_path[i]);
 
 	return printed;
 }