aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2014-01-29 09:14:41 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-01-31 15:21:51 -0500
commita00d28cb72d3629c6481fe21ba6c6b4f96caed49 (patch)
tree9e37aba781546006aafea081ee2cbcb3b9c2b893
parent0ae617bedde062003fd70e566e9a2601e273ea0e (diff)
perf symbols: Prevent the use of kcore if the kernel has moved
Use of kcore is predicated upon it matching the recorded data. If the kernel has been relocated at boot time (i.e. since the data was recorded) then do not use kcore. Note that it is possible to make a copy of kcore at the time the data is recorded using 'perf buildid-cache'. Then the perf tools will use the copy because it does match the data. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Tested-by: Jiri Olsa <jolsa@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1391004884-10334-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/symbol.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 39ce9adbaaf0..4ac1f871ec27 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -976,6 +976,23 @@ static int validate_kcore_modules(const char *kallsyms_filename,
976 return 0; 976 return 0;
977} 977}
978 978
979static int validate_kcore_addresses(const char *kallsyms_filename,
980 struct map *map)
981{
982 struct kmap *kmap = map__kmap(map);
983
984 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
985 u64 start;
986
987 start = kallsyms__get_function_start(kallsyms_filename,
988 kmap->ref_reloc_sym->name);
989 if (start != kmap->ref_reloc_sym->addr)
990 return -EINVAL;
991 }
992
993 return validate_kcore_modules(kallsyms_filename, map);
994}
995
979struct kcore_mapfn_data { 996struct kcore_mapfn_data {
980 struct dso *dso; 997 struct dso *dso;
981 enum map_type type; 998 enum map_type type;
@@ -1019,8 +1036,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1019 kallsyms_filename)) 1036 kallsyms_filename))
1020 return -EINVAL; 1037 return -EINVAL;
1021 1038
1022 /* All modules must be present at their original addresses */ 1039 /* Modules and kernel must be present at their original addresses */
1023 if (validate_kcore_modules(kallsyms_filename, map)) 1040 if (validate_kcore_addresses(kallsyms_filename, map))
1024 return -EINVAL; 1041 return -EINVAL;
1025 1042
1026 md.dso = dso; 1043 md.dso = dso;
@@ -1424,7 +1441,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1424 continue; 1441 continue;
1425 scnprintf(kallsyms_filename, sizeof(kallsyms_filename), 1442 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1426 "%s/%s/kallsyms", dir, dent->d_name); 1443 "%s/%s/kallsyms", dir, dent->d_name);
1427 if (!validate_kcore_modules(kallsyms_filename, map)) { 1444 if (!validate_kcore_addresses(kallsyms_filename, map)) {
1428 strlcpy(dir, kallsyms_filename, dir_sz); 1445 strlcpy(dir, kallsyms_filename, dir_sz);
1429 ret = 0; 1446 ret = 0;
1430 break; 1447 break;
@@ -1479,7 +1496,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1479 if (fd != -1) { 1496 if (fd != -1) {
1480 close(fd); 1497 close(fd);
1481 /* If module maps match go with /proc/kallsyms */ 1498 /* If module maps match go with /proc/kallsyms */
1482 if (!validate_kcore_modules("/proc/kallsyms", map)) 1499 if (!validate_kcore_addresses("/proc/kallsyms", map))
1483 goto proc_kallsyms; 1500 goto proc_kallsyms;
1484 } 1501 }
1485 1502