mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
perf symbols: Add a 'type' field to struct map
That way we will be able to check if the right symtab is loaded in the underlying DSO. 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-5-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
605ca4ba01
commit
3610583c29
6 changed files with 42 additions and 21 deletions
|
@ -996,7 +996,7 @@ static void event__process_mmap(event_t *self)
|
||||||
struct thread *thread = threads__findnew(self->mmap.pid);
|
struct thread *thread = threads__findnew(self->mmap.pid);
|
||||||
|
|
||||||
if (thread != NULL) {
|
if (thread != NULL) {
|
||||||
struct map *map = map__new(&self->mmap, NULL, 0);
|
struct map *map = map__new(&self->mmap, MAP__FUNCTION, NULL, 0);
|
||||||
if (map != NULL)
|
if (map != NULL)
|
||||||
thread__insert_map(thread, map);
|
thread__insert_map(thread, map);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ typedef union event_union {
|
||||||
struct sample_event sample;
|
struct sample_event sample;
|
||||||
} event_t;
|
} event_t;
|
||||||
|
|
||||||
|
enum map_type {
|
||||||
|
MAP__FUNCTION,
|
||||||
|
};
|
||||||
|
|
||||||
struct map {
|
struct map {
|
||||||
union {
|
union {
|
||||||
struct rb_node rb_node;
|
struct rb_node rb_node;
|
||||||
|
@ -87,6 +91,7 @@ struct map {
|
||||||
};
|
};
|
||||||
u64 start;
|
u64 start;
|
||||||
u64 end;
|
u64 end;
|
||||||
|
enum map_type type;
|
||||||
u64 pgoff;
|
u64 pgoff;
|
||||||
u64 (*map_ip)(struct map *, u64);
|
u64 (*map_ip)(struct map *, u64);
|
||||||
u64 (*unmap_ip)(struct map *, u64);
|
u64 (*unmap_ip)(struct map *, u64);
|
||||||
|
@ -112,9 +117,10 @@ struct symbol;
|
||||||
|
|
||||||
typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
|
typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
|
||||||
|
|
||||||
void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
|
void map__init(struct map *self, enum map_type type,
|
||||||
struct dso *dso);
|
u64 start, u64 end, u64 pgoff, struct dso *dso);
|
||||||
struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
|
struct map *map__new(struct mmap_event *event, enum map_type,
|
||||||
|
char *cwd, int cwdlen);
|
||||||
void map__delete(struct map *self);
|
void map__delete(struct map *self);
|
||||||
struct map *map__clone(struct map *self);
|
struct map *map__clone(struct map *self);
|
||||||
int map__overlap(struct map *l, struct map *r);
|
int map__overlap(struct map *l, struct map *r);
|
||||||
|
|
|
@ -20,9 +20,10 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
|
void map__init(struct map *self, enum map_type type,
|
||||||
struct dso *dso)
|
u64 start, u64 end, u64 pgoff, struct dso *dso)
|
||||||
{
|
{
|
||||||
|
self->type = type;
|
||||||
self->start = start;
|
self->start = start;
|
||||||
self->end = end;
|
self->end = end;
|
||||||
self->pgoff = pgoff;
|
self->pgoff = pgoff;
|
||||||
|
@ -32,7 +33,8 @@ void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
|
||||||
RB_CLEAR_NODE(&self->rb_node);
|
RB_CLEAR_NODE(&self->rb_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
|
struct map *map__new(struct mmap_event *event, enum map_type type,
|
||||||
|
char *cwd, int cwdlen)
|
||||||
{
|
{
|
||||||
struct map *self = malloc(sizeof(*self));
|
struct map *self = malloc(sizeof(*self));
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
|
||||||
if (dso == NULL)
|
if (dso == NULL)
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
|
|
||||||
map__init(self, event->start, event->start + event->len,
|
map__init(self, type, event->start, event->start + event->len,
|
||||||
event->pgoff, dso);
|
event->pgoff, dso);
|
||||||
|
|
||||||
if (self->dso == vdso || anon)
|
if (self->dso == vdso || anon)
|
||||||
|
@ -103,7 +105,7 @@ void map__fixup_end(struct map *self, struct rb_root *symbols)
|
||||||
struct symbol *map__find_function(struct map *self, u64 ip,
|
struct symbol *map__find_function(struct map *self, u64 ip,
|
||||||
symbol_filter_t filter)
|
symbol_filter_t filter)
|
||||||
{
|
{
|
||||||
if (!self->dso->loaded) {
|
if (!dso__loaded(self->dso, self->type)) {
|
||||||
int nr = dso__load(self->dso, self, filter);
|
int nr = dso__load(self->dso, self, filter);
|
||||||
|
|
||||||
if (nr < 0) {
|
if (nr < 0) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ int cwdlen;
|
||||||
int
|
int
|
||||||
process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
|
process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
|
||||||
{
|
{
|
||||||
struct map *map = map__new(&event->mmap, cwd, cwdlen);
|
struct map *map = map__new(&event->mmap, MAP__FUNCTION, cwd, cwdlen);
|
||||||
struct thread *thread = threads__findnew(event->mmap.pid);
|
struct thread *thread = threads__findnew(event->mmap.pid);
|
||||||
|
|
||||||
dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
|
dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum dso_origin {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dsos__add(struct list_head *head, struct dso *dso);
|
static void dsos__add(struct list_head *head, struct dso *dso);
|
||||||
static struct map *map__new2(u64 start, struct dso *dso);
|
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
|
||||||
static void kernel_maps__insert(struct map *map);
|
static void kernel_maps__insert(struct map *map);
|
||||||
static int dso__load_kernel_sym(struct dso *self, struct map *map,
|
static int dso__load_kernel_sym(struct dso *self, struct map *map,
|
||||||
symbol_filter_t filter);
|
symbol_filter_t filter);
|
||||||
|
@ -45,6 +45,16 @@ static struct symbol_conf symbol_conf__defaults = {
|
||||||
|
|
||||||
static struct rb_root kernel_maps__functions;
|
static struct rb_root kernel_maps__functions;
|
||||||
|
|
||||||
|
bool dso__loaded(const struct dso *self, enum map_type type)
|
||||||
|
{
|
||||||
|
return self->loaded & (1 << type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dso__set_loaded(struct dso *self, enum map_type type)
|
||||||
|
{
|
||||||
|
self->loaded |= (1 << type);
|
||||||
|
}
|
||||||
|
|
||||||
static void symbols__fixup_end(struct rb_root *self)
|
static void symbols__fixup_end(struct rb_root *self)
|
||||||
{
|
{
|
||||||
struct rb_node *nd, *prevnd = rb_first(self);
|
struct rb_node *nd, *prevnd = rb_first(self);
|
||||||
|
@ -387,7 +397,7 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter)
|
||||||
if (dso == NULL)
|
if (dso == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
map = map__new2(pos->start, dso);
|
map = map__new2(pos->start, dso, MAP__FUNCTION);
|
||||||
if (map == NULL) {
|
if (map == NULL) {
|
||||||
dso__delete(dso);
|
dso__delete(dso);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -846,7 +856,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
|
||||||
curr_dso = dso__new(dso_name);
|
curr_dso = dso__new(dso_name);
|
||||||
if (curr_dso == NULL)
|
if (curr_dso == NULL)
|
||||||
goto out_elf_end;
|
goto out_elf_end;
|
||||||
curr_map = map__new2(start, curr_dso);
|
curr_map = map__new2(start, curr_dso,
|
||||||
|
MAP__FUNCTION);
|
||||||
if (curr_map == NULL) {
|
if (curr_map == NULL) {
|
||||||
dso__delete(curr_dso);
|
dso__delete(curr_dso);
|
||||||
goto out_elf_end;
|
goto out_elf_end;
|
||||||
|
@ -1076,7 +1087,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
self->loaded = 1;
|
dso__set_loaded(self, map->type);
|
||||||
|
|
||||||
if (self->kernel)
|
if (self->kernel)
|
||||||
return dso__load_kernel_sym(self, map, filter);
|
return dso__load_kernel_sym(self, map, filter);
|
||||||
|
@ -1275,7 +1286,7 @@ static int dsos__set_modules_path(void)
|
||||||
* they are loaded) and for vmlinux, where only after we load all the
|
* they are loaded) and for vmlinux, where only after we load all the
|
||||||
* symbols we'll know where it starts and ends.
|
* symbols we'll know where it starts and ends.
|
||||||
*/
|
*/
|
||||||
static struct map *map__new2(u64 start, struct dso *dso)
|
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
|
||||||
{
|
{
|
||||||
struct map *self = malloc(sizeof(*self));
|
struct map *self = malloc(sizeof(*self));
|
||||||
|
|
||||||
|
@ -1283,7 +1294,7 @@ static struct map *map__new2(u64 start, struct dso *dso)
|
||||||
/*
|
/*
|
||||||
* ->end will be filled after we load all the symbols
|
* ->end will be filled after we load all the symbols
|
||||||
*/
|
*/
|
||||||
map__init(self, start, 0, 0, dso);
|
map__init(self, type, start, 0, 0, dso);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -1333,7 +1344,7 @@ static int kernel_maps__create_module_maps(void)
|
||||||
if (dso == NULL)
|
if (dso == NULL)
|
||||||
goto out_delete_line;
|
goto out_delete_line;
|
||||||
|
|
||||||
map = map__new2(start, dso);
|
map = map__new2(start, dso, MAP__FUNCTION);
|
||||||
if (map == NULL) {
|
if (map == NULL) {
|
||||||
dso__delete(dso);
|
dso__delete(dso);
|
||||||
goto out_delete_line;
|
goto out_delete_line;
|
||||||
|
@ -1394,7 +1405,7 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
self->loaded = 1;
|
dso__set_loaded(self, map->type);
|
||||||
err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0);
|
err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -1522,7 +1533,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
|
||||||
if (kernel == NULL)
|
if (kernel == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
kernel_map__functions = map__new2(0, kernel);
|
kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION);
|
||||||
if (kernel_map__functions == NULL)
|
if (kernel_map__functions == NULL)
|
||||||
goto out_delete_kernel_dso;
|
goto out_delete_kernel_dso;
|
||||||
|
|
||||||
|
@ -1533,7 +1544,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
|
||||||
vdso = dso__new("[vdso]");
|
vdso = dso__new("[vdso]");
|
||||||
if (vdso == NULL)
|
if (vdso == NULL)
|
||||||
goto out_delete_kernel_map;
|
goto out_delete_kernel_map;
|
||||||
vdso->loaded = 1;
|
dso__set_loaded(vdso, MAP__FUNCTION);
|
||||||
|
|
||||||
if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
|
if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
|
||||||
sizeof(kernel->build_id)) == 0)
|
sizeof(kernel->build_id)) == 0)
|
||||||
|
|
|
@ -69,10 +69,10 @@ struct dso {
|
||||||
struct symbol *(*find_function)(struct dso *, u64 ip);
|
struct symbol *(*find_function)(struct dso *, u64 ip);
|
||||||
u8 adjust_symbols:1;
|
u8 adjust_symbols:1;
|
||||||
u8 slen_calculated:1;
|
u8 slen_calculated:1;
|
||||||
u8 loaded:1;
|
|
||||||
u8 has_build_id:1;
|
u8 has_build_id:1;
|
||||||
u8 kernel:1;
|
u8 kernel:1;
|
||||||
unsigned char origin;
|
unsigned char origin;
|
||||||
|
u8 loaded;
|
||||||
u8 build_id[BUILD_ID_SIZE];
|
u8 build_id[BUILD_ID_SIZE];
|
||||||
u16 long_name_len;
|
u16 long_name_len;
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
|
@ -85,6 +85,8 @@ void dso__delete(struct dso *self);
|
||||||
|
|
||||||
struct symbol *dso__find_function(struct dso *self, u64 ip);
|
struct symbol *dso__find_function(struct dso *self, u64 ip);
|
||||||
|
|
||||||
|
bool dso__loaded(const struct dso *self, enum map_type type);
|
||||||
|
|
||||||
struct dso *dsos__findnew(const char *name);
|
struct dso *dsos__findnew(const char *name);
|
||||||
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
|
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
|
||||||
void dsos__fprintf(FILE *fp);
|
void dsos__fprintf(FILE *fp);
|
||||||
|
|
Loading…
Reference in a new issue