perf symbols: Cache /proc/kallsyms files by build-id

So that when we don't have a vmlinux handy we can store the
kallsyms for later use by 'perf report'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1263501006-14185-3-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b31e0ae..1b65fed 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -237,11 +237,13 @@
 	char *filename = malloc(size),
 	     *linkname = malloc(size), *targetname, *sbuild_id;
 	int len, err = -1;
+	bool is_kallsyms = self->kernel && self->long_name[0] != '/';
 
 	if (filename == NULL || linkname == NULL)
 		goto out_free;
 
-	len = snprintf(filename, size, "%s%s", debugdir, self->long_name);
+	len = snprintf(filename, size, "%s%s%s",
+		       debugdir, is_kallsyms ? "/" : "", self->long_name);
 	if (mkdir_p(filename, 0755))
 		goto out_free;
 
@@ -249,9 +251,14 @@
 	sbuild_id = filename + len;
 	build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
 
-	if (access(filename, F_OK) && link(self->long_name, filename) &&
-	    copyfile(self->long_name, filename))
-		goto out_free;
+	if (access(filename, F_OK)) {
+		if (is_kallsyms) {
+			 if (copyfile("/proc/kallsyms", filename))
+				goto out_free;
+		} else if (link(self->long_name, filename) &&
+			   copyfile(self->long_name, filename))
+			goto out_free;
+	}
 
 	len = snprintf(linkname, size, "%s/.build-id/%.2s",
 		       debugdir, sbuild_id);