Skip to content

Commit

Permalink
perf symbols: Make the kallsyms loading routines part of the dso class
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
acmel authored and Ingo Molnar committed Nov 27, 2009
1 parent 6a4694a commit 4e06255
Showing 1 changed file with 38 additions and 39 deletions.
77 changes: 38 additions & 39 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
unsigned int symbol__priv_size;
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
static struct map *kernel_map__functions;

static struct symbol_conf symbol_conf__defaults = {
.use_modules = true,
Expand Down Expand Up @@ -296,10 +295,11 @@ size_t dso__fprintf(struct dso *self, FILE *fp)
* so that we can in the next step set the symbol ->end address and then
* call kernel_maps__split_kallsyms.
*/
static int kernel_maps__load_all_kallsyms(void)
static int dso__load_all_kallsyms(struct dso *self, struct map *map)
{
char *line = NULL;
size_t n;
struct rb_root *root = &self->symbols[map->type];
FILE *file = fopen("/proc/kallsyms", "r");

if (file == NULL)
Expand Down Expand Up @@ -342,13 +342,11 @@ static int kernel_maps__load_all_kallsyms(void)

if (sym == NULL)
goto out_delete_line;

/*
* We will pass the symbols to the filter later, in
* kernel_maps__split_kallsyms, when we have split the
* maps per module
* map__split_kallsyms, when we have split the maps per module
*/
symbols__insert(&kernel_map__functions->dso->symbols[MAP__FUNCTION], sym);
symbols__insert(root, sym);
}

free(line);
Expand All @@ -367,12 +365,14 @@ static int kernel_maps__load_all_kallsyms(void)
* kernel range is broken in several maps, named [kernel].N, as we don't have
* the original ELF section names vmlinux have.
*/
static int kernel_maps__split_kallsyms(symbol_filter_t filter)
static int dso__split_kallsyms(struct dso *self, struct map *map,
symbol_filter_t filter)
{
struct map *map = kernel_map__functions;
struct map *curr_map = map;
struct symbol *pos;
int count = 0;
struct rb_node *next = rb_first(&kernel_map__functions->dso->symbols[map->type]);
struct rb_root *root = &self->symbols[map->type];
struct rb_node *next = rb_first(root);
int kernel_range = 0;

while (next) {
Expand All @@ -385,9 +385,9 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter)
if (module) {
*module++ = '\0';

if (strcmp(map->dso->name, module)) {
map = kernel_maps__find_by_dso_name(module);
if (!map) {
if (strcmp(self->name, module)) {
curr_map = kernel_maps__find_by_dso_name(module);
if (curr_map == NULL) {
pr_err("/proc/{kallsyms,modules} "
"inconsistency!\n");
return -1;
Expand All @@ -397,9 +397,9 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter)
* So that we look just like we get from .ko files,
* i.e. not prelinked, relative to map->start.
*/
pos->start = map->map_ip(map, pos->start);
pos->end = map->map_ip(map, pos->end);
} else if (map != kernel_map__functions) {
pos->start = curr_map->map_ip(curr_map, pos->start);
pos->end = curr_map->map_ip(curr_map, pos->end);
} else if (curr_map != map) {
char dso_name[PATH_MAX];
struct dso *dso;

Expand All @@ -410,25 +410,24 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter)
if (dso == NULL)
return -1;

map = map__new2(pos->start, dso, MAP__FUNCTION);
curr_map = map__new2(pos->start, dso, map->type);
if (map == NULL) {
dso__delete(dso);
return -1;
}

map->map_ip = map->unmap_ip = identity__map_ip;
kernel_maps__insert(map);
curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
kernel_maps__insert(curr_map);
++kernel_range;
}

if (filter && filter(map, pos)) {
rb_erase(&pos->rb_node, &kernel_map__functions->dso->symbols[map->type]);
if (filter && filter(curr_map, pos)) {
rb_erase(&pos->rb_node, root);
symbol__delete(pos);
} else {
if (map != kernel_map__functions) {
rb_erase(&pos->rb_node,
&kernel_map__functions->dso->symbols[map->type]);
symbols__insert(&map->dso->symbols[map->type], pos);
if (curr_map != map) {
rb_erase(&pos->rb_node, root);
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
}
count++;
}
Expand All @@ -438,15 +437,16 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter)
}


static int kernel_maps__load_kallsyms(symbol_filter_t filter)
static int dso__load_kallsyms(struct dso *self, struct map *map,
symbol_filter_t filter)
{
if (kernel_maps__load_all_kallsyms())
if (dso__load_all_kallsyms(self, map) < 0)
return -1;

symbols__fixup_end(&kernel_map__functions->dso->symbols[MAP__FUNCTION]);
kernel_map__functions->dso->origin = DSO__ORIG_KERNEL;
symbols__fixup_end(&self->symbols[map->type]);
self->origin = DSO__ORIG_KERNEL;

return kernel_maps__split_kallsyms(filter);
return dso__split_kallsyms(self, map, filter);
}

size_t kernel_maps__fprintf(FILE *fp)
Expand Down Expand Up @@ -1457,9 +1457,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
if (err <= 0) {
pr_info("The file %s cannot be used, "
"trying to use /proc/kallsyms...", self->long_name);
sleep(2);
do_kallsyms:
err = kernel_maps__load_kallsyms(filter);
err = dso__load_kallsyms(self, map, filter);
if (err > 0 && !is_kallsyms)
dso__set_long_name(self, strdup("[kernel.kallsyms]"));
}
Expand Down Expand Up @@ -1541,18 +1540,19 @@ size_t dsos__fprintf_buildid(FILE *fp)

static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
{
struct map *kmap;
struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]");

if (kernel == NULL)
return -1;

kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION);
if (kernel_map__functions == NULL)
kmap = map__new2(0, kernel, MAP__FUNCTION);
if (kmap == NULL)
goto out_delete_kernel_dso;

kernel_map__functions->map_ip = kernel_map__functions->unmap_ip = identity__map_ip;
kernel->short_name = "[kernel]";
kernel->kernel = 1;
kmap->map_ip = kmap->unmap_ip = identity__map_ip;
kernel->short_name = "[kernel]";
kernel->kernel = 1;

vdso = dso__new("[vdso]");
if (vdso == NULL)
Expand All @@ -1563,15 +1563,14 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
sizeof(kernel->build_id)) == 0)
kernel->has_build_id = true;

kernel_maps__insert(kernel_map__functions);
kernel_maps__insert(kmap);
dsos__add(&dsos__kernel, kernel);
dsos__add(&dsos__user, vdso);

return 0;

out_delete_kernel_map:
map__delete(kernel_map__functions);
kernel_map__functions = NULL;
map__delete(kmap);
out_delete_kernel_dso:
dso__delete(kernel);
return -1;
Expand Down

0 comments on commit 4e06255

Please sign in to comment.