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.c449
1 files changed, 382 insertions, 67 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7eb0362f4ffd..c0c36965fff0 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -51,6 +51,7 @@ static enum dso_binary_type binary_type_symtab[] = {
51 DSO_BINARY_TYPE__SYSTEM_PATH_DSO, 51 DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
52 DSO_BINARY_TYPE__GUEST_KMODULE, 52 DSO_BINARY_TYPE__GUEST_KMODULE,
53 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, 53 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
54 DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
54 DSO_BINARY_TYPE__NOT_FOUND, 55 DSO_BINARY_TYPE__NOT_FOUND,
55}; 56};
56 57
@@ -159,10 +160,12 @@ again:
159 160
160 if (choose_best_symbol(curr, next) == SYMBOL_A) { 161 if (choose_best_symbol(curr, next) == SYMBOL_A) {
161 rb_erase(&next->rb_node, symbols); 162 rb_erase(&next->rb_node, symbols);
163 symbol__delete(next);
162 goto again; 164 goto again;
163 } else { 165 } else {
164 nd = rb_next(&curr->rb_node); 166 nd = rb_next(&curr->rb_node);
165 rb_erase(&curr->rb_node, symbols); 167 rb_erase(&curr->rb_node, symbols);
168 symbol__delete(curr);
166 } 169 }
167 } 170 }
168} 171}
@@ -499,6 +502,64 @@ out_failure:
499 return -1; 502 return -1;
500} 503}
501 504
505int modules__parse(const char *filename, void *arg,
506 int (*process_module)(void *arg, const char *name,
507 u64 start))
508{
509 char *line = NULL;
510 size_t n;
511 FILE *file;
512 int err = 0;
513
514 file = fopen(filename, "r");
515 if (file == NULL)
516 return -1;
517
518 while (1) {
519 char name[PATH_MAX];
520 u64 start;
521 char *sep;
522 ssize_t line_len;
523
524 line_len = getline(&line, &n, file);
525 if (line_len < 0) {
526 if (feof(file))
527 break;
528 err = -1;
529 goto out;
530 }
531
532 if (!line) {
533 err = -1;
534 goto out;
535 }
536
537 line[--line_len] = '\0'; /* \n */
538
539 sep = strrchr(line, 'x');
540 if (sep == NULL)
541 continue;
542
543 hex2u64(sep + 1, &start);
544
545 sep = strchr(line, ' ');
546 if (sep == NULL)
547 continue;
548
549 *sep = '\0';
550
551 scnprintf(name, sizeof(name), "[%s]", line);
552
553 err = process_module(arg, name, start);
554 if (err)
555 break;
556 }
557out:
558 free(line);
559 fclose(file);
560 return err;
561}
562
502struct process_kallsyms_args { 563struct process_kallsyms_args {
503 struct map *map; 564 struct map *map;
504 struct dso *dso; 565 struct dso *dso;
@@ -739,51 +800,242 @@ bool symbol__restricted_filename(const char *filename,
739 return restricted; 800 return restricted;
740} 801}
741 802
742struct kcore_mapfn_data { 803struct module_info {
743 struct dso *dso; 804 struct rb_node rb_node;
744 enum map_type type; 805 char *name;
745 struct list_head maps; 806 u64 start;
746}; 807};
747 808
748static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) 809static void add_module(struct module_info *mi, struct rb_root *modules)
749{ 810{
750 struct kcore_mapfn_data *md = data; 811 struct rb_node **p = &modules->rb_node;
751 struct map *map; 812 struct rb_node *parent = NULL;
813 struct module_info *m;
752 814
753 map = map__new2(start, md->dso, md->type); 815 while (*p != NULL) {
754 if (map == NULL) 816 parent = *p;
817 m = rb_entry(parent, struct module_info, rb_node);
818 if (strcmp(mi->name, m->name) < 0)
819 p = &(*p)->rb_left;
820 else
821 p = &(*p)->rb_right;
822 }
823 rb_link_node(&mi->rb_node, parent, p);
824 rb_insert_color(&mi->rb_node, modules);
825}
826
827static void delete_modules(struct rb_root *modules)
828{
829 struct module_info *mi;
830 struct rb_node *next = rb_first(modules);
831
832 while (next) {
833 mi = rb_entry(next, struct module_info, rb_node);
834 next = rb_next(&mi->rb_node);
835 rb_erase(&mi->rb_node, modules);
836 free(mi->name);
837 free(mi);
838 }
839}
840
841static struct module_info *find_module(const char *name,
842 struct rb_root *modules)
843{
844 struct rb_node *n = modules->rb_node;
845
846 while (n) {
847 struct module_info *m;
848 int cmp;
849
850 m = rb_entry(n, struct module_info, rb_node);
851 cmp = strcmp(name, m->name);
852 if (cmp < 0)
853 n = n->rb_left;
854 else if (cmp > 0)
855 n = n->rb_right;
856 else
857 return m;
858 }
859
860 return NULL;
861}
862
863static int __read_proc_modules(void *arg, const char *name, u64 start)
864{
865 struct rb_root *modules = arg;
866 struct module_info *mi;
867
868 mi = zalloc(sizeof(struct module_info));
869 if (!mi)
755 return -ENOMEM; 870 return -ENOMEM;
756 871
757 map->end = map->start + len; 872 mi->name = strdup(name);
758 map->pgoff = pgoff; 873 mi->start = start;
759 874
760 list_add(&map->node, &md->maps); 875 if (!mi->name) {
876 free(mi);
877 return -ENOMEM;
878 }
879
880 add_module(mi, modules);
881
882 return 0;
883}
884
885static int read_proc_modules(const char *filename, struct rb_root *modules)
886{
887 if (symbol__restricted_filename(filename, "/proc/modules"))
888 return -1;
889
890 if (modules__parse(filename, modules, __read_proc_modules)) {
891 delete_modules(modules);
892 return -1;
893 }
761 894
762 return 0; 895 return 0;
763} 896}
764 897
898int compare_proc_modules(const char *from, const char *to)
899{
900 struct rb_root from_modules = RB_ROOT;
901 struct rb_root to_modules = RB_ROOT;
902 struct rb_node *from_node, *to_node;
903 struct module_info *from_m, *to_m;
904 int ret = -1;
905
906 if (read_proc_modules(from, &from_modules))
907 return -1;
908
909 if (read_proc_modules(to, &to_modules))
910 goto out_delete_from;
911
912 from_node = rb_first(&from_modules);
913 to_node = rb_first(&to_modules);
914 while (from_node) {
915 if (!to_node)
916 break;
917
918 from_m = rb_entry(from_node, struct module_info, rb_node);
919 to_m = rb_entry(to_node, struct module_info, rb_node);
920
921 if (from_m->start != to_m->start ||
922 strcmp(from_m->name, to_m->name))
923 break;
924
925 from_node = rb_next(from_node);
926 to_node = rb_next(to_node);
927 }
928
929 if (!from_node && !to_node)
930 ret = 0;
931
932 delete_modules(&to_modules);
933out_delete_from:
934 delete_modules(&from_modules);
935
936 return ret;
937}
938
939static int do_validate_kcore_modules(const char *filename, struct map *map,
940 struct map_groups *kmaps)
941{
942 struct rb_root modules = RB_ROOT;
943 struct map *old_map;
944 int err;
945
946 err = read_proc_modules(filename, &modules);
947 if (err)
948 return err;
949
950 old_map = map_groups__first(kmaps, map->type);
951 while (old_map) {
952 struct map *next = map_groups__next(old_map);
953 struct module_info *mi;
954
955 if (old_map == map || old_map->start == map->start) {
956 /* The kernel map */
957 old_map = next;
958 continue;
959 }
960
961 /* Module must be in memory at the same address */
962 mi = find_module(old_map->dso->short_name, &modules);
963 if (!mi || mi->start != old_map->start) {
964 err = -EINVAL;
965 goto out;
966 }
967
968 old_map = next;
969 }
970out:
971 delete_modules(&modules);
972 return err;
973}
974
765/* 975/*
766 * If kallsyms is referenced by name then we look for kcore in the same 976 * If kallsyms is referenced by name then we look for filename in the same
767 * directory. 977 * directory.
768 */ 978 */
769static bool kcore_filename_from_kallsyms_filename(char *kcore_filename, 979static bool filename_from_kallsyms_filename(char *filename,
770 const char *kallsyms_filename) 980 const char *base_name,
981 const char *kallsyms_filename)
771{ 982{
772 char *name; 983 char *name;
773 984
774 strcpy(kcore_filename, kallsyms_filename); 985 strcpy(filename, kallsyms_filename);
775 name = strrchr(kcore_filename, '/'); 986 name = strrchr(filename, '/');
776 if (!name) 987 if (!name)
777 return false; 988 return false;
778 989
779 if (!strcmp(name, "/kallsyms")) { 990 name += 1;
780 strcpy(name, "/kcore"); 991
992 if (!strcmp(name, "kallsyms")) {
993 strcpy(name, base_name);
781 return true; 994 return true;
782 } 995 }
783 996
784 return false; 997 return false;
785} 998}
786 999
1000static int validate_kcore_modules(const char *kallsyms_filename,
1001 struct map *map)
1002{
1003 struct map_groups *kmaps = map__kmap(map)->kmaps;
1004 char modules_filename[PATH_MAX];
1005
1006 if (!filename_from_kallsyms_filename(modules_filename, "modules",
1007 kallsyms_filename))
1008 return -EINVAL;
1009
1010 if (do_validate_kcore_modules(modules_filename, map, kmaps))
1011 return -EINVAL;
1012
1013 return 0;
1014}
1015
1016struct kcore_mapfn_data {
1017 struct dso *dso;
1018 enum map_type type;
1019 struct list_head maps;
1020};
1021
1022static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
1023{
1024 struct kcore_mapfn_data *md = data;
1025 struct map *map;
1026
1027 map = map__new2(start, md->dso, md->type);
1028 if (map == NULL)
1029 return -ENOMEM;
1030
1031 map->end = map->start + len;
1032 map->pgoff = pgoff;
1033
1034 list_add(&map->node, &md->maps);
1035
1036 return 0;
1037}
1038
787static int dso__load_kcore(struct dso *dso, struct map *map, 1039static int dso__load_kcore(struct dso *dso, struct map *map,
788 const char *kallsyms_filename) 1040 const char *kallsyms_filename)
789{ 1041{
@@ -800,8 +1052,12 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
800 if (map != machine->vmlinux_maps[map->type]) 1052 if (map != machine->vmlinux_maps[map->type])
801 return -EINVAL; 1053 return -EINVAL;
802 1054
803 if (!kcore_filename_from_kallsyms_filename(kcore_filename, 1055 if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
804 kallsyms_filename)) 1056 kallsyms_filename))
1057 return -EINVAL;
1058
1059 /* All modules must be present at their original addresses */
1060 if (validate_kcore_modules(kallsyms_filename, map))
805 return -EINVAL; 1061 return -EINVAL;
806 1062
807 md.dso = dso; 1063 md.dso = dso;
@@ -1188,6 +1444,105 @@ out:
1188 return err; 1444 return err;
1189} 1445}
1190 1446
1447static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1448{
1449 char kallsyms_filename[PATH_MAX];
1450 struct dirent *dent;
1451 int ret = -1;
1452 DIR *d;
1453
1454 d = opendir(dir);
1455 if (!d)
1456 return -1;
1457
1458 while (1) {
1459 dent = readdir(d);
1460 if (!dent)
1461 break;
1462 if (dent->d_type != DT_DIR)
1463 continue;
1464 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1465 "%s/%s/kallsyms", dir, dent->d_name);
1466 if (!validate_kcore_modules(kallsyms_filename, map)) {
1467 strlcpy(dir, kallsyms_filename, dir_sz);
1468 ret = 0;
1469 break;
1470 }
1471 }
1472
1473 closedir(d);
1474
1475 return ret;
1476}
1477
1478static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1479{
1480 u8 host_build_id[BUILD_ID_SIZE];
1481 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1482 bool is_host = false;
1483 char path[PATH_MAX];
1484
1485 if (!dso->has_build_id) {
1486 /*
1487 * Last resort, if we don't have a build-id and couldn't find
1488 * any vmlinux file, try the running kernel kallsyms table.
1489 */
1490 goto proc_kallsyms;
1491 }
1492
1493 if (sysfs__read_build_id("/sys/kernel/notes", host_build_id,
1494 sizeof(host_build_id)) == 0)
1495 is_host = dso__build_id_equal(dso, host_build_id);
1496
1497 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1498
1499 /* Use /proc/kallsyms if possible */
1500 if (is_host) {
1501 DIR *d;
1502 int fd;
1503
1504 /* If no cached kcore go with /proc/kallsyms */
1505 scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s",
1506 buildid_dir, sbuild_id);
1507 d = opendir(path);
1508 if (!d)
1509 goto proc_kallsyms;
1510 closedir(d);
1511
1512 /*
1513 * Do not check the build-id cache, until we know we cannot use
1514 * /proc/kcore.
1515 */
1516 fd = open("/proc/kcore", O_RDONLY);
1517 if (fd != -1) {
1518 close(fd);
1519 /* If module maps match go with /proc/kallsyms */
1520 if (!validate_kcore_modules("/proc/kallsyms", map))
1521 goto proc_kallsyms;
1522 }
1523
1524 /* Find kallsyms in build-id cache with kcore */
1525 if (!find_matching_kcore(map, path, sizeof(path)))
1526 return strdup(path);
1527
1528 goto proc_kallsyms;
1529 }
1530
1531 scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
1532 buildid_dir, sbuild_id);
1533
1534 if (access(path, F_OK)) {
1535 pr_err("No kallsyms or vmlinux with build-id %s was found\n",
1536 sbuild_id);
1537 return NULL;
1538 }
1539
1540 return strdup(path);
1541
1542proc_kallsyms:
1543 return strdup("/proc/kallsyms");
1544}
1545
1191static int dso__load_kernel_sym(struct dso *dso, struct map *map, 1546static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1192 symbol_filter_t filter) 1547 symbol_filter_t filter)
1193{ 1548{
@@ -1214,7 +1569,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1214 goto do_kallsyms; 1569 goto do_kallsyms;
1215 } 1570 }
1216 1571
1217 if (symbol_conf.vmlinux_name != NULL) { 1572 if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
1218 err = dso__load_vmlinux(dso, map, 1573 err = dso__load_vmlinux(dso, map,
1219 symbol_conf.vmlinux_name, filter); 1574 symbol_conf.vmlinux_name, filter);
1220 if (err > 0) { 1575 if (err > 0) {
@@ -1226,7 +1581,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1226 return err; 1581 return err;
1227 } 1582 }
1228 1583
1229 if (vmlinux_path != NULL) { 1584 if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
1230 err = dso__load_vmlinux_path(dso, map, filter); 1585 err = dso__load_vmlinux_path(dso, map, filter);
1231 if (err > 0) 1586 if (err > 0)
1232 return err; 1587 return err;
@@ -1236,51 +1591,11 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1236 if (symbol_conf.symfs[0] != 0) 1591 if (symbol_conf.symfs[0] != 0)
1237 return -1; 1592 return -1;
1238 1593
1239 /* 1594 kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
1240 * Say the kernel DSO was created when processing the build-id header table, 1595 if (!kallsyms_allocated_filename)
1241 * we have a build-id, so check if it is the same as the running kernel, 1596 return -1;
1242 * using it if it is.
1243 */
1244 if (dso->has_build_id) {
1245 u8 kallsyms_build_id[BUILD_ID_SIZE];
1246 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1247
1248 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1249 sizeof(kallsyms_build_id)) == 0) {
1250 if (dso__build_id_equal(dso, kallsyms_build_id)) {
1251 kallsyms_filename = "/proc/kallsyms";
1252 goto do_kallsyms;
1253 }
1254 }
1255 /*
1256 * Now look if we have it on the build-id cache in
1257 * $HOME/.debug/[kernel.kallsyms].
1258 */
1259 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1260 sbuild_id);
1261
1262 if (asprintf(&kallsyms_allocated_filename,
1263 "%s/.debug/[kernel.kallsyms]/%s",
1264 getenv("HOME"), sbuild_id) == -1) {
1265 pr_err("Not enough memory for kallsyms file lookup\n");
1266 return -1;
1267 }
1268
1269 kallsyms_filename = kallsyms_allocated_filename;
1270 1597
1271 if (access(kallsyms_filename, F_OK)) { 1598 kallsyms_filename = kallsyms_allocated_filename;
1272 pr_err("No kallsyms or vmlinux with build-id %s "
1273 "was found\n", sbuild_id);
1274 free(kallsyms_allocated_filename);
1275 return -1;
1276 }
1277 } else {
1278 /*
1279 * Last resort, if we don't have a build-id and couldn't find
1280 * any vmlinux file, try the running kernel kallsyms table.
1281 */
1282 kallsyms_filename = "/proc/kallsyms";
1283 }
1284 1599
1285do_kallsyms: 1600do_kallsyms:
1286 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); 1601 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);