aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 39ce9adbaaf0..a9d758a3b371 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -627,7 +627,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
627 * kernel range is broken in several maps, named [kernel].N, as we don't have 627 * kernel range is broken in several maps, named [kernel].N, as we don't have
628 * the original ELF section names vmlinux have. 628 * the original ELF section names vmlinux have.
629 */ 629 */
630static int dso__split_kallsyms(struct dso *dso, struct map *map, 630static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta,
631 symbol_filter_t filter) 631 symbol_filter_t filter)
632{ 632{
633 struct map_groups *kmaps = map__kmap(map)->kmaps; 633 struct map_groups *kmaps = map__kmap(map)->kmaps;
@@ -692,6 +692,12 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map,
692 char dso_name[PATH_MAX]; 692 char dso_name[PATH_MAX];
693 struct dso *ndso; 693 struct dso *ndso;
694 694
695 if (delta) {
696 /* Kernel was relocated at boot time */
697 pos->start -= delta;
698 pos->end -= delta;
699 }
700
695 if (count == 0) { 701 if (count == 0) {
696 curr_map = map; 702 curr_map = map;
697 goto filter_symbol; 703 goto filter_symbol;
@@ -721,6 +727,10 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map,
721 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 727 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
722 map_groups__insert(kmaps, curr_map); 728 map_groups__insert(kmaps, curr_map);
723 ++kernel_range; 729 ++kernel_range;
730 } else if (delta) {
731 /* Kernel was relocated at boot time */
732 pos->start -= delta;
733 pos->end -= delta;
724 } 734 }
725filter_symbol: 735filter_symbol:
726 if (filter && filter(curr_map, pos)) { 736 if (filter && filter(curr_map, pos)) {
@@ -976,6 +986,23 @@ static int validate_kcore_modules(const char *kallsyms_filename,
976 return 0; 986 return 0;
977} 987}
978 988
989static int validate_kcore_addresses(const char *kallsyms_filename,
990 struct map *map)
991{
992 struct kmap *kmap = map__kmap(map);
993
994 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
995 u64 start;
996
997 start = kallsyms__get_function_start(kallsyms_filename,
998 kmap->ref_reloc_sym->name);
999 if (start != kmap->ref_reloc_sym->addr)
1000 return -EINVAL;
1001 }
1002
1003 return validate_kcore_modules(kallsyms_filename, map);
1004}
1005
979struct kcore_mapfn_data { 1006struct kcore_mapfn_data {
980 struct dso *dso; 1007 struct dso *dso;
981 enum map_type type; 1008 enum map_type type;
@@ -1019,8 +1046,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1019 kallsyms_filename)) 1046 kallsyms_filename))
1020 return -EINVAL; 1047 return -EINVAL;
1021 1048
1022 /* All modules must be present at their original addresses */ 1049 /* Modules and kernel must be present at their original addresses */
1023 if (validate_kcore_modules(kallsyms_filename, map)) 1050 if (validate_kcore_addresses(kallsyms_filename, map))
1024 return -EINVAL; 1051 return -EINVAL;
1025 1052
1026 md.dso = dso; 1053 md.dso = dso;
@@ -1113,15 +1140,41 @@ out_err:
1113 return -EINVAL; 1140 return -EINVAL;
1114} 1141}
1115 1142
1143/*
1144 * If the kernel is relocated at boot time, kallsyms won't match. Compute the
1145 * delta based on the relocation reference symbol.
1146 */
1147static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
1148{
1149 struct kmap *kmap = map__kmap(map);
1150 u64 addr;
1151
1152 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
1153 return 0;
1154
1155 addr = kallsyms__get_function_start(filename,
1156 kmap->ref_reloc_sym->name);
1157 if (!addr)
1158 return -1;
1159
1160 *delta = addr - kmap->ref_reloc_sym->addr;
1161 return 0;
1162}
1163
1116int dso__load_kallsyms(struct dso *dso, const char *filename, 1164int dso__load_kallsyms(struct dso *dso, const char *filename,
1117 struct map *map, symbol_filter_t filter) 1165 struct map *map, symbol_filter_t filter)
1118{ 1166{
1167 u64 delta = 0;
1168
1119 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 1169 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
1120 return -1; 1170 return -1;
1121 1171
1122 if (dso__load_all_kallsyms(dso, filename, map) < 0) 1172 if (dso__load_all_kallsyms(dso, filename, map) < 0)
1123 return -1; 1173 return -1;
1124 1174
1175 if (kallsyms__delta(map, filename, &delta))
1176 return -1;
1177
1125 symbols__fixup_duplicate(&dso->symbols[map->type]); 1178 symbols__fixup_duplicate(&dso->symbols[map->type]);
1126 symbols__fixup_end(&dso->symbols[map->type]); 1179 symbols__fixup_end(&dso->symbols[map->type]);
1127 1180
@@ -1133,7 +1186,7 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
1133 if (!dso__load_kcore(dso, map, filename)) 1186 if (!dso__load_kcore(dso, map, filename))
1134 return dso__split_kallsyms_for_kcore(dso, map, filter); 1187 return dso__split_kallsyms_for_kcore(dso, map, filter);
1135 else 1188 else
1136 return dso__split_kallsyms(dso, map, filter); 1189 return dso__split_kallsyms(dso, map, delta, filter);
1137} 1190}
1138 1191
1139static int dso__load_perf_map(struct dso *dso, struct map *map, 1192static int dso__load_perf_map(struct dso *dso, struct map *map,
@@ -1424,7 +1477,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1424 continue; 1477 continue;
1425 scnprintf(kallsyms_filename, sizeof(kallsyms_filename), 1478 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1426 "%s/%s/kallsyms", dir, dent->d_name); 1479 "%s/%s/kallsyms", dir, dent->d_name);
1427 if (!validate_kcore_modules(kallsyms_filename, map)) { 1480 if (!validate_kcore_addresses(kallsyms_filename, map)) {
1428 strlcpy(dir, kallsyms_filename, dir_sz); 1481 strlcpy(dir, kallsyms_filename, dir_sz);
1429 ret = 0; 1482 ret = 0;
1430 break; 1483 break;
@@ -1479,7 +1532,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1479 if (fd != -1) { 1532 if (fd != -1) {
1480 close(fd); 1533 close(fd);
1481 /* If module maps match go with /proc/kallsyms */ 1534 /* If module maps match go with /proc/kallsyms */
1482 if (!validate_kcore_modules("/proc/kallsyms", map)) 1535 if (!validate_kcore_addresses("/proc/kallsyms", map))
1483 goto proc_kallsyms; 1536 goto proc_kallsyms;
1484 } 1537 }
1485 1538