aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c74
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/* 386int 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 */
391static 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
447out_delete_line:
448 free(line);
449out_failure: 430out_failure:
450 return -1; 431 return -1;
451} 432}
452 433
434struct process_kallsyms_args {
435 struct map *map;
436 struct dso *dso;
437};
438
439static 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 */
469static 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