diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 79ca6a099f96..b9e0da57d84b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -383,16 +383,12 @@ size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) | |||
383 | return ret; | 383 | return ret; |
384 | } | 384 | } |
385 | 385 | ||
386 | /* | 386 | int kallsyms__parse(void *arg, int (*process_symbol)(void *arg, const char *name, |
387 | * Loads the function entries in /proc/kallsyms into kernel_map->dso, | 387 | char type, u64 start)) |
388 | * so that we can in the next step set the symbol ->end address and then | ||
389 | * call kernel_maps__split_kallsyms. | ||
390 | */ | ||
391 | static int dso__load_all_kallsyms(struct dso *self, struct map *map) | ||
392 | { | 388 | { |
393 | char *line = NULL; | 389 | char *line = NULL; |
394 | size_t n; | 390 | size_t n; |
395 | struct rb_root *root = &self->symbols[map->type]; | 391 | int err = 0; |
396 | FILE *file = fopen("/proc/kallsyms", "r"); | 392 | FILE *file = fopen("/proc/kallsyms", "r"); |
397 | 393 | ||
398 | if (file == NULL) | 394 | if (file == NULL) |
@@ -400,7 +396,6 @@ static int dso__load_all_kallsyms(struct dso *self, struct map *map) | |||
400 | 396 | ||
401 | while (!feof(file)) { | 397 | while (!feof(file)) { |
402 | u64 start; | 398 | u64 start; |
403 | struct symbol *sym; | ||
404 | int line_len, len; | 399 | int line_len, len; |
405 | char symbol_type; | 400 | char symbol_type; |
406 | char *symbol_name; | 401 | char *symbol_name; |
@@ -421,35 +416,62 @@ static int dso__load_all_kallsyms(struct dso *self, struct map *map) | |||
421 | continue; | 416 | continue; |
422 | 417 | ||
423 | symbol_type = toupper(line[len]); | 418 | symbol_type = toupper(line[len]); |
424 | if (!symbol_type__is_a(symbol_type, map->type)) | ||
425 | continue; | ||
426 | |||
427 | symbol_name = line + len + 2; | 419 | symbol_name = line + len + 2; |
428 | /* | ||
429 | * Will fix up the end later, when we have all symbols sorted. | ||
430 | */ | ||
431 | sym = symbol__new(start, 0, symbol_name); | ||
432 | 420 | ||
433 | if (sym == NULL) | 421 | err = process_symbol(arg, symbol_name, symbol_type, start); |
434 | goto out_delete_line; | 422 | if (err) |
435 | /* | 423 | break; |
436 | * We will pass the symbols to the filter later, in | ||
437 | * map__split_kallsyms, when we have split the maps per module | ||
438 | */ | ||
439 | symbols__insert(root, sym); | ||
440 | } | 424 | } |
441 | 425 | ||
442 | free(line); | 426 | free(line); |
443 | fclose(file); | 427 | fclose(file); |
428 | return err; | ||
444 | 429 | ||
445 | return 0; | ||
446 | |||
447 | out_delete_line: | ||
448 | free(line); | ||
449 | out_failure: | 430 | out_failure: |
450 | return -1; | 431 | return -1; |
451 | } | 432 | } |
452 | 433 | ||
434 | struct process_kallsyms_args { | ||
435 | struct map *map; | ||
436 | struct dso *dso; | ||
437 | }; | ||
438 | |||
439 | static int map__process_kallsym_symbol(void *arg, const char *name, | ||
440 | char type, u64 start) | ||
441 | { | ||
442 | struct symbol *sym; | ||
443 | struct process_kallsyms_args *a = arg; | ||
444 | struct rb_root *root = &a->dso->symbols[a->map->type]; | ||
445 | |||
446 | if (!symbol_type__is_a(type, a->map->type)) | ||
447 | return 0; | ||
448 | |||
449 | /* | ||
450 | * Will fix up the end later, when we have all symbols sorted. | ||
451 | */ | ||
452 | sym = symbol__new(start, 0, name); | ||
453 | |||
454 | if (sym == NULL) | ||
455 | return -ENOMEM; | ||
456 | /* | ||
457 | * We will pass the symbols to the filter later, in | ||
458 | * map__split_kallsyms, when we have split the maps per module | ||
459 | */ | ||
460 | symbols__insert(root, sym); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Loads the function entries in /proc/kallsyms into kernel_map->dso, | ||
466 | * so that we can in the next step set the symbol ->end address and then | ||
467 | * call kernel_maps__split_kallsyms. | ||
468 | */ | ||
469 | static int dso__load_all_kallsyms(struct dso *self, struct map *map) | ||
470 | { | ||
471 | struct process_kallsyms_args args = { .map = map, .dso = self, }; | ||
472 | return kallsyms__parse(&args, map__process_kallsym_symbol); | ||
473 | } | ||
474 | |||
453 | /* | 475 | /* |
454 | * Split the symbols into maps, making sure there are no overlaps, i.e. the | 476 | * Split the symbols into maps, making sure there are no overlaps, i.e. the |
455 | * kernel range is broken in several maps, named [kernel].N, as we don't have | 477 | * kernel range is broken in several maps, named [kernel].N, as we don't have |