diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-10-07 12:48:56 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-10-08 13:27:11 -0400 |
commit | 2e538c4a1847291cf01218d4fe7bb4dc60fef7cf (patch) | |
tree | 7c2b04cf627ef339feab565e5633a57f2ead5a49 /tools/perf/util/symbol.c | |
parent | da21d1b547cbaa2c026cf645753651c25d340923 (diff) |
perf tools: Improve kernel/modules symbol lookup
This removes the ovelapping of vmlinux addresses with modules,
using the ELF section name when using --vmlinux and creating a
unique DSO name when using /proc/kallsyms ([kernel].N).
This is done by creating multiple 'struct map' instances for
address ranges backed by DSOs that have just the symbols for that
range and a name that is derived from the ELF section name.o
Now it is possible to ask for just the symbols in some particular
kernel section:
$ perf report -m --vmlinux ../build/tip-recvmmsg/vmlinux \
--dsos [kernel].vsyscall_fn | head -15
52.73% Xorg [.] vread_hpet
18.61% firefox [.] vread_hpet
14.50% npviewer.bin [.] vread_hpet
6.83% compiz [.] vread_hpet
5.73% glxgears [.] vread_hpet
0.63% java [.] vread_hpet
0.30% gnome-terminal [.] vread_hpet
0.23% perf [.] vread_hpet
0.18% xchat [.] vread_hpet
$
Now we don't have to first lookup the list of modules and then, if
it fails, vmlinux symbols, its just a simple lookup for the map
then the symbols, just like for threads.
Reports generated using /proc/kallsyms and --vmlinux should provide
the same results, modulo the DSO name for sections other than
".text".
But they don't right now because things like:
ffffffff81011c20-ffffffff81012068 system_call
ffffffff81011c30-ffffffff81011c9b system_call_after_swapgs
ffffffff81011c9c-ffffffff81011cb6 system_call_fastpath
ffffffff81011cb7-ffffffff81011cbb ret_from_sys_call
I.e. overlapping symbols, again some ASM special case that we have
to fixup.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <1254934136-8503-1-git-send-email-acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 288 |
1 files changed, 201 insertions, 87 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a6887f94dfe..faa84f5d4f5 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -26,27 +26,35 @@ enum dso_origin { | |||
26 | 26 | ||
27 | static void dsos__add(struct dso *dso); | 27 | static void dsos__add(struct dso *dso); |
28 | static struct dso *dsos__find(const char *name); | 28 | static struct dso *dsos__find(const char *name); |
29 | static struct map *map__new2(u64 start, struct dso *dso); | ||
30 | static void kernel_maps__insert(struct map *map); | ||
29 | 31 | ||
30 | static struct rb_root kernel_maps; | 32 | static struct rb_root kernel_maps; |
31 | 33 | ||
32 | static void dso__set_symbols_end(struct dso *self) | 34 | static void dso__fixup_sym_end(struct dso *self) |
33 | { | 35 | { |
34 | struct rb_node *nd, *prevnd = rb_first(&self->syms); | 36 | struct rb_node *nd, *prevnd = rb_first(&self->syms); |
37 | struct symbol *curr, *prev; | ||
35 | 38 | ||
36 | if (prevnd == NULL) | 39 | if (prevnd == NULL) |
37 | return; | 40 | return; |
38 | 41 | ||
42 | curr = rb_entry(prevnd, struct symbol, rb_node); | ||
43 | |||
39 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { | 44 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { |
40 | struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node), | 45 | prev = curr; |
41 | *curr = rb_entry(nd, struct symbol, rb_node); | 46 | curr = rb_entry(nd, struct symbol, rb_node); |
42 | 47 | ||
43 | if (prev->end == prev->start) | 48 | if (prev->end == prev->start) |
44 | prev->end = curr->start - 1; | 49 | prev->end = curr->start - 1; |
45 | prevnd = nd; | ||
46 | } | 50 | } |
51 | |||
52 | /* Last entry */ | ||
53 | if (curr->end == curr->start) | ||
54 | curr->end = roundup(curr->start, 4096); | ||
47 | } | 55 | } |
48 | 56 | ||
49 | static void kernel_maps__fixup_sym_end(void) | 57 | static void kernel_maps__fixup_end(void) |
50 | { | 58 | { |
51 | struct map *prev, *curr; | 59 | struct map *prev, *curr; |
52 | struct rb_node *nd, *prevnd = rb_first(&kernel_maps); | 60 | struct rb_node *nd, *prevnd = rb_first(&kernel_maps); |
@@ -55,13 +63,17 @@ static void kernel_maps__fixup_sym_end(void) | |||
55 | return; | 63 | return; |
56 | 64 | ||
57 | curr = rb_entry(prevnd, struct map, rb_node); | 65 | curr = rb_entry(prevnd, struct map, rb_node); |
58 | dso__set_symbols_end(curr->dso); | ||
59 | 66 | ||
60 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { | 67 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { |
61 | prev = curr; | 68 | prev = curr; |
62 | curr = rb_entry(nd, struct map, rb_node); | 69 | curr = rb_entry(nd, struct map, rb_node); |
63 | prev->end = curr->start - 1; | 70 | prev->end = curr->start - 1; |
64 | dso__set_symbols_end(curr->dso); | 71 | } |
72 | |||
73 | nd = rb_last(&curr->dso->syms); | ||
74 | if (nd) { | ||
75 | struct symbol *sym = rb_entry(nd, struct symbol, rb_node); | ||
76 | curr->end = sym->end; | ||
65 | } | 77 | } |
66 | } | 78 | } |
67 | 79 | ||
@@ -200,13 +212,16 @@ size_t dso__fprintf(struct dso *self, FILE *fp) | |||
200 | return ret; | 212 | return ret; |
201 | } | 213 | } |
202 | 214 | ||
203 | static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v) | 215 | /* |
216 | * Loads the function entries in /proc/kallsyms into kernel_map->dso, | ||
217 | * so that we can in the next step set the symbol ->end address and then | ||
218 | * call kernel_maps__split_kallsyms. | ||
219 | */ | ||
220 | static int kernel_maps__load_all_kallsyms(int v) | ||
204 | { | 221 | { |
205 | struct map *map = kernel_map; | ||
206 | char *line = NULL; | 222 | char *line = NULL; |
207 | size_t n; | 223 | size_t n; |
208 | FILE *file = fopen("/proc/kallsyms", "r"); | 224 | FILE *file = fopen("/proc/kallsyms", "r"); |
209 | int count = 0; | ||
210 | 225 | ||
211 | if (file == NULL) | 226 | if (file == NULL) |
212 | goto out_failure; | 227 | goto out_failure; |
@@ -216,7 +231,7 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v) | |||
216 | struct symbol *sym; | 231 | struct symbol *sym; |
217 | int line_len, len; | 232 | int line_len, len; |
218 | char symbol_type; | 233 | char symbol_type; |
219 | char *module, *symbol_name; | 234 | char *symbol_name; |
220 | 235 | ||
221 | line_len = getline(&line, &n, file); | 236 | line_len = getline(&line, &n, file); |
222 | if (line_len < 0) | 237 | if (line_len < 0) |
@@ -241,20 +256,55 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v) | |||
241 | continue; | 256 | continue; |
242 | 257 | ||
243 | symbol_name = line + len + 2; | 258 | symbol_name = line + len + 2; |
244 | module = strchr(symbol_name, '\t'); | 259 | /* |
245 | if (module) { | 260 | * Will fix up the end later, when we have all symbols sorted. |
246 | char *module_name_end; | 261 | */ |
262 | sym = symbol__new(start, 0, symbol_name, | ||
263 | kernel_map->dso->sym_priv_size, v); | ||
247 | 264 | ||
265 | if (sym == NULL) | ||
266 | goto out_delete_line; | ||
267 | |||
268 | dso__insert_symbol(kernel_map->dso, sym); | ||
269 | } | ||
270 | |||
271 | free(line); | ||
272 | fclose(file); | ||
273 | |||
274 | return 0; | ||
275 | |||
276 | out_delete_line: | ||
277 | free(line); | ||
278 | out_failure: | ||
279 | return -1; | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Split the symbols into maps, making sure there are no overlaps, i.e. the | ||
284 | * kernel range is broken in several maps, named [kernel].N, as we don't have | ||
285 | * the original ELF section names vmlinux have. | ||
286 | */ | ||
287 | static int kernel_maps__split_kallsyms(symbol_filter_t filter, int use_modules) | ||
288 | { | ||
289 | struct map *map = kernel_map; | ||
290 | struct symbol *pos; | ||
291 | int count = 0; | ||
292 | struct rb_node *next = rb_first(&kernel_map->dso->syms); | ||
293 | int kernel_range = 0; | ||
294 | |||
295 | while (next) { | ||
296 | char *module; | ||
297 | |||
298 | pos = rb_entry(next, struct symbol, rb_node); | ||
299 | next = rb_next(&pos->rb_node); | ||
300 | |||
301 | module = strchr(pos->name, '\t'); | ||
302 | if (module) { | ||
248 | if (!use_modules) | 303 | if (!use_modules) |
249 | continue; | 304 | goto delete_symbol; |
250 | *module = '\0'; | 305 | |
251 | module = strchr(module + 1, '['); | 306 | *module++ = '\0'; |
252 | if (!module) | 307 | |
253 | continue; | ||
254 | module_name_end = strchr(module + 1, ']'); | ||
255 | if (!module_name_end) | ||
256 | continue; | ||
257 | *(module_name_end + 1) = '\0'; | ||
258 | if (strcmp(map->dso->name, module)) { | 308 | if (strcmp(map->dso->name, module)) { |
259 | map = kernel_maps__find_by_dso_name(module); | 309 | map = kernel_maps__find_by_dso_name(module); |
260 | if (!map) { | 310 | if (!map) { |
@@ -263,50 +313,77 @@ static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v) | |||
263 | return -1; | 313 | return -1; |
264 | } | 314 | } |
265 | } | 315 | } |
266 | start = map->map_ip(map, start); | 316 | /* |
267 | } else | 317 | * So that we look just like we get from .ko files, |
268 | map = kernel_map; | 318 | * i.e. not prelinked, relative to map->start. |
269 | /* | 319 | */ |
270 | * Well fix up the end later, when we have all sorted. | 320 | pos->start = map->map_ip(map, pos->start); |
271 | */ | 321 | pos->end = map->map_ip(map, pos->end); |
272 | sym = symbol__new(start, 0, symbol_name, | 322 | } else if (map != kernel_map) { |
273 | map->dso->sym_priv_size, v); | 323 | char dso_name[PATH_MAX]; |
324 | struct dso *dso; | ||
325 | |||
326 | snprintf(dso_name, sizeof(dso_name), "[kernel].%d", | ||
327 | kernel_range++); | ||
328 | |||
329 | dso = dso__new(dso_name, | ||
330 | kernel_map->dso->sym_priv_size); | ||
331 | if (dso == NULL) | ||
332 | return -1; | ||
333 | |||
334 | map = map__new2(pos->start, dso); | ||
335 | if (map == NULL) { | ||
336 | dso__delete(dso); | ||
337 | return -1; | ||
338 | } | ||
274 | 339 | ||
275 | if (sym == NULL) | 340 | map->map_ip = vdso__map_ip; |
276 | goto out_delete_line; | 341 | kernel_maps__insert(map); |
342 | ++kernel_range; | ||
343 | } | ||
277 | 344 | ||
278 | if (filter && filter(map, sym)) | 345 | if (filter && filter(map, pos)) { |
279 | symbol__delete(sym, map->dso->sym_priv_size); | 346 | delete_symbol: |
280 | else { | 347 | rb_erase(&pos->rb_node, &kernel_map->dso->syms); |
281 | dso__insert_symbol(map->dso, sym); | 348 | symbol__delete(pos, kernel_map->dso->sym_priv_size); |
349 | } else { | ||
350 | if (map != kernel_map) { | ||
351 | rb_erase(&pos->rb_node, &kernel_map->dso->syms); | ||
352 | dso__insert_symbol(map->dso, pos); | ||
353 | } | ||
282 | count++; | 354 | count++; |
283 | } | 355 | } |
284 | } | 356 | } |
285 | 357 | ||
286 | free(line); | ||
287 | fclose(file); | ||
288 | |||
289 | return count; | 358 | return count; |
359 | } | ||
290 | 360 | ||
291 | out_delete_line: | 361 | |
292 | free(line); | 362 | static int kernel_maps__load_kallsyms(symbol_filter_t filter, |
293 | out_failure: | 363 | int use_modules, int v) |
294 | return -1; | 364 | { |
365 | if (kernel_maps__load_all_kallsyms(v)) | ||
366 | return -1; | ||
367 | |||
368 | dso__fixup_sym_end(kernel_map->dso); | ||
369 | |||
370 | return kernel_maps__split_kallsyms(filter, use_modules); | ||
295 | } | 371 | } |
296 | 372 | ||
297 | static size_t kernel_maps__fprintf(FILE *fp) | 373 | static size_t kernel_maps__fprintf(FILE *fp, int v) |
298 | { | 374 | { |
299 | size_t printed = fprintf(stderr, "Kernel maps:\n"); | 375 | size_t printed = fprintf(stderr, "Kernel maps:\n"); |
300 | struct rb_node *nd; | 376 | struct rb_node *nd; |
301 | 377 | ||
302 | printed += map__fprintf(kernel_map, fp); | ||
303 | printed += dso__fprintf(kernel_map->dso, fp); | ||
304 | |||
305 | for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) { | 378 | for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) { |
306 | struct map *pos = rb_entry(nd, struct map, rb_node); | 379 | struct map *pos = rb_entry(nd, struct map, rb_node); |
307 | 380 | ||
381 | printed += fprintf(fp, "Map:"); | ||
308 | printed += map__fprintf(pos, fp); | 382 | printed += map__fprintf(pos, fp); |
309 | printed += dso__fprintf(pos->dso, fp); | 383 | if (v > 1) { |
384 | printed += dso__fprintf(pos->dso, fp); | ||
385 | printed += fprintf(fp, "--\n"); | ||
386 | } | ||
310 | } | 387 | } |
311 | 388 | ||
312 | return printed + fprintf(stderr, "END kernel maps\n"); | 389 | return printed + fprintf(stderr, "END kernel maps\n"); |
@@ -594,6 +671,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
594 | int fd, symbol_filter_t filter, int kernel, | 671 | int fd, symbol_filter_t filter, int kernel, |
595 | int kmodule, int v) | 672 | int kmodule, int v) |
596 | { | 673 | { |
674 | struct map *curr_map = map; | ||
675 | struct dso *curr_dso = self; | ||
676 | size_t dso_name_len = strlen(self->short_name); | ||
597 | Elf_Data *symstrs, *secstrs; | 677 | Elf_Data *symstrs, *secstrs; |
598 | uint32_t nr_syms; | 678 | uint32_t nr_syms; |
599 | int err = -1; | 679 | int err = -1; |
@@ -660,10 +740,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
660 | elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { | 740 | elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { |
661 | struct symbol *f; | 741 | struct symbol *f; |
662 | const char *elf_name; | 742 | const char *elf_name; |
663 | char *demangled; | 743 | char *demangled = NULL; |
664 | int is_label = elf_sym__is_label(&sym); | 744 | int is_label = elf_sym__is_label(&sym); |
665 | const char *section_name; | 745 | const char *section_name; |
666 | u64 sh_offset = 0; | ||
667 | 746 | ||
668 | if (!is_label && !elf_sym__is_function(&sym)) | 747 | if (!is_label && !elf_sym__is_function(&sym)) |
669 | continue; | 748 | continue; |
@@ -677,14 +756,51 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
677 | if (is_label && !elf_sec__is_text(&shdr, secstrs)) | 756 | if (is_label && !elf_sec__is_text(&shdr, secstrs)) |
678 | continue; | 757 | continue; |
679 | 758 | ||
759 | elf_name = elf_sym__name(&sym, symstrs); | ||
680 | section_name = elf_sec__name(&shdr, secstrs); | 760 | section_name = elf_sec__name(&shdr, secstrs); |
681 | 761 | ||
682 | if ((kernel || kmodule)) { | 762 | if (kernel || kmodule) { |
683 | if (strstr(section_name, ".init")) | 763 | char dso_name[PATH_MAX]; |
684 | sh_offset = shdr.sh_offset; | 764 | |
765 | if (strcmp(section_name, | ||
766 | curr_dso->short_name + dso_name_len) == 0) | ||
767 | goto new_symbol; | ||
768 | |||
769 | if (strcmp(section_name, ".text") == 0) { | ||
770 | curr_map = map; | ||
771 | curr_dso = self; | ||
772 | goto new_symbol; | ||
773 | } | ||
774 | |||
775 | snprintf(dso_name, sizeof(dso_name), | ||
776 | "%s%s", self->short_name, section_name); | ||
777 | |||
778 | curr_map = kernel_maps__find_by_dso_name(dso_name); | ||
779 | if (curr_map == NULL) { | ||
780 | u64 start = sym.st_value; | ||
781 | |||
782 | if (kmodule) | ||
783 | start += map->start + shdr.sh_offset; | ||
784 | |||
785 | curr_dso = dso__new(dso_name, self->sym_priv_size); | ||
786 | if (curr_dso == NULL) | ||
787 | goto out_elf_end; | ||
788 | curr_map = map__new2(start, curr_dso); | ||
789 | if (curr_map == NULL) { | ||
790 | dso__delete(curr_dso); | ||
791 | goto out_elf_end; | ||
792 | } | ||
793 | curr_map->map_ip = vdso__map_ip; | ||
794 | curr_dso->origin = DSO__ORIG_KERNEL; | ||
795 | kernel_maps__insert(curr_map); | ||
796 | dsos__add(curr_dso); | ||
797 | } else | ||
798 | curr_dso = curr_map->dso; | ||
799 | |||
800 | goto new_symbol; | ||
685 | } | 801 | } |
686 | 802 | ||
687 | if (self->adjust_symbols) { | 803 | if (curr_dso->adjust_symbols) { |
688 | if (v > 2) | 804 | if (v > 2) |
689 | printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", | 805 | printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", |
690 | (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); | 806 | (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); |
@@ -696,25 +812,29 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
696 | * DWARF DW_compile_unit has this, but we don't always have access | 812 | * DWARF DW_compile_unit has this, but we don't always have access |
697 | * to it... | 813 | * to it... |
698 | */ | 814 | */ |
699 | elf_name = elf_sym__name(&sym, symstrs); | ||
700 | demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); | 815 | demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); |
701 | if (demangled != NULL) | 816 | if (demangled != NULL) |
702 | elf_name = demangled; | 817 | elf_name = demangled; |
703 | 818 | new_symbol: | |
704 | f = symbol__new(sym.st_value + sh_offset, sym.st_size, elf_name, | 819 | f = symbol__new(sym.st_value, sym.st_size, elf_name, |
705 | self->sym_priv_size, v); | 820 | curr_dso->sym_priv_size, v); |
706 | free(demangled); | 821 | free(demangled); |
707 | if (!f) | 822 | if (!f) |
708 | goto out_elf_end; | 823 | goto out_elf_end; |
709 | 824 | ||
710 | if (filter && filter(map, f)) | 825 | if (filter && filter(curr_map, f)) |
711 | symbol__delete(f, self->sym_priv_size); | 826 | symbol__delete(f, curr_dso->sym_priv_size); |
712 | else { | 827 | else { |
713 | dso__insert_symbol(self, f); | 828 | dso__insert_symbol(curr_dso, f); |
714 | nr++; | 829 | nr++; |
715 | } | 830 | } |
716 | } | 831 | } |
717 | 832 | ||
833 | /* | ||
834 | * For misannotated, zeroed, ASM function sizes. | ||
835 | */ | ||
836 | if (nr > 0) | ||
837 | dso__fixup_sym_end(self); | ||
718 | err = nr; | 838 | err = nr; |
719 | out_elf_end: | 839 | out_elf_end: |
720 | elf_end(elf); | 840 | elf_end(elf); |
@@ -883,27 +1003,17 @@ static void kernel_maps__insert(struct map *map) | |||
883 | 1003 | ||
884 | struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp) | 1004 | struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp) |
885 | { | 1005 | { |
886 | /* | ||
887 | * We can't have kernel_map in kernel_maps because it spans an address | ||
888 | * space that includes the modules. The right way to fix this is to | ||
889 | * create several maps, so that we don't have overlapping ranges with | ||
890 | * modules. For now lets look first on the kernel dso. | ||
891 | */ | ||
892 | struct map *map = maps__find(&kernel_maps, ip); | 1006 | struct map *map = maps__find(&kernel_maps, ip); |
893 | struct symbol *sym; | 1007 | |
1008 | if (mapp) | ||
1009 | *mapp = map; | ||
894 | 1010 | ||
895 | if (map) { | 1011 | if (map) { |
896 | ip = map->map_ip(map, ip); | 1012 | ip = map->map_ip(map, ip); |
897 | sym = map->dso->find_symbol(map->dso, ip); | 1013 | return map->dso->find_symbol(map->dso, ip); |
898 | } else { | ||
899 | map = kernel_map; | ||
900 | sym = map->dso->find_symbol(map->dso, ip); | ||
901 | } | 1014 | } |
902 | 1015 | ||
903 | if (mapp) | 1016 | return NULL; |
904 | *mapp = map; | ||
905 | |||
906 | return sym; | ||
907 | } | 1017 | } |
908 | 1018 | ||
909 | struct map *kernel_maps__find_by_dso_name(const char *name) | 1019 | struct map *kernel_maps__find_by_dso_name(const char *name) |
@@ -994,6 +1104,14 @@ static int dsos__load_modules_sym_dir(char *dirname, | |||
994 | last = rb_last(&map->dso->syms); | 1104 | last = rb_last(&map->dso->syms); |
995 | if (last) { | 1105 | if (last) { |
996 | struct symbol *sym; | 1106 | struct symbol *sym; |
1107 | /* | ||
1108 | * We do this here as well, even having the | ||
1109 | * symbol size found in the symtab because | ||
1110 | * misannotated ASM symbols may have the size | ||
1111 | * set to zero. | ||
1112 | */ | ||
1113 | dso__fixup_sym_end(map->dso); | ||
1114 | |||
997 | sym = rb_entry(last, struct symbol, rb_node); | 1115 | sym = rb_entry(last, struct symbol, rb_node); |
998 | map->end = map->start + sym->end; | 1116 | map->end = map->start + sym->end; |
999 | } | 1117 | } |
@@ -1163,17 +1281,11 @@ int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, | |||
1163 | } | 1281 | } |
1164 | 1282 | ||
1165 | if (err <= 0) | 1283 | if (err <= 0) |
1166 | err = maps__load_kallsyms(filter, use_modules, v); | 1284 | err = kernel_maps__load_kallsyms(filter, use_modules, v); |
1167 | 1285 | ||
1168 | if (err > 0) { | 1286 | if (err > 0) { |
1169 | struct rb_node *node = rb_first(&dso->syms); | 1287 | struct rb_node *node = rb_first(&dso->syms); |
1170 | struct symbol *sym = rb_entry(node, struct symbol, rb_node); | 1288 | struct symbol *sym = rb_entry(node, struct symbol, rb_node); |
1171 | /* | ||
1172 | * Now that we have all sorted out, just set the ->end of all | ||
1173 | * symbols that still don't have it. | ||
1174 | */ | ||
1175 | dso__set_symbols_end(dso); | ||
1176 | kernel_maps__fixup_sym_end(); | ||
1177 | 1289 | ||
1178 | kernel_map->start = sym->start; | 1290 | kernel_map->start = sym->start; |
1179 | node = rb_last(&dso->syms); | 1291 | node = rb_last(&dso->syms); |
@@ -1181,14 +1293,16 @@ int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, | |||
1181 | kernel_map->end = sym->end; | 1293 | kernel_map->end = sym->end; |
1182 | 1294 | ||
1183 | dso->origin = DSO__ORIG_KERNEL; | 1295 | dso->origin = DSO__ORIG_KERNEL; |
1296 | kernel_maps__insert(kernel_map); | ||
1184 | /* | 1297 | /* |
1185 | * XXX See kernel_maps__find_symbol comment | 1298 | * Now that we have all sorted out, just set the ->end of all |
1186 | * kernel_maps__insert(kernel_map) | 1299 | * maps: |
1187 | */ | 1300 | */ |
1301 | kernel_maps__fixup_end(); | ||
1188 | dsos__add(dso); | 1302 | dsos__add(dso); |
1189 | 1303 | ||
1190 | if (v > 0) | 1304 | if (v > 0) |
1191 | kernel_maps__fprintf(stderr); | 1305 | kernel_maps__fprintf(stderr, v); |
1192 | } | 1306 | } |
1193 | 1307 | ||
1194 | return err; | 1308 | return err; |