aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-01-04 13:19:26 -0500
committerIngo Molnar <mingo@elte.hu>2010-01-13 04:09:08 -0500
commit682b335a5bccf9e5b7e74380784aa2f145d04444 (patch)
tree98a2be405f1a162964935d9b33a1acccedec2ea3 /tools/perf/util/symbol.c
parent60666c630bdb33983a894b050b588b663f38f368 (diff)
perf symbols: Generalise the kallsyms parsing routine
Will be used to find an specific symbol by name on 'perf record' to support relocation reference symbols to support relocatable kernels. Still have to conver the perf trace tools to use it instead of their current reimplementation. 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: <1262629169-22797-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
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 79ca6a099f9..b9e0da57d84 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