aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-04-07 04:22:45 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-04-08 08:07:03 -0400
commitba92732e9808df679ddf75c5ea1c0caae6d7dce2 (patch)
treef00303efe3ed8cd3f2c5508d8af87db9b0137a82 /tools/perf
parent8ea92ceb748535799e3e9f35afb85bdc23bf6d7c (diff)
perf kmaps: Check kmaps to make code more robust
This patch add checks in places where map__kmap is used to get kmaps from struct kmap. Error messages are added at map__kmap to warn invalid accessing of kmap (for the case of !map->dso->kernel, kmap(map) does not exists at all). Also, introduces map__kmaps() to warn uninitialized kmaps. Reviewed-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: pi3orama@163.com Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Link: http://lkml.kernel.org/r/1428394966-131044-2-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/machine.c5
-rw-r--r--tools/perf/util/map.c20
-rw-r--r--tools/perf/util/map.h6
-rw-r--r--tools/perf/util/probe-event.c2
-rw-r--r--tools/perf/util/session.c3
-rw-r--r--tools/perf/util/symbol-elf.c16
-rw-r--r--tools/perf/util/symbol.c34
7 files changed, 70 insertions, 16 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e45c8f33a8fd..9c380a2caa54 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -679,6 +679,9 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
679 machine->vmlinux_maps[type]->unmap_ip = 679 machine->vmlinux_maps[type]->unmap_ip =
680 identity__map_ip; 680 identity__map_ip;
681 kmap = map__kmap(machine->vmlinux_maps[type]); 681 kmap = map__kmap(machine->vmlinux_maps[type]);
682 if (!kmap)
683 return -1;
684
682 kmap->kmaps = &machine->kmaps; 685 kmap->kmaps = &machine->kmaps;
683 map_groups__insert(&machine->kmaps, 686 map_groups__insert(&machine->kmaps,
684 machine->vmlinux_maps[type]); 687 machine->vmlinux_maps[type]);
@@ -700,7 +703,7 @@ void machine__destroy_kernel_maps(struct machine *machine)
700 kmap = map__kmap(machine->vmlinux_maps[type]); 703 kmap = map__kmap(machine->vmlinux_maps[type]);
701 map_groups__remove(&machine->kmaps, 704 map_groups__remove(&machine->kmaps,
702 machine->vmlinux_maps[type]); 705 machine->vmlinux_maps[type]);
703 if (kmap->ref_reloc_sym) { 706 if (kmap && kmap->ref_reloc_sym) {
704 /* 707 /*
705 * ref_reloc_sym is shared among all maps, so free just 708 * ref_reloc_sym is shared among all maps, so free just
706 * on one of them. 709 * on one of them.
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 62ca9f2607d5..a14f08f41686 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -778,3 +778,23 @@ struct map *maps__next(struct map *map)
778 return rb_entry(next, struct map, rb_node); 778 return rb_entry(next, struct map, rb_node);
779 return NULL; 779 return NULL;
780} 780}
781
782struct kmap *map__kmap(struct map *map)
783{
784 if (!map->dso || !map->dso->kernel) {
785 pr_err("Internal error: map__kmap with a non-kernel map\n");
786 return NULL;
787 }
788 return (struct kmap *)(map + 1);
789}
790
791struct map_groups *map__kmaps(struct map *map)
792{
793 struct kmap *kmap = map__kmap(map);
794
795 if (!kmap || !kmap->kmaps) {
796 pr_err("Internal error: map__kmaps with a non-kernel map\n");
797 return NULL;
798 }
799 return kmap->kmaps;
800}
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 0e42438b1e59..ec19c59ca38e 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -76,10 +76,8 @@ static inline struct map_groups *map_groups__get(struct map_groups *mg)
76 76
77void map_groups__put(struct map_groups *mg); 77void map_groups__put(struct map_groups *mg);
78 78
79static inline struct kmap *map__kmap(struct map *map) 79struct kmap *map__kmap(struct map *map);
80{ 80struct map_groups *map__kmaps(struct map *map);
81 return (struct kmap *)(map + 1);
82}
83 81
84static inline u64 map__map_ip(struct map *map, u64 ip) 82static inline u64 map__map_ip(struct map *map, u64 ip)
85{ 83{
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 8feac0774c41..4fd49f021073 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -135,6 +135,8 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
135 return NULL; 135 return NULL;
136 136
137 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]); 137 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
138 if (!kmap)
139 return NULL;
138 return kmap->ref_reloc_sym; 140 return kmap->ref_reloc_sym;
139} 141}
140 142
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index dfacf1d50162..0c74012575ac 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1466,6 +1466,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1466 1466
1467 for (i = 0; i < MAP__NR_TYPES; ++i) { 1467 for (i = 0; i < MAP__NR_TYPES; ++i) {
1468 struct kmap *kmap = map__kmap(maps[i]); 1468 struct kmap *kmap = map__kmap(maps[i]);
1469
1470 if (!kmap)
1471 continue;
1469 kmap->ref_reloc_sym = ref; 1472 kmap->ref_reloc_sym = ref;
1470 } 1473 }
1471 1474
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 476268c99431..a7ab6063e038 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -776,6 +776,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
776 symbol_filter_t filter, int kmodule) 776 symbol_filter_t filter, int kmodule)
777{ 777{
778 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL; 778 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
779 struct map_groups *kmaps = kmap ? map__kmaps(map) : NULL;
779 struct map *curr_map = map; 780 struct map *curr_map = map;
780 struct dso *curr_dso = dso; 781 struct dso *curr_dso = dso;
781 Elf_Data *symstrs, *secstrs; 782 Elf_Data *symstrs, *secstrs;
@@ -791,6 +792,9 @@ int dso__load_sym(struct dso *dso, struct map *map,
791 int nr = 0; 792 int nr = 0;
792 bool remap_kernel = false, adjust_kernel_syms = false; 793 bool remap_kernel = false, adjust_kernel_syms = false;
793 794
795 if (kmap && !kmaps)
796 return -1;
797
794 dso->symtab_type = syms_ss->type; 798 dso->symtab_type = syms_ss->type;
795 dso->is_64_bit = syms_ss->is_64_bit; 799 dso->is_64_bit = syms_ss->is_64_bit;
796 dso->rel = syms_ss->ehdr.e_type == ET_REL; 800 dso->rel = syms_ss->ehdr.e_type == ET_REL;
@@ -958,8 +962,10 @@ int dso__load_sym(struct dso *dso, struct map *map,
958 map->map_ip = map__map_ip; 962 map->map_ip = map__map_ip;
959 map->unmap_ip = map__unmap_ip; 963 map->unmap_ip = map__unmap_ip;
960 /* Ensure maps are correctly ordered */ 964 /* Ensure maps are correctly ordered */
961 map_groups__remove(kmap->kmaps, map); 965 if (kmaps) {
962 map_groups__insert(kmap->kmaps, map); 966 map_groups__remove(kmaps, map);
967 map_groups__insert(kmaps, map);
968 }
963 } 969 }
964 970
965 /* 971 /*
@@ -983,7 +989,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
983 snprintf(dso_name, sizeof(dso_name), 989 snprintf(dso_name, sizeof(dso_name),
984 "%s%s", dso->short_name, section_name); 990 "%s%s", dso->short_name, section_name);
985 991
986 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name); 992 curr_map = map_groups__find_by_name(kmaps, map->type, dso_name);
987 if (curr_map == NULL) { 993 if (curr_map == NULL) {
988 u64 start = sym.st_value; 994 u64 start = sym.st_value;
989 995
@@ -1013,7 +1019,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
1013 curr_map->unmap_ip = identity__map_ip; 1019 curr_map->unmap_ip = identity__map_ip;
1014 } 1020 }
1015 curr_dso->symtab_type = dso->symtab_type; 1021 curr_dso->symtab_type = dso->symtab_type;
1016 map_groups__insert(kmap->kmaps, curr_map); 1022 map_groups__insert(kmaps, curr_map);
1017 /* 1023 /*
1018 * The new DSO should go to the kernel DSOS 1024 * The new DSO should go to the kernel DSOS
1019 */ 1025 */
@@ -1075,7 +1081,7 @@ new_symbol:
1075 * We need to fixup this here too because we create new 1081 * We need to fixup this here too because we create new
1076 * maps here, for things like vsyscall sections. 1082 * maps here, for things like vsyscall sections.
1077 */ 1083 */
1078 __map_groups__fixup_end(kmap->kmaps, map->type); 1084 __map_groups__fixup_end(kmaps, map->type);
1079 } 1085 }
1080 } 1086 }
1081 err = nr; 1087 err = nr;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fddeb9073039..201f6c4ca738 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -630,13 +630,16 @@ static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
630static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map, 630static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
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__kmaps(map);
634 struct map *curr_map; 634 struct map *curr_map;
635 struct symbol *pos; 635 struct symbol *pos;
636 int count = 0, moved = 0; 636 int count = 0, moved = 0;
637 struct rb_root *root = &dso->symbols[map->type]; 637 struct rb_root *root = &dso->symbols[map->type];
638 struct rb_node *next = rb_first(root); 638 struct rb_node *next = rb_first(root);
639 639
640 if (!kmaps)
641 return -1;
642
640 while (next) { 643 while (next) {
641 char *module; 644 char *module;
642 645
@@ -682,8 +685,8 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
682static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta, 685static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta,
683 symbol_filter_t filter) 686 symbol_filter_t filter)
684{ 687{
685 struct map_groups *kmaps = map__kmap(map)->kmaps; 688 struct map_groups *kmaps = map__kmaps(map);
686 struct machine *machine = kmaps->machine; 689 struct machine *machine;
687 struct map *curr_map = map; 690 struct map *curr_map = map;
688 struct symbol *pos; 691 struct symbol *pos;
689 int count = 0, moved = 0; 692 int count = 0, moved = 0;
@@ -691,6 +694,11 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta,
691 struct rb_node *next = rb_first(root); 694 struct rb_node *next = rb_first(root);
692 int kernel_range = 0; 695 int kernel_range = 0;
693 696
697 if (!kmaps)
698 return -1;
699
700 machine = kmaps->machine;
701
694 while (next) { 702 while (next) {
695 char *module; 703 char *module;
696 704
@@ -1025,9 +1033,12 @@ static bool filename_from_kallsyms_filename(char *filename,
1025static int validate_kcore_modules(const char *kallsyms_filename, 1033static int validate_kcore_modules(const char *kallsyms_filename,
1026 struct map *map) 1034 struct map *map)
1027{ 1035{
1028 struct map_groups *kmaps = map__kmap(map)->kmaps; 1036 struct map_groups *kmaps = map__kmaps(map);
1029 char modules_filename[PATH_MAX]; 1037 char modules_filename[PATH_MAX];
1030 1038
1039 if (!kmaps)
1040 return -EINVAL;
1041
1031 if (!filename_from_kallsyms_filename(modules_filename, "modules", 1042 if (!filename_from_kallsyms_filename(modules_filename, "modules",
1032 kallsyms_filename)) 1043 kallsyms_filename))
1033 return -EINVAL; 1044 return -EINVAL;
@@ -1043,6 +1054,9 @@ static int validate_kcore_addresses(const char *kallsyms_filename,
1043{ 1054{
1044 struct kmap *kmap = map__kmap(map); 1055 struct kmap *kmap = map__kmap(map);
1045 1056
1057 if (!kmap)
1058 return -EINVAL;
1059
1046 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { 1060 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
1047 u64 start; 1061 u64 start;
1048 1062
@@ -1081,8 +1095,8 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
1081static int dso__load_kcore(struct dso *dso, struct map *map, 1095static int dso__load_kcore(struct dso *dso, struct map *map,
1082 const char *kallsyms_filename) 1096 const char *kallsyms_filename)
1083{ 1097{
1084 struct map_groups *kmaps = map__kmap(map)->kmaps; 1098 struct map_groups *kmaps = map__kmaps(map);
1085 struct machine *machine = kmaps->machine; 1099 struct machine *machine;
1086 struct kcore_mapfn_data md; 1100 struct kcore_mapfn_data md;
1087 struct map *old_map, *new_map, *replacement_map = NULL; 1101 struct map *old_map, *new_map, *replacement_map = NULL;
1088 bool is_64_bit; 1102 bool is_64_bit;
@@ -1090,6 +1104,11 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1090 char kcore_filename[PATH_MAX]; 1104 char kcore_filename[PATH_MAX];
1091 struct symbol *sym; 1105 struct symbol *sym;
1092 1106
1107 if (!kmaps)
1108 return -EINVAL;
1109
1110 machine = kmaps->machine;
1111
1093 /* This function requires that the map is the kernel map */ 1112 /* This function requires that the map is the kernel map */
1094 if (map != machine->vmlinux_maps[map->type]) 1113 if (map != machine->vmlinux_maps[map->type])
1095 return -EINVAL; 1114 return -EINVAL;
@@ -1202,6 +1221,9 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
1202 struct kmap *kmap = map__kmap(map); 1221 struct kmap *kmap = map__kmap(map);
1203 u64 addr; 1222 u64 addr;
1204 1223
1224 if (!kmap)
1225 return -1;
1226
1205 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) 1227 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
1206 return 0; 1228 return 0;
1207 1229