diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-27 13:29:18 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-27 14:21:59 -0500 |
commit | 4e06255f5cf2acf6a5abfe7df8c9690463259dea (patch) | |
tree | e351fa45e34d33fc8309cd603cc0e7b92f4e3949 /tools | |
parent | 6a4694a433a218c729d336b348a01bfc720da095 (diff) |
perf symbols: Make the kallsyms loading routines part of the dso class
So that the kallsyms loading routines are the direct counterpart
of the vmlinux loading ones, i.e. dso__load_kallsyms is the
counterpart of dso__load_vmlinux.
In the process make them also use the symbols rb tree indexed by
map->type, paving the way for supporting other types of symtabs,
such as the next one to be supported: variables.
This also allowed removal of yet another global variable:
kernel_map__functions.
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-7-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/symbol.c | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9a2dd819dee..956656fcaab 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -37,7 +37,6 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
37 | unsigned int symbol__priv_size; | 37 | unsigned int symbol__priv_size; |
38 | static int vmlinux_path__nr_entries; | 38 | static int vmlinux_path__nr_entries; |
39 | static char **vmlinux_path; | 39 | static char **vmlinux_path; |
40 | static struct map *kernel_map__functions; | ||
41 | 40 | ||
42 | static struct symbol_conf symbol_conf__defaults = { | 41 | static struct symbol_conf symbol_conf__defaults = { |
43 | .use_modules = true, | 42 | .use_modules = true, |
@@ -296,10 +295,11 @@ size_t dso__fprintf(struct dso *self, FILE *fp) | |||
296 | * so that we can in the next step set the symbol ->end address and then | 295 | * so that we can in the next step set the symbol ->end address and then |
297 | * call kernel_maps__split_kallsyms. | 296 | * call kernel_maps__split_kallsyms. |
298 | */ | 297 | */ |
299 | static int kernel_maps__load_all_kallsyms(void) | 298 | static int dso__load_all_kallsyms(struct dso *self, struct map *map) |
300 | { | 299 | { |
301 | char *line = NULL; | 300 | char *line = NULL; |
302 | size_t n; | 301 | size_t n; |
302 | struct rb_root *root = &self->symbols[map->type]; | ||
303 | FILE *file = fopen("/proc/kallsyms", "r"); | 303 | FILE *file = fopen("/proc/kallsyms", "r"); |
304 | 304 | ||
305 | if (file == NULL) | 305 | if (file == NULL) |
@@ -342,13 +342,11 @@ static int kernel_maps__load_all_kallsyms(void) | |||
342 | 342 | ||
343 | if (sym == NULL) | 343 | if (sym == NULL) |
344 | goto out_delete_line; | 344 | goto out_delete_line; |
345 | |||
346 | /* | 345 | /* |
347 | * We will pass the symbols to the filter later, in | 346 | * We will pass the symbols to the filter later, in |
348 | * kernel_maps__split_kallsyms, when we have split the | 347 | * map__split_kallsyms, when we have split the maps per module |
349 | * maps per module | ||
350 | */ | 348 | */ |
351 | symbols__insert(&kernel_map__functions->dso->symbols[MAP__FUNCTION], sym); | 349 | symbols__insert(root, sym); |
352 | } | 350 | } |
353 | 351 | ||
354 | free(line); | 352 | free(line); |
@@ -367,12 +365,14 @@ out_failure: | |||
367 | * kernel range is broken in several maps, named [kernel].N, as we don't have | 365 | * kernel range is broken in several maps, named [kernel].N, as we don't have |
368 | * the original ELF section names vmlinux have. | 366 | * the original ELF section names vmlinux have. |
369 | */ | 367 | */ |
370 | static int kernel_maps__split_kallsyms(symbol_filter_t filter) | 368 | static int dso__split_kallsyms(struct dso *self, struct map *map, |
369 | symbol_filter_t filter) | ||
371 | { | 370 | { |
372 | struct map *map = kernel_map__functions; | 371 | struct map *curr_map = map; |
373 | struct symbol *pos; | 372 | struct symbol *pos; |
374 | int count = 0; | 373 | int count = 0; |
375 | struct rb_node *next = rb_first(&kernel_map__functions->dso->symbols[map->type]); | 374 | struct rb_root *root = &self->symbols[map->type]; |
375 | struct rb_node *next = rb_first(root); | ||
376 | int kernel_range = 0; | 376 | int kernel_range = 0; |
377 | 377 | ||
378 | while (next) { | 378 | while (next) { |
@@ -385,9 +385,9 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
385 | if (module) { | 385 | if (module) { |
386 | *module++ = '\0'; | 386 | *module++ = '\0'; |
387 | 387 | ||
388 | if (strcmp(map->dso->name, module)) { | 388 | if (strcmp(self->name, module)) { |
389 | map = kernel_maps__find_by_dso_name(module); | 389 | curr_map = kernel_maps__find_by_dso_name(module); |
390 | if (!map) { | 390 | if (curr_map == NULL) { |
391 | pr_err("/proc/{kallsyms,modules} " | 391 | pr_err("/proc/{kallsyms,modules} " |
392 | "inconsistency!\n"); | 392 | "inconsistency!\n"); |
393 | return -1; | 393 | return -1; |
@@ -397,9 +397,9 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
397 | * So that we look just like we get from .ko files, | 397 | * So that we look just like we get from .ko files, |
398 | * i.e. not prelinked, relative to map->start. | 398 | * i.e. not prelinked, relative to map->start. |
399 | */ | 399 | */ |
400 | pos->start = map->map_ip(map, pos->start); | 400 | pos->start = curr_map->map_ip(curr_map, pos->start); |
401 | pos->end = map->map_ip(map, pos->end); | 401 | pos->end = curr_map->map_ip(curr_map, pos->end); |
402 | } else if (map != kernel_map__functions) { | 402 | } else if (curr_map != map) { |
403 | char dso_name[PATH_MAX]; | 403 | char dso_name[PATH_MAX]; |
404 | struct dso *dso; | 404 | struct dso *dso; |
405 | 405 | ||
@@ -410,25 +410,24 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
410 | if (dso == NULL) | 410 | if (dso == NULL) |
411 | return -1; | 411 | return -1; |
412 | 412 | ||
413 | map = map__new2(pos->start, dso, MAP__FUNCTION); | 413 | curr_map = map__new2(pos->start, dso, map->type); |
414 | if (map == NULL) { | 414 | if (map == NULL) { |
415 | dso__delete(dso); | 415 | dso__delete(dso); |
416 | return -1; | 416 | return -1; |
417 | } | 417 | } |
418 | 418 | ||
419 | map->map_ip = map->unmap_ip = identity__map_ip; | 419 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; |
420 | kernel_maps__insert(map); | 420 | kernel_maps__insert(curr_map); |
421 | ++kernel_range; | 421 | ++kernel_range; |
422 | } | 422 | } |
423 | 423 | ||
424 | if (filter && filter(map, pos)) { | 424 | if (filter && filter(curr_map, pos)) { |
425 | rb_erase(&pos->rb_node, &kernel_map__functions->dso->symbols[map->type]); | 425 | rb_erase(&pos->rb_node, root); |
426 | symbol__delete(pos); | 426 | symbol__delete(pos); |
427 | } else { | 427 | } else { |
428 | if (map != kernel_map__functions) { | 428 | if (curr_map != map) { |
429 | rb_erase(&pos->rb_node, | 429 | rb_erase(&pos->rb_node, root); |
430 | &kernel_map__functions->dso->symbols[map->type]); | 430 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); |
431 | symbols__insert(&map->dso->symbols[map->type], pos); | ||
432 | } | 431 | } |
433 | count++; | 432 | count++; |
434 | } | 433 | } |
@@ -438,15 +437,16 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
438 | } | 437 | } |
439 | 438 | ||
440 | 439 | ||
441 | static int kernel_maps__load_kallsyms(symbol_filter_t filter) | 440 | static int dso__load_kallsyms(struct dso *self, struct map *map, |
441 | symbol_filter_t filter) | ||
442 | { | 442 | { |
443 | if (kernel_maps__load_all_kallsyms()) | 443 | if (dso__load_all_kallsyms(self, map) < 0) |
444 | return -1; | 444 | return -1; |
445 | 445 | ||
446 | symbols__fixup_end(&kernel_map__functions->dso->symbols[MAP__FUNCTION]); | 446 | symbols__fixup_end(&self->symbols[map->type]); |
447 | kernel_map__functions->dso->origin = DSO__ORIG_KERNEL; | 447 | self->origin = DSO__ORIG_KERNEL; |
448 | 448 | ||
449 | return kernel_maps__split_kallsyms(filter); | 449 | return dso__split_kallsyms(self, map, filter); |
450 | } | 450 | } |
451 | 451 | ||
452 | size_t kernel_maps__fprintf(FILE *fp) | 452 | size_t kernel_maps__fprintf(FILE *fp) |
@@ -1457,9 +1457,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1457 | if (err <= 0) { | 1457 | if (err <= 0) { |
1458 | pr_info("The file %s cannot be used, " | 1458 | pr_info("The file %s cannot be used, " |
1459 | "trying to use /proc/kallsyms...", self->long_name); | 1459 | "trying to use /proc/kallsyms...", self->long_name); |
1460 | sleep(2); | ||
1461 | do_kallsyms: | 1460 | do_kallsyms: |
1462 | err = kernel_maps__load_kallsyms(filter); | 1461 | err = dso__load_kallsyms(self, map, filter); |
1463 | if (err > 0 && !is_kallsyms) | 1462 | if (err > 0 && !is_kallsyms) |
1464 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); | 1463 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); |
1465 | } | 1464 | } |
@@ -1541,18 +1540,19 @@ size_t dsos__fprintf_buildid(FILE *fp) | |||
1541 | 1540 | ||
1542 | static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | 1541 | static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) |
1543 | { | 1542 | { |
1543 | struct map *kmap; | ||
1544 | struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]"); | 1544 | struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]"); |
1545 | 1545 | ||
1546 | if (kernel == NULL) | 1546 | if (kernel == NULL) |
1547 | return -1; | 1547 | return -1; |
1548 | 1548 | ||
1549 | kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION); | 1549 | kmap = map__new2(0, kernel, MAP__FUNCTION); |
1550 | if (kernel_map__functions == NULL) | 1550 | if (kmap == NULL) |
1551 | goto out_delete_kernel_dso; | 1551 | goto out_delete_kernel_dso; |
1552 | 1552 | ||
1553 | kernel_map__functions->map_ip = kernel_map__functions->unmap_ip = identity__map_ip; | 1553 | kmap->map_ip = kmap->unmap_ip = identity__map_ip; |
1554 | kernel->short_name = "[kernel]"; | 1554 | kernel->short_name = "[kernel]"; |
1555 | kernel->kernel = 1; | 1555 | kernel->kernel = 1; |
1556 | 1556 | ||
1557 | vdso = dso__new("[vdso]"); | 1557 | vdso = dso__new("[vdso]"); |
1558 | if (vdso == NULL) | 1558 | if (vdso == NULL) |
@@ -1563,15 +1563,14 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) | |||
1563 | sizeof(kernel->build_id)) == 0) | 1563 | sizeof(kernel->build_id)) == 0) |
1564 | kernel->has_build_id = true; | 1564 | kernel->has_build_id = true; |
1565 | 1565 | ||
1566 | kernel_maps__insert(kernel_map__functions); | 1566 | kernel_maps__insert(kmap); |
1567 | dsos__add(&dsos__kernel, kernel); | 1567 | dsos__add(&dsos__kernel, kernel); |
1568 | dsos__add(&dsos__user, vdso); | 1568 | dsos__add(&dsos__user, vdso); |
1569 | 1569 | ||
1570 | return 0; | 1570 | return 0; |
1571 | 1571 | ||
1572 | out_delete_kernel_map: | 1572 | out_delete_kernel_map: |
1573 | map__delete(kernel_map__functions); | 1573 | map__delete(kmap); |
1574 | kernel_map__functions = NULL; | ||
1575 | out_delete_kernel_dso: | 1574 | out_delete_kernel_dso: |
1576 | dso__delete(kernel); | 1575 | dso__delete(kernel); |
1577 | return -1; | 1576 | return -1; |