aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-probe.c5
-rw-r--r--tools/perf/util/event.c6
-rw-r--r--tools/perf/util/map.c20
-rw-r--r--tools/perf/util/map.h22
-rw-r--r--tools/perf/util/session.c35
-rw-r--r--tools/perf/util/session.h22
-rw-r--r--tools/perf/util/symbol.c122
-rw-r--r--tools/perf/util/symbol.h19
-rw-r--r--tools/perf/util/thread.c3
-rw-r--r--tools/perf/util/thread.h14
11 files changed, 149 insertions, 121 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 5d5dc6b09617..924a9518931a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -369,7 +369,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
369 if (is_caller) { 369 if (is_caller) {
370 addr = data->call_site; 370 addr = data->call_site;
371 if (!raw_ip) 371 if (!raw_ip)
372 sym = map_groups__find_function(&session->kmaps, session, addr, NULL); 372 sym = map_groups__find_function(&session->kmaps, addr, NULL);
373 } else 373 } else
374 addr = data->ptr; 374 addr = data->ptr;
375 375
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 34f2acb1cc88..4fa73eca1d82 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -122,8 +122,7 @@ static int opt_del_probe_event(const struct option *opt __used,
122static void evaluate_probe_point(struct probe_point *pp) 122static void evaluate_probe_point(struct probe_point *pp)
123{ 123{
124 struct symbol *sym; 124 struct symbol *sym;
125 sym = map__find_symbol_by_name(session.kmap, pp->function, 125 sym = map__find_symbol_by_name(session.kmap, pp->function, NULL);
126 session.psession, NULL);
127 if (!sym) 126 if (!sym)
128 die("Kernel symbol \'%s\' not found - probe not added.", 127 die("Kernel symbol \'%s\' not found - probe not added.",
129 pp->function); 128 pp->function);
@@ -132,7 +131,7 @@ static void evaluate_probe_point(struct probe_point *pp)
132#ifndef NO_LIBDWARF 131#ifndef NO_LIBDWARF
133static int open_vmlinux(void) 132static int open_vmlinux(void)
134{ 133{
135 if (map__load(session.kmap, session.psession, NULL) < 0) { 134 if (map__load(session.kmap, NULL) < 0) {
136 pr_debug("Failed to load kernel map.\n"); 135 pr_debug("Failed to load kernel map.\n");
137 return -EINVAL; 136 return -EINVAL;
138 } 137 }
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bbaee61c1683..c3831f633dec 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -374,9 +374,7 @@ int event__process_mmap(event_t *self, struct perf_session *session)
374 goto out_problem; 374 goto out_problem;
375 375
376 kernel->kernel = 1; 376 kernel->kernel = 1;
377 if (__map_groups__create_kernel_maps(&session->kmaps, 377 if (__perf_session__create_kernel_maps(session, kernel) < 0)
378 session->vmlinux_maps,
379 kernel) < 0)
380 goto out_problem; 378 goto out_problem;
381 379
382 session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start; 380 session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
@@ -476,7 +474,7 @@ void thread__find_addr_location(struct thread *self,
476{ 474{
477 thread__find_addr_map(self, session, cpumode, type, addr, al); 475 thread__find_addr_map(self, session, cpumode, type, addr, al);
478 if (al->map != NULL) 476 if (al->map != NULL)
479 al->sym = map__find_symbol(al->map, session, al->addr, filter); 477 al->sym = map__find_symbol(al->map, al->addr, filter);
480 else 478 else
481 al->sym = NULL; 479 al->sym = NULL;
482} 480}
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index c4d55a0da2ea..36ff0bf0315d 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -104,8 +104,7 @@ void map__fixup_end(struct map *self)
104 104
105#define DSO__DELETED "(deleted)" 105#define DSO__DELETED "(deleted)"
106 106
107int map__load(struct map *self, struct perf_session *session, 107int map__load(struct map *self, symbol_filter_t filter)
108 symbol_filter_t filter)
109{ 108{
110 const char *name = self->dso->long_name; 109 const char *name = self->dso->long_name;
111 int nr; 110 int nr;
@@ -113,7 +112,7 @@ int map__load(struct map *self, struct perf_session *session,
113 if (dso__loaded(self->dso, self->type)) 112 if (dso__loaded(self->dso, self->type))
114 return 0; 113 return 0;
115 114
116 nr = dso__load(self->dso, self, session, filter); 115 nr = dso__load(self->dso, self, filter);
117 if (nr < 0) { 116 if (nr < 0) {
118 if (self->dso->has_build_id) { 117 if (self->dso->has_build_id) {
119 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 118 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -144,24 +143,29 @@ int map__load(struct map *self, struct perf_session *session,
144 143
145 return -1; 144 return -1;
146 } 145 }
146 /*
147 * Only applies to the kernel, as its symtabs aren't relative like the
148 * module ones.
149 */
150 if (self->dso->kernel)
151 map__reloc_vmlinux(self);
147 152
148 return 0; 153 return 0;
149} 154}
150 155
151struct symbol *map__find_symbol(struct map *self, struct perf_session *session, 156struct symbol *map__find_symbol(struct map *self, u64 addr,
152 u64 addr, symbol_filter_t filter) 157 symbol_filter_t filter)
153{ 158{
154 if (map__load(self, session, filter) < 0) 159 if (map__load(self, filter) < 0)
155 return NULL; 160 return NULL;
156 161
157 return dso__find_symbol(self->dso, self->type, addr); 162 return dso__find_symbol(self->dso, self->type, addr);
158} 163}
159 164
160struct symbol *map__find_symbol_by_name(struct map *self, const char *name, 165struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
161 struct perf_session *session,
162 symbol_filter_t filter) 166 symbol_filter_t filter)
163{ 167{
164 if (map__load(self, session, filter) < 0) 168 if (map__load(self, filter) < 0)
165 return NULL; 169 return NULL;
166 170
167 if (!dso__sorted_by_name(self->dso, self->type)) 171 if (!dso__sorted_by_name(self->dso, self->type))
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 72f0b6ab5ea5..de048399d776 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -14,6 +14,8 @@ enum map_type {
14#define MAP__NR_TYPES (MAP__VARIABLE + 1) 14#define MAP__NR_TYPES (MAP__VARIABLE + 1)
15 15
16struct dso; 16struct dso;
17struct ref_reloc_sym;
18struct map_groups;
17 19
18struct map { 20struct map {
19 union { 21 union {
@@ -29,6 +31,16 @@ struct map {
29 struct dso *dso; 31 struct dso *dso;
30}; 32};
31 33
34struct kmap {
35 struct ref_reloc_sym *ref_reloc_sym;
36 struct map_groups *kmaps;
37};
38
39static inline struct kmap *map__kmap(struct map *self)
40{
41 return (struct kmap *)(self + 1);
42}
43
32static inline u64 map__map_ip(struct map *map, u64 ip) 44static inline u64 map__map_ip(struct map *map, u64 ip)
33{ 45{
34 return ip - map->start + map->pgoff; 46 return ip - map->start + map->pgoff;
@@ -58,16 +70,14 @@ struct map *map__clone(struct map *self);
58int map__overlap(struct map *l, struct map *r); 70int map__overlap(struct map *l, struct map *r);
59size_t map__fprintf(struct map *self, FILE *fp); 71size_t map__fprintf(struct map *self, FILE *fp);
60 72
61struct perf_session; 73int map__load(struct map *self, symbol_filter_t filter);
62 74struct symbol *map__find_symbol(struct map *self,
63int map__load(struct map *self, struct perf_session *session,
64 symbol_filter_t filter);
65struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
66 u64 addr, symbol_filter_t filter); 75 u64 addr, symbol_filter_t filter);
67struct symbol *map__find_symbol_by_name(struct map *self, const char *name, 76struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
68 struct perf_session *session,
69 symbol_filter_t filter); 77 symbol_filter_t filter);
70void map__fixup_start(struct map *self); 78void map__fixup_start(struct map *self);
71void map__fixup_end(struct map *self); 79void map__fixup_end(struct map *self);
72 80
81void map__reloc_vmlinux(struct map *self);
82
73#endif /* __PERF_MAP_H */ 83#endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index cf91d099f0aa..aa8a03120bbd 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -53,6 +53,11 @@ out_close:
53 return -1; 53 return -1;
54} 54}
55 55
56static inline int perf_session__create_kernel_maps(struct perf_session *self)
57{
58 return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
59}
60
56struct perf_session *perf_session__new(const char *filename, int mode, bool force) 61struct perf_session *perf_session__new(const char *filename, int mode, bool force)
57{ 62{
58 size_t len = filename ? strlen(filename) + 1 : 0; 63 size_t len = filename ? strlen(filename) + 1 : 0;
@@ -507,6 +512,7 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
507 u64 addr) 512 u64 addr)
508{ 513{
509 char *bracket; 514 char *bracket;
515 enum map_type i;
510 516
511 self->ref_reloc_sym.name = strdup(symbol_name); 517 self->ref_reloc_sym.name = strdup(symbol_name);
512 if (self->ref_reloc_sym.name == NULL) 518 if (self->ref_reloc_sym.name == NULL)
@@ -517,6 +523,12 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
517 *bracket = '\0'; 523 *bracket = '\0';
518 524
519 self->ref_reloc_sym.addr = addr; 525 self->ref_reloc_sym.addr = addr;
526
527 for (i = 0; i < MAP__NR_TYPES; ++i) {
528 struct kmap *kmap = map__kmap(self->vmlinux_maps[i]);
529 kmap->ref_reloc_sym = &self->ref_reloc_sym;
530 }
531
520 return 0; 532 return 0;
521} 533}
522 534
@@ -530,20 +542,21 @@ static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
530 return ip - (s64)map->pgoff; 542 return ip - (s64)map->pgoff;
531} 543}
532 544
533void perf_session__reloc_vmlinux_maps(struct perf_session *self, 545void map__reloc_vmlinux(struct map *self)
534 u64 unrelocated_addr)
535{ 546{
536 enum map_type type; 547 struct kmap *kmap = map__kmap(self);
537 s64 reloc = unrelocated_addr - self->ref_reloc_sym.addr; 548 s64 reloc;
538 549
539 if (!reloc) 550 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
540 return; 551 return;
541 552
542 for (type = 0; type < MAP__NR_TYPES; ++type) { 553 reloc = (kmap->ref_reloc_sym->unrelocated_addr -
543 struct map *map = self->vmlinux_maps[type]; 554 kmap->ref_reloc_sym->addr);
544 555
545 map->map_ip = map__reloc_map_ip; 556 if (!reloc)
546 map->unmap_ip = map__reloc_unmap_ip; 557 return;
547 map->pgoff = reloc; 558
548 } 559 self->map_ip = map__reloc_map_ip;
560 self->unmap_ip = map__reloc_unmap_ip;
561 self->pgoff = reloc;
549} 562}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 36d1a80c0b6c..752d75aebade 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -3,13 +3,13 @@
3 3
4#include "event.h" 4#include "event.h"
5#include "header.h" 5#include "header.h"
6#include "symbol.h"
6#include "thread.h" 7#include "thread.h"
7#include <linux/rbtree.h> 8#include <linux/rbtree.h>
8#include "../../../include/linux/perf_event.h" 9#include "../../../include/linux/perf_event.h"
9 10
10struct ip_callchain; 11struct ip_callchain;
11struct thread; 12struct thread;
12struct symbol;
13 13
14struct perf_session { 14struct perf_session {
15 struct perf_header header; 15 struct perf_header header;
@@ -24,10 +24,7 @@ struct perf_session {
24 unsigned long unknown_events; 24 unsigned long unknown_events;
25 struct rb_root hists; 25 struct rb_root hists;
26 u64 sample_type; 26 u64 sample_type;
27 struct { 27 struct ref_reloc_sym ref_reloc_sym;
28 const char *name;
29 u64 addr;
30 } ref_reloc_sym;
31 int fd; 28 int fd;
32 int cwdlen; 29 int cwdlen;
33 char *cwd; 30 char *cwd;
@@ -69,9 +66,20 @@ int perf_header__read_build_ids(struct perf_header *self, int input,
69int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self, 66int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
70 const char *symbol_name, 67 const char *symbol_name,
71 u64 addr); 68 u64 addr);
72void perf_session__reloc_vmlinux_maps(struct perf_session *self,
73 u64 unrelocated_addr);
74 69
75void mem_bswap_64(void *src, int byte_size); 70void mem_bswap_64(void *src, int byte_size);
76 71
72static inline int __perf_session__create_kernel_maps(struct perf_session *self,
73 struct dso *kernel)
74{
75 return __map_groups__create_kernel_maps(&self->kmaps,
76 self->vmlinux_maps, kernel);
77}
78
79static inline struct map *
80 perf_session__new_module_map(struct perf_session *self,
81 u64 start, const char *filename)
82{
83 return map_groups__new_module(&self->kmaps, start, filename);
84}
77#endif /* __PERF_SESSION_H */ 85#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index f9049d12ead6..613874260761 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,6 +1,5 @@
1#include "util.h" 1#include "util.h"
2#include "../perf.h" 2#include "../perf.h"
3#include "session.h"
4#include "sort.h" 3#include "sort.h"
5#include "string.h" 4#include "string.h"
6#include "symbol.h" 5#include "symbol.h"
@@ -34,7 +33,7 @@ enum dso_origin {
34static void dsos__add(struct list_head *head, struct dso *dso); 33static void dsos__add(struct list_head *head, struct dso *dso);
35static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 34static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
36static int dso__load_kernel_sym(struct dso *self, struct map *map, 35static int dso__load_kernel_sym(struct dso *self, struct map *map,
37 struct perf_session *session, symbol_filter_t filter); 36 symbol_filter_t filter);
38static int vmlinux_path__nr_entries; 37static int vmlinux_path__nr_entries;
39static char **vmlinux_path; 38static char **vmlinux_path;
40 39
@@ -480,8 +479,9 @@ static int dso__load_all_kallsyms(struct dso *self, const char *filename,
480 * the original ELF section names vmlinux have. 479 * the original ELF section names vmlinux have.
481 */ 480 */
482static int dso__split_kallsyms(struct dso *self, struct map *map, 481static int dso__split_kallsyms(struct dso *self, struct map *map,
483 struct perf_session *session, symbol_filter_t filter) 482 symbol_filter_t filter)
484{ 483{
484 struct map_groups *kmaps = map__kmap(map)->kmaps;
485 struct map *curr_map = map; 485 struct map *curr_map = map;
486 struct symbol *pos; 486 struct symbol *pos;
487 int count = 0; 487 int count = 0;
@@ -503,7 +503,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
503 *module++ = '\0'; 503 *module++ = '\0';
504 504
505 if (strcmp(curr_map->dso->short_name, module)) { 505 if (strcmp(curr_map->dso->short_name, module)) {
506 curr_map = map_groups__find_by_name(&session->kmaps, map->type, module); 506 curr_map = map_groups__find_by_name(kmaps, map->type, module);
507 if (curr_map == NULL) { 507 if (curr_map == NULL) {
508 pr_debug("/proc/{kallsyms,modules} " 508 pr_debug("/proc/{kallsyms,modules} "
509 "inconsistency while looking " 509 "inconsistency while looking "
@@ -538,7 +538,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
538 } 538 }
539 539
540 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 540 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
541 map_groups__insert(&session->kmaps, curr_map); 541 map_groups__insert(kmaps, curr_map);
542 ++kernel_range; 542 ++kernel_range;
543 } 543 }
544 544
@@ -557,9 +557,8 @@ discard_symbol: rb_erase(&pos->rb_node, root);
557 return count; 557 return count;
558} 558}
559 559
560 560int dso__load_kallsyms(struct dso *self, const char *filename,
561static int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, 561 struct map *map, symbol_filter_t filter)
562 struct perf_session *session, symbol_filter_t filter)
563{ 562{
564 if (dso__load_all_kallsyms(self, filename, map) < 0) 563 if (dso__load_all_kallsyms(self, filename, map) < 0)
565 return -1; 564 return -1;
@@ -567,7 +566,7 @@ static int dso__load_kallsyms(struct dso *self, const char *filename, struct map
567 symbols__fixup_end(&self->symbols[map->type]); 566 symbols__fixup_end(&self->symbols[map->type]);
568 self->origin = DSO__ORIG_KERNEL; 567 self->origin = DSO__ORIG_KERNEL;
569 568
570 return dso__split_kallsyms(self, map, session, filter); 569 return dso__split_kallsyms(self, map, filter);
571} 570}
572 571
573static int dso__load_perf_map(struct dso *self, struct map *map, 572static int dso__load_perf_map(struct dso *self, struct map *map,
@@ -893,10 +892,10 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
893 } 892 }
894} 893}
895 894
896static int dso__load_sym(struct dso *self, struct map *map, 895static int dso__load_sym(struct dso *self, struct map *map, const char *name,
897 struct perf_session *session, const char *name, int fd, 896 int fd, symbol_filter_t filter, int kmodule)
898 symbol_filter_t filter, int kernel, int kmodule)
899{ 897{
898 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
900 struct map *curr_map = map; 899 struct map *curr_map = map;
901 struct dso *curr_dso = self; 900 struct dso *curr_dso = self;
902 size_t dso_name_len = strlen(self->short_name); 901 size_t dso_name_len = strlen(self->short_name);
@@ -953,7 +952,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
953 nr_syms = shdr.sh_size / shdr.sh_entsize; 952 nr_syms = shdr.sh_size / shdr.sh_entsize;
954 953
955 memset(&sym, 0, sizeof(sym)); 954 memset(&sym, 0, sizeof(sym));
956 if (!kernel) { 955 if (!self->kernel) {
957 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 956 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
958 elf_section_by_name(elf, &ehdr, &shdr, 957 elf_section_by_name(elf, &ehdr, &shdr,
959 ".gnu.prelink_undo", 958 ".gnu.prelink_undo",
@@ -967,9 +966,9 @@ static int dso__load_sym(struct dso *self, struct map *map,
967 int is_label = elf_sym__is_label(&sym); 966 int is_label = elf_sym__is_label(&sym);
968 const char *section_name; 967 const char *section_name;
969 968
970 if (kernel && session->ref_reloc_sym.name != NULL && 969 if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
971 strcmp(elf_name, session->ref_reloc_sym.name) == 0) 970 strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
972 perf_session__reloc_vmlinux_maps(session, sym.st_value); 971 kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
973 972
974 if (!is_label && !elf_sym__is_a(&sym, map->type)) 973 if (!is_label && !elf_sym__is_a(&sym, map->type))
975 continue; 974 continue;
@@ -985,7 +984,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
985 984
986 section_name = elf_sec__name(&shdr, secstrs); 985 section_name = elf_sec__name(&shdr, secstrs);
987 986
988 if (kernel || kmodule) { 987 if (self->kernel || kmodule) {
989 char dso_name[PATH_MAX]; 988 char dso_name[PATH_MAX];
990 989
991 if (strcmp(section_name, 990 if (strcmp(section_name,
@@ -1001,7 +1000,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
1001 snprintf(dso_name, sizeof(dso_name), 1000 snprintf(dso_name, sizeof(dso_name),
1002 "%s%s", self->short_name, section_name); 1001 "%s%s", self->short_name, section_name);
1003 1002
1004 curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name); 1003 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1005 if (curr_map == NULL) { 1004 if (curr_map == NULL) {
1006 u64 start = sym.st_value; 1005 u64 start = sym.st_value;
1007 1006
@@ -1020,7 +1019,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
1020 curr_map->map_ip = identity__map_ip; 1019 curr_map->map_ip = identity__map_ip;
1021 curr_map->unmap_ip = identity__map_ip; 1020 curr_map->unmap_ip = identity__map_ip;
1022 curr_dso->origin = DSO__ORIG_KERNEL; 1021 curr_dso->origin = DSO__ORIG_KERNEL;
1023 map_groups__insert(&session->kmaps, curr_map); 1022 map_groups__insert(kmap->kmaps, curr_map);
1024 dsos__add(&dsos__kernel, curr_dso); 1023 dsos__add(&dsos__kernel, curr_dso);
1025 } else 1024 } else
1026 curr_dso = curr_map->dso; 1025 curr_dso = curr_map->dso;
@@ -1236,8 +1235,7 @@ char dso__symtab_origin(const struct dso *self)
1236 return origin[self->origin]; 1235 return origin[self->origin];
1237} 1236}
1238 1237
1239int dso__load(struct dso *self, struct map *map, struct perf_session *session, 1238int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1240 symbol_filter_t filter)
1241{ 1239{
1242 int size = PATH_MAX; 1240 int size = PATH_MAX;
1243 char *name; 1241 char *name;
@@ -1249,7 +1247,7 @@ int dso__load(struct dso *self, struct map *map, struct perf_session *session,
1249 dso__set_loaded(self, map->type); 1247 dso__set_loaded(self, map->type);
1250 1248
1251 if (self->kernel) 1249 if (self->kernel)
1252 return dso__load_kernel_sym(self, map, session, filter); 1250 return dso__load_kernel_sym(self, map, filter);
1253 1251
1254 name = malloc(size); 1252 name = malloc(size);
1255 if (!name) 1253 if (!name)
@@ -1320,7 +1318,7 @@ open_file:
1320 fd = open(name, O_RDONLY); 1318 fd = open(name, O_RDONLY);
1321 } while (fd < 0); 1319 } while (fd < 0);
1322 1320
1323 ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0); 1321 ret = dso__load_sym(self, map, name, fd, filter, 0);
1324 close(fd); 1322 close(fd);
1325 1323
1326 /* 1324 /*
@@ -1376,7 +1374,7 @@ static int dso__kernel_module_get_build_id(struct dso *self)
1376 return 0; 1374 return 0;
1377} 1375}
1378 1376
1379static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname) 1377static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname)
1380{ 1378{
1381 struct dirent *dent; 1379 struct dirent *dent;
1382 DIR *dir = opendir(dirname); 1380 DIR *dir = opendir(dirname);
@@ -1396,7 +1394,7 @@ static int perf_session__set_modules_path_dir(struct perf_session *self, char *d
1396 1394
1397 snprintf(path, sizeof(path), "%s/%s", 1395 snprintf(path, sizeof(path), "%s/%s",
1398 dirname, dent->d_name); 1396 dirname, dent->d_name);
1399 if (perf_session__set_modules_path_dir(self, path) < 0) 1397 if (map_groups__set_modules_path_dir(self, path) < 0)
1400 goto failure; 1398 goto failure;
1401 } else { 1399 } else {
1402 char *dot = strrchr(dent->d_name, '.'), 1400 char *dot = strrchr(dent->d_name, '.'),
@@ -1410,7 +1408,7 @@ static int perf_session__set_modules_path_dir(struct perf_session *self, char *d
1410 (int)(dot - dent->d_name), dent->d_name); 1408 (int)(dot - dent->d_name), dent->d_name);
1411 1409
1412 strxfrchar(dso_name, '-', '_'); 1410 strxfrchar(dso_name, '-', '_');
1413 map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name); 1411 map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
1414 if (map == NULL) 1412 if (map == NULL)
1415 continue; 1413 continue;
1416 1414
@@ -1431,7 +1429,7 @@ failure:
1431 return -1; 1429 return -1;
1432} 1430}
1433 1431
1434static int perf_session__set_modules_path(struct perf_session *self) 1432static int map_groups__set_modules_path(struct map_groups *self)
1435{ 1433{
1436 struct utsname uts; 1434 struct utsname uts;
1437 char modules_path[PATH_MAX]; 1435 char modules_path[PATH_MAX];
@@ -1442,7 +1440,7 @@ static int perf_session__set_modules_path(struct perf_session *self)
1442 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1440 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1443 uts.release); 1441 uts.release);
1444 1442
1445 return perf_session__set_modules_path_dir(self, modules_path); 1443 return map_groups__set_modules_path_dir(self, modules_path);
1446} 1444}
1447 1445
1448/* 1446/*
@@ -1452,8 +1450,8 @@ static int perf_session__set_modules_path(struct perf_session *self)
1452 */ 1450 */
1453static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1451static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1454{ 1452{
1455 struct map *self = malloc(sizeof(*self)); 1453 struct map *self = zalloc(sizeof(*self) +
1456 1454 (dso->kernel ? sizeof(struct kmap) : 0));
1457 if (self != NULL) { 1455 if (self != NULL) {
1458 /* 1456 /*
1459 * ->end will be filled after we load all the symbols 1457 * ->end will be filled after we load all the symbols
@@ -1464,8 +1462,8 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1464 return self; 1462 return self;
1465} 1463}
1466 1464
1467struct map *perf_session__new_module_map(struct perf_session *self, u64 start, 1465struct map *map_groups__new_module(struct map_groups *self, u64 start,
1468 const char *filename) 1466 const char *filename)
1469{ 1467{
1470 struct map *map; 1468 struct map *map;
1471 struct dso *dso = __dsos__findnew(&dsos__kernel, filename); 1469 struct dso *dso = __dsos__findnew(&dsos__kernel, filename);
@@ -1478,11 +1476,11 @@ struct map *perf_session__new_module_map(struct perf_session *self, u64 start,
1478 return NULL; 1476 return NULL;
1479 1477
1480 dso->origin = DSO__ORIG_KMODULE; 1478 dso->origin = DSO__ORIG_KMODULE;
1481 map_groups__insert(&self->kmaps, map); 1479 map_groups__insert(self, map);
1482 return map; 1480 return map;
1483} 1481}
1484 1482
1485static int perf_session__create_module_maps(struct perf_session *self) 1483static int map_groups__create_modules(struct map_groups *self)
1486{ 1484{
1487 char *line = NULL; 1485 char *line = NULL;
1488 size_t n; 1486 size_t n;
@@ -1520,7 +1518,7 @@ static int perf_session__create_module_maps(struct perf_session *self)
1520 *sep = '\0'; 1518 *sep = '\0';
1521 1519
1522 snprintf(name, sizeof(name), "[%s]", line); 1520 snprintf(name, sizeof(name), "[%s]", line);
1523 map = perf_session__new_module_map(self, start, name); 1521 map = map_groups__new_module(self, start, name);
1524 if (map == NULL) 1522 if (map == NULL)
1525 goto out_delete_line; 1523 goto out_delete_line;
1526 dso__kernel_module_get_build_id(map->dso); 1524 dso__kernel_module_get_build_id(map->dso);
@@ -1529,7 +1527,7 @@ static int perf_session__create_module_maps(struct perf_session *self)
1529 free(line); 1527 free(line);
1530 fclose(file); 1528 fclose(file);
1531 1529
1532 return perf_session__set_modules_path(self); 1530 return map_groups__set_modules_path(self);
1533 1531
1534out_delete_line: 1532out_delete_line:
1535 free(line); 1533 free(line);
@@ -1538,7 +1536,6 @@ out_failure:
1538} 1536}
1539 1537
1540static int dso__load_vmlinux(struct dso *self, struct map *map, 1538static int dso__load_vmlinux(struct dso *self, struct map *map,
1541 struct perf_session *session,
1542 const char *vmlinux, symbol_filter_t filter) 1539 const char *vmlinux, symbol_filter_t filter)
1543{ 1540{
1544 int err = -1, fd; 1541 int err = -1, fd;
@@ -1572,14 +1569,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1572 return -1; 1569 return -1;
1573 1570
1574 dso__set_loaded(self, map->type); 1571 dso__set_loaded(self, map->type);
1575 err = dso__load_sym(self, map, session, vmlinux, fd, filter, 1, 0); 1572 err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
1576 close(fd); 1573 close(fd);
1577 1574
1578 return err; 1575 return err;
1579} 1576}
1580 1577
1581int dso__load_vmlinux_path(struct dso *self, struct map *map, 1578int dso__load_vmlinux_path(struct dso *self, struct map *map,
1582 struct perf_session *session, symbol_filter_t filter) 1579 symbol_filter_t filter)
1583{ 1580{
1584 int i, err = 0; 1581 int i, err = 0;
1585 1582
@@ -1587,8 +1584,7 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
1587 vmlinux_path__nr_entries); 1584 vmlinux_path__nr_entries);
1588 1585
1589 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1586 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1590 err = dso__load_vmlinux(self, map, session, vmlinux_path[i], 1587 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1591 filter);
1592 if (err > 0) { 1588 if (err > 0) {
1593 pr_debug("Using %s for symbols\n", vmlinux_path[i]); 1589 pr_debug("Using %s for symbols\n", vmlinux_path[i]);
1594 dso__set_long_name(self, strdup(vmlinux_path[i])); 1590 dso__set_long_name(self, strdup(vmlinux_path[i]));
@@ -1600,7 +1596,7 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
1600} 1596}
1601 1597
1602static int dso__load_kernel_sym(struct dso *self, struct map *map, 1598static int dso__load_kernel_sym(struct dso *self, struct map *map,
1603 struct perf_session *session, symbol_filter_t filter) 1599 symbol_filter_t filter)
1604{ 1600{
1605 int err; 1601 int err;
1606 const char *kallsyms_filename = NULL; 1602 const char *kallsyms_filename = NULL;
@@ -1621,13 +1617,13 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1621 * match. 1617 * match.
1622 */ 1618 */
1623 if (symbol_conf.vmlinux_name != NULL) { 1619 if (symbol_conf.vmlinux_name != NULL) {
1624 err = dso__load_vmlinux(self, map, session, 1620 err = dso__load_vmlinux(self, map,
1625 symbol_conf.vmlinux_name, filter); 1621 symbol_conf.vmlinux_name, filter);
1626 goto out_try_fixup; 1622 goto out_try_fixup;
1627 } 1623 }
1628 1624
1629 if (vmlinux_path != NULL) { 1625 if (vmlinux_path != NULL) {
1630 err = dso__load_vmlinux_path(self, map, session, filter); 1626 err = dso__load_vmlinux_path(self, map, filter);
1631 if (err > 0) 1627 if (err > 0)
1632 goto out_fixup; 1628 goto out_fixup;
1633 } 1629 }
@@ -1675,7 +1671,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1675 } 1671 }
1676 1672
1677do_kallsyms: 1673do_kallsyms:
1678 err = dso__load_kallsyms(self, kallsyms_filename, map, session, filter); 1674 err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1679 free(kallsyms_allocated_filename); 1675 free(kallsyms_allocated_filename);
1680 1676
1681out_try_fixup: 1677out_try_fixup:
@@ -1812,30 +1808,23 @@ int __map_groups__create_kernel_maps(struct map_groups *self,
1812 enum map_type type; 1808 enum map_type type;
1813 1809
1814 for (type = 0; type < MAP__NR_TYPES; ++type) { 1810 for (type = 0; type < MAP__NR_TYPES; ++type) {
1811 struct kmap *kmap;
1812
1815 vmlinux_maps[type] = map__new2(0, kernel, type); 1813 vmlinux_maps[type] = map__new2(0, kernel, type);
1816 if (vmlinux_maps[type] == NULL) 1814 if (vmlinux_maps[type] == NULL)
1817 return -1; 1815 return -1;
1818 1816
1819 vmlinux_maps[type]->map_ip = 1817 vmlinux_maps[type]->map_ip =
1820 vmlinux_maps[type]->unmap_ip = identity__map_ip; 1818 vmlinux_maps[type]->unmap_ip = identity__map_ip;
1819
1820 kmap = map__kmap(vmlinux_maps[type]);
1821 kmap->kmaps = self;
1821 map_groups__insert(self, vmlinux_maps[type]); 1822 map_groups__insert(self, vmlinux_maps[type]);
1822 } 1823 }
1823 1824
1824 return 0; 1825 return 0;
1825} 1826}
1826 1827
1827static int map_groups__create_kernel_maps(struct map_groups *self,
1828 struct map *vmlinux_maps[MAP__NR_TYPES],
1829 const char *vmlinux)
1830{
1831 struct dso *kernel = dsos__create_kernel(vmlinux);
1832
1833 if (kernel == NULL)
1834 return -1;
1835
1836 return __map_groups__create_kernel_maps(self, vmlinux_maps, kernel);
1837}
1838
1839static void vmlinux_path__exit(void) 1828static void vmlinux_path__exit(void)
1840{ 1829{
1841 while (--vmlinux_path__nr_entries >= 0) { 1830 while (--vmlinux_path__nr_entries >= 0) {
@@ -1941,19 +1930,22 @@ out_free_comm_list:
1941 return -1; 1930 return -1;
1942} 1931}
1943 1932
1944int perf_session__create_kernel_maps(struct perf_session *self) 1933int map_groups__create_kernel_maps(struct map_groups *self,
1934 struct map *vmlinux_maps[MAP__NR_TYPES])
1945{ 1935{
1946 if (map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps, 1936 struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name);
1947 symbol_conf.vmlinux_name) < 0) 1937
1938 if (kernel == NULL)
1939 return -1;
1940
1941 if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0)
1948 return -1; 1942 return -1;
1949 1943
1950 if (symbol_conf.use_modules && 1944 if (symbol_conf.use_modules && map_groups__create_modules(self) < 0)
1951 perf_session__create_module_maps(self) < 0) 1945 return -1;
1952 pr_debug("Failed to load list of modules for session %s, "
1953 "continuing...\n", self->filename);
1954 /* 1946 /*
1955 * Now that we have all the maps created, just set the ->end of them: 1947 * Now that we have all the maps created, just set the ->end of them:
1956 */ 1948 */
1957 map_groups__fixup_end(&self->kmaps); 1949 map_groups__fixup_end(self);
1958 return 0; 1950 return 0;
1959} 1951}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 124302778c09..e6a59e5c2bea 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -80,6 +80,12 @@ static inline void *symbol__priv(struct symbol *self)
80 return ((void *)self) - symbol_conf.priv_size; 80 return ((void *)self) - symbol_conf.priv_size;
81} 81}
82 82
83struct ref_reloc_sym {
84 const char *name;
85 u64 addr;
86 u64 unrelocated_addr;
87};
88
83struct addr_location { 89struct addr_location {
84 struct thread *thread; 90 struct thread *thread;
85 struct map *map; 91 struct map *map;
@@ -126,12 +132,11 @@ static inline struct dso *dsos__findnew(const char *name)
126 return __dsos__findnew(&dsos__user, name); 132 return __dsos__findnew(&dsos__user, name);
127} 133}
128 134
129struct perf_session; 135int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
130
131int dso__load(struct dso *self, struct map *map, struct perf_session *session,
132 symbol_filter_t filter);
133int dso__load_vmlinux_path(struct dso *self, struct map *map, 136int dso__load_vmlinux_path(struct dso *self, struct map *map,
134 struct perf_session *session, symbol_filter_t filter); 137 symbol_filter_t filter);
138int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
139 symbol_filter_t filter);
135void dsos__fprintf(FILE *fp); 140void dsos__fprintf(FILE *fp);
136size_t dsos__fprintf_buildid(FILE *fp, bool with_hits); 141size_t dsos__fprintf_buildid(FILE *fp, bool with_hits);
137 142
@@ -156,9 +161,5 @@ int kallsyms__parse(const char *filename, void *arg,
156int symbol__init(void); 161int symbol__init(void);
157bool symbol_type__is_a(char symbol_type, enum map_type map_type); 162bool symbol_type__is_a(char symbol_type, enum map_type map_type);
158 163
159int perf_session__create_kernel_maps(struct perf_session *self);
160
161struct map *perf_session__new_module_map(struct perf_session *self, u64 start,
162 const char *filename);
163extern struct dso *vdso; 164extern struct dso *vdso;
164#endif /* __PERF_SYMBOL */ 165#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 4a08dcf50b68..634b7f7140d5 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -282,14 +282,13 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
282} 282}
283 283
284struct symbol *map_groups__find_symbol(struct map_groups *self, 284struct symbol *map_groups__find_symbol(struct map_groups *self,
285 struct perf_session *session,
286 enum map_type type, u64 addr, 285 enum map_type type, u64 addr,
287 symbol_filter_t filter) 286 symbol_filter_t filter)
288{ 287{
289 struct map *map = map_groups__find(self, type, addr); 288 struct map *map = map_groups__find(self, type, addr);
290 289
291 if (map != NULL) 290 if (map != NULL)
292 return map__find_symbol(map, session, map->map_ip(map, addr), filter); 291 return map__find_symbol(map, map->map_ip(map, addr), filter);
293 292
294 return NULL; 293 return NULL;
295} 294}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e35653c1817c..56f317b8a06c 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -59,15 +59,14 @@ void thread__find_addr_location(struct thread *self,
59 struct addr_location *al, 59 struct addr_location *al,
60 symbol_filter_t filter); 60 symbol_filter_t filter);
61struct symbol *map_groups__find_symbol(struct map_groups *self, 61struct symbol *map_groups__find_symbol(struct map_groups *self,
62 struct perf_session *session,
63 enum map_type type, u64 addr, 62 enum map_type type, u64 addr,
64 symbol_filter_t filter); 63 symbol_filter_t filter);
65 64
66static inline struct symbol * 65static inline struct symbol *map_groups__find_function(struct map_groups *self,
67map_groups__find_function(struct map_groups *self, struct perf_session *session, 66 u64 addr,
68 u64 addr, symbol_filter_t filter) 67 symbol_filter_t filter)
69{ 68{
70 return map_groups__find_symbol(self, session, MAP__FUNCTION, addr, filter); 69 return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
71} 70}
72 71
73struct map *map_groups__find_by_name(struct map_groups *self, 72struct map *map_groups__find_by_name(struct map_groups *self,
@@ -76,4 +75,9 @@ struct map *map_groups__find_by_name(struct map_groups *self,
76int __map_groups__create_kernel_maps(struct map_groups *self, 75int __map_groups__create_kernel_maps(struct map_groups *self,
77 struct map *vmlinux_maps[MAP__NR_TYPES], 76 struct map *vmlinux_maps[MAP__NR_TYPES],
78 struct dso *kernel); 77 struct dso *kernel);
78int map_groups__create_kernel_maps(struct map_groups *self,
79 struct map *vmlinux_maps[MAP__NR_TYPES]);
80
81struct map *map_groups__new_module(struct map_groups *self, u64 start,
82 const char *filename);
79#endif /* __PERF_THREAD_H */ 83#endif /* __PERF_THREAD_H */