diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-27 13:29:16 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-27 14:21:59 -0500 |
commit | 3610583c29563e23dd038d2870f59c88438bf7a3 (patch) | |
tree | cb8d20387bcc8e37b0db2432f339387a4fd52150 /tools/perf/util | |
parent | 605ca4ba017455d39ac6991c58eb1e80fb8af48d (diff) |
perf symbols: Add a 'type' field to struct map
That way we will be able to check if the right symtab is loaded
in the underlying DSO.
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: <1259346563-12568-5-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.h | 12 | ||||
-rw-r--r-- | tools/perf/util/map.c | 12 | ||||
-rw-r--r-- | tools/perf/util/process_events.c | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 31 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 4 |
5 files changed, 41 insertions, 20 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 882a9531db97..29543bd88007 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -80,6 +80,10 @@ typedef union event_union { | |||
80 | struct sample_event sample; | 80 | struct sample_event sample; |
81 | } event_t; | 81 | } event_t; |
82 | 82 | ||
83 | enum map_type { | ||
84 | MAP__FUNCTION, | ||
85 | }; | ||
86 | |||
83 | struct map { | 87 | struct map { |
84 | union { | 88 | union { |
85 | struct rb_node rb_node; | 89 | struct rb_node rb_node; |
@@ -87,6 +91,7 @@ struct map { | |||
87 | }; | 91 | }; |
88 | u64 start; | 92 | u64 start; |
89 | u64 end; | 93 | u64 end; |
94 | enum map_type type; | ||
90 | u64 pgoff; | 95 | u64 pgoff; |
91 | u64 (*map_ip)(struct map *, u64); | 96 | u64 (*map_ip)(struct map *, u64); |
92 | u64 (*unmap_ip)(struct map *, u64); | 97 | u64 (*unmap_ip)(struct map *, u64); |
@@ -112,9 +117,10 @@ struct symbol; | |||
112 | 117 | ||
113 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); | 118 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); |
114 | 119 | ||
115 | void map__init(struct map *self, u64 start, u64 end, u64 pgoff, | 120 | void map__init(struct map *self, enum map_type type, |
116 | struct dso *dso); | 121 | u64 start, u64 end, u64 pgoff, struct dso *dso); |
117 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen); | 122 | struct map *map__new(struct mmap_event *event, enum map_type, |
123 | char *cwd, int cwdlen); | ||
118 | void map__delete(struct map *self); | 124 | void map__delete(struct map *self); |
119 | struct map *map__clone(struct map *self); | 125 | struct map *map__clone(struct map *self); |
120 | int map__overlap(struct map *l, struct map *r); | 126 | int map__overlap(struct map *l, struct map *r); |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 41c5c4a20010..52bb4c6cf74d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -20,9 +20,10 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen) | |||
20 | return n; | 20 | return n; |
21 | } | 21 | } |
22 | 22 | ||
23 | void map__init(struct map *self, u64 start, u64 end, u64 pgoff, | 23 | void map__init(struct map *self, enum map_type type, |
24 | struct dso *dso) | 24 | u64 start, u64 end, u64 pgoff, struct dso *dso) |
25 | { | 25 | { |
26 | self->type = type; | ||
26 | self->start = start; | 27 | self->start = start; |
27 | self->end = end; | 28 | self->end = end; |
28 | self->pgoff = pgoff; | 29 | self->pgoff = pgoff; |
@@ -32,7 +33,8 @@ void map__init(struct map *self, u64 start, u64 end, u64 pgoff, | |||
32 | RB_CLEAR_NODE(&self->rb_node); | 33 | RB_CLEAR_NODE(&self->rb_node); |
33 | } | 34 | } |
34 | 35 | ||
35 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen) | 36 | struct map *map__new(struct mmap_event *event, enum map_type type, |
37 | char *cwd, int cwdlen) | ||
36 | { | 38 | { |
37 | struct map *self = malloc(sizeof(*self)); | 39 | struct map *self = malloc(sizeof(*self)); |
38 | 40 | ||
@@ -63,7 +65,7 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen) | |||
63 | if (dso == NULL) | 65 | if (dso == NULL) |
64 | goto out_delete; | 66 | goto out_delete; |
65 | 67 | ||
66 | map__init(self, event->start, event->start + event->len, | 68 | map__init(self, type, event->start, event->start + event->len, |
67 | event->pgoff, dso); | 69 | event->pgoff, dso); |
68 | 70 | ||
69 | if (self->dso == vdso || anon) | 71 | if (self->dso == vdso || anon) |
@@ -103,7 +105,7 @@ void map__fixup_end(struct map *self, struct rb_root *symbols) | |||
103 | struct symbol *map__find_function(struct map *self, u64 ip, | 105 | struct symbol *map__find_function(struct map *self, u64 ip, |
104 | symbol_filter_t filter) | 106 | symbol_filter_t filter) |
105 | { | 107 | { |
106 | if (!self->dso->loaded) { | 108 | if (!dso__loaded(self->dso, self->type)) { |
107 | int nr = dso__load(self->dso, self, filter); | 109 | int nr = dso__load(self->dso, self, filter); |
108 | 110 | ||
109 | if (nr < 0) { | 111 | if (nr < 0) { |
diff --git a/tools/perf/util/process_events.c b/tools/perf/util/process_events.c index a9204363efd8..53778684641c 100644 --- a/tools/perf/util/process_events.c +++ b/tools/perf/util/process_events.c | |||
@@ -6,7 +6,7 @@ int cwdlen; | |||
6 | int | 6 | int |
7 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 7 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
8 | { | 8 | { |
9 | struct map *map = map__new(&event->mmap, cwd, cwdlen); | 9 | struct map *map = map__new(&event->mmap, MAP__FUNCTION, cwd, cwdlen); |
10 | struct thread *thread = threads__findnew(event->mmap.pid); | 10 | struct thread *thread = threads__findnew(event->mmap.pid); |
11 | 11 | ||
12 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", | 12 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 0b8a298d41ad..45a4a9a7618b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -29,7 +29,7 @@ enum dso_origin { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static void dsos__add(struct list_head *head, struct dso *dso); | 31 | static void dsos__add(struct list_head *head, struct dso *dso); |
32 | static struct map *map__new2(u64 start, struct dso *dso); | 32 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); |
33 | static void kernel_maps__insert(struct map *map); | 33 | static void kernel_maps__insert(struct map *map); |
34 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 34 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
35 | symbol_filter_t filter); | 35 | symbol_filter_t filter); |
@@ -45,6 +45,16 @@ static struct symbol_conf symbol_conf__defaults = { | |||
45 | 45 | ||
46 | static struct rb_root kernel_maps__functions; | 46 | static struct rb_root kernel_maps__functions; |
47 | 47 | ||
48 | bool dso__loaded(const struct dso *self, enum map_type type) | ||
49 | { | ||
50 | return self->loaded & (1 << type); | ||
51 | } | ||
52 | |||
53 | static void dso__set_loaded(struct dso *self, enum map_type type) | ||
54 | { | ||
55 | self->loaded |= (1 << type); | ||
56 | } | ||
57 | |||
48 | static void symbols__fixup_end(struct rb_root *self) | 58 | static void symbols__fixup_end(struct rb_root *self) |
49 | { | 59 | { |
50 | struct rb_node *nd, *prevnd = rb_first(self); | 60 | struct rb_node *nd, *prevnd = rb_first(self); |
@@ -387,7 +397,7 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
387 | if (dso == NULL) | 397 | if (dso == NULL) |
388 | return -1; | 398 | return -1; |
389 | 399 | ||
390 | map = map__new2(pos->start, dso); | 400 | map = map__new2(pos->start, dso, MAP__FUNCTION); |
391 | if (map == NULL) { | 401 | if (map == NULL) { |
392 | dso__delete(dso); | 402 | dso__delete(dso); |
393 | return -1; | 403 | return -1; |
@@ -846,7 +856,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
846 | curr_dso = dso__new(dso_name); | 856 | curr_dso = dso__new(dso_name); |
847 | if (curr_dso == NULL) | 857 | if (curr_dso == NULL) |
848 | goto out_elf_end; | 858 | goto out_elf_end; |
849 | curr_map = map__new2(start, curr_dso); | 859 | curr_map = map__new2(start, curr_dso, |
860 | MAP__FUNCTION); | ||
850 | if (curr_map == NULL) { | 861 | if (curr_map == NULL) { |
851 | dso__delete(curr_dso); | 862 | dso__delete(curr_dso); |
852 | goto out_elf_end; | 863 | goto out_elf_end; |
@@ -1076,7 +1087,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1076 | int ret = -1; | 1087 | int ret = -1; |
1077 | int fd; | 1088 | int fd; |
1078 | 1089 | ||
1079 | self->loaded = 1; | 1090 | dso__set_loaded(self, map->type); |
1080 | 1091 | ||
1081 | if (self->kernel) | 1092 | if (self->kernel) |
1082 | return dso__load_kernel_sym(self, map, filter); | 1093 | return dso__load_kernel_sym(self, map, filter); |
@@ -1275,7 +1286,7 @@ static int dsos__set_modules_path(void) | |||
1275 | * they are loaded) and for vmlinux, where only after we load all the | 1286 | * they are loaded) and for vmlinux, where only after we load all the |
1276 | * symbols we'll know where it starts and ends. | 1287 | * symbols we'll know where it starts and ends. |
1277 | */ | 1288 | */ |
1278 | static struct map *map__new2(u64 start, struct dso *dso) | 1289 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) |
1279 | { | 1290 | { |
1280 | struct map *self = malloc(sizeof(*self)); | 1291 | struct map *self = malloc(sizeof(*self)); |
1281 | 1292 | ||
@@ -1283,7 +1294,7 @@ static struct map *map__new2(u64 start, struct dso *dso) | |||
1283 | /* | 1294 | /* |
1284 | * ->end will be filled after we load all the symbols | 1295 | * ->end will be filled after we load all the symbols |
1285 | */ | 1296 | */ |
1286 | map__init(self, start, 0, 0, dso); | 1297 | map__init(self, type, start, 0, 0, dso); |
1287 | } | 1298 | } |
1288 | 1299 | ||
1289 | return self; | 1300 | return self; |
@@ -1333,7 +1344,7 @@ static int kernel_maps__create_module_maps(void) | |||
1333 | if (dso == NULL) | 1344 | if (dso == NULL) |
1334 | goto out_delete_line; | 1345 | goto out_delete_line; |
1335 | 1346 | ||
1336 | map = map__new2(start, dso); | 1347 | map = map__new2(start, dso, MAP__FUNCTION); |
1337 | if (map == NULL) { | 1348 | if (map == NULL) { |
1338 | dso__delete(dso); | 1349 | dso__delete(dso); |
1339 | goto out_delete_line; | 1350 | goto out_delete_line; |
@@ -1394,7 +1405,7 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1394 | if (fd < 0) | 1405 | if (fd < 0) |
1395 | return -1; | 1406 | return -1; |
1396 | 1407 | ||
1397 | self->loaded = 1; | 1408 | dso__set_loaded(self, map->type); |
1398 | err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0); | 1409 | err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0); |
1399 | 1410 | ||
1400 | close(fd); | 1411 | close(fd); |
@@ -1522,7 +1533,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | |||
1522 | if (kernel == NULL) | 1533 | if (kernel == NULL) |
1523 | return -1; | 1534 | return -1; |
1524 | 1535 | ||
1525 | kernel_map__functions = map__new2(0, kernel); | 1536 | kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION); |
1526 | if (kernel_map__functions == NULL) | 1537 | if (kernel_map__functions == NULL) |
1527 | goto out_delete_kernel_dso; | 1538 | goto out_delete_kernel_dso; |
1528 | 1539 | ||
@@ -1533,7 +1544,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | |||
1533 | vdso = dso__new("[vdso]"); | 1544 | vdso = dso__new("[vdso]"); |
1534 | if (vdso == NULL) | 1545 | if (vdso == NULL) |
1535 | goto out_delete_kernel_map; | 1546 | goto out_delete_kernel_map; |
1536 | vdso->loaded = 1; | 1547 | dso__set_loaded(vdso, MAP__FUNCTION); |
1537 | 1548 | ||
1538 | if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id, | 1549 | if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id, |
1539 | sizeof(kernel->build_id)) == 0) | 1550 | sizeof(kernel->build_id)) == 0) |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index fb0be9e92bf3..11d41952ce04 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -69,10 +69,10 @@ struct dso { | |||
69 | struct symbol *(*find_function)(struct dso *, u64 ip); | 69 | struct symbol *(*find_function)(struct dso *, u64 ip); |
70 | u8 adjust_symbols:1; | 70 | u8 adjust_symbols:1; |
71 | u8 slen_calculated:1; | 71 | u8 slen_calculated:1; |
72 | u8 loaded:1; | ||
73 | u8 has_build_id:1; | 72 | u8 has_build_id:1; |
74 | u8 kernel:1; | 73 | u8 kernel:1; |
75 | unsigned char origin; | 74 | unsigned char origin; |
75 | u8 loaded; | ||
76 | u8 build_id[BUILD_ID_SIZE]; | 76 | u8 build_id[BUILD_ID_SIZE]; |
77 | u16 long_name_len; | 77 | u16 long_name_len; |
78 | const char *short_name; | 78 | const char *short_name; |
@@ -85,6 +85,8 @@ void dso__delete(struct dso *self); | |||
85 | 85 | ||
86 | struct symbol *dso__find_function(struct dso *self, u64 ip); | 86 | struct symbol *dso__find_function(struct dso *self, u64 ip); |
87 | 87 | ||
88 | bool dso__loaded(const struct dso *self, enum map_type type); | ||
89 | |||
88 | struct dso *dsos__findnew(const char *name); | 90 | struct dso *dsos__findnew(const char *name); |
89 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); | 91 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); |
90 | void dsos__fprintf(FILE *fp); | 92 | void dsos__fprintf(FILE *fp); |