aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-02-03 13:52:00 -0500
committerIngo Molnar <mingo@elte.hu>2010-02-04 03:33:24 -0500
commit9de89fe7c577847877ae00ea1aa6315559b10243 (patch)
tree523bcd2c2b1e2a839100b472ff864860cdc8caeb /tools/perf/util
parentb8f46c5a34fa64fd456295388d18f50ae69d9f37 (diff)
perf symbols: Remove perf_session usage in symbols layer
I noticed while writing the first test in 'perf regtest' that to just test the symbol handling routines one needs to create a perf session, that is a layer centered on a perf.data file, events, etc, so I untied these layers. This reduces the complexity for the users as the number of parameters to most of the symbols and session APIs now was reduced while not adding more state to all the map instances by only having data that is needed to split the kernel (kallsyms and ELF symtab sections) maps and do vmlinux relocation on the main kernel map. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1265223128-11786-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-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
9 files changed, 146 insertions, 117 deletions
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 */