perf symbols: Add a 'type' field to struct map
authorArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 27 Nov 2009 18:29:16 +0000 (16:29 -0200)
committerIngo Molnar <mingo@elte.hu>
Fri, 27 Nov 2009 19:21:59 +0000 (20:21 +0100)
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>
tools/perf/builtin-top.c
tools/perf/util/event.h
tools/perf/util/map.c
tools/perf/util/process_events.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index ded6cf65ad9cc6684d647390e05dd3f24826661f..a0168f260d06c139e560bb16b563dc4538748661 100644 (file)
@@ -996,7 +996,7 @@ static void event__process_mmap(event_t *self)
        struct thread *thread = threads__findnew(self->mmap.pid);
 
        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)
                        thread__insert_map(thread, map);
        }
index 882a9531db973bdad6a1d01c5777145c955e3726..29543bd880071a8267429a29ecea8e1504f8a9c1 100644 (file)
@@ -80,6 +80,10 @@ typedef union event_union {
        struct sample_event             sample;
 } event_t;
 
+enum map_type {
+       MAP__FUNCTION,
+};
+
 struct map {
        union {
                struct rb_node  rb_node;
@@ -87,6 +91,7 @@ struct map {
        };
        u64                     start;
        u64                     end;
+       enum map_type           type;
        u64                     pgoff;
        u64                     (*map_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);
 
-void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
-              struct dso *dso);
-struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
+void map__init(struct map *self, enum map_type type,
+              u64 start, u64 end, u64 pgoff, struct dso *dso);
+struct map *map__new(struct mmap_event *event, enum map_type,
+                    char *cwd, int cwdlen);
 void map__delete(struct map *self);
 struct map *map__clone(struct map *self);
 int map__overlap(struct map *l, struct map *r);
index 41c5c4a20010edf61da524833e8c64ce88f629ea..52bb4c6cf74dd5369650e66392a3dac15cfce511 100644 (file)
@@ -20,9 +20,10 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen)
        return n;
 }
 
-void map__init(struct map *self, u64 start, u64 end, u64 pgoff,
-              struct dso *dso)
+void map__init(struct map *self, enum map_type type,
+              u64 start, u64 end, u64 pgoff, struct dso *dso)
 {
+       self->type     = type;
        self->start    = start;
        self->end      = end;
        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);
 }
 
-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));
 
@@ -63,7 +65,7 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
                if (dso == NULL)
                        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);
 
                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,
                                  symbol_filter_t filter)
 {
-       if (!self->dso->loaded) {
+       if (!dso__loaded(self->dso, self->type)) {
                int nr = dso__load(self->dso, self, filter);
 
                if (nr < 0) {
index a9204363efd890bb3b218cbe05b25aecf87502fb..53778684641cebdd483d40ee009718b43a2f0127 100644 (file)
@@ -6,7 +6,7 @@ int     cwdlen;
 int
 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);
 
        dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
index 0b8a298d41adf02fd1b74dbb785595abd8aab8fb..45a4a9a7618bdd36b43769b7974fbc90f497f194 100644 (file)
@@ -29,7 +29,7 @@ enum dso_origin {
 };
 
 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 int dso__load_kernel_sym(struct dso *self, struct map *map,
                                symbol_filter_t filter);
@@ -45,6 +45,16 @@ static struct symbol_conf symbol_conf__defaults = {
 
 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)
 {
        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)
                                return -1;
 
-                       map = map__new2(pos->start, dso);
+                       map = map__new2(pos->start, dso, MAP__FUNCTION);
                        if (map == NULL) {
                                dso__delete(dso);
                                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);
                                if (curr_dso == NULL)
                                        goto out_elf_end;
-                               curr_map = map__new2(start, curr_dso);
+                               curr_map = map__new2(start, curr_dso,
+                                                    MAP__FUNCTION);
                                if (curr_map == NULL) {
                                        dso__delete(curr_dso);
                                        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 fd;
 
-       self->loaded = 1;
+       dso__set_loaded(self, map->type);
 
        if (self->kernel)
                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
  * 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));
 
@@ -1283,7 +1294,7 @@ static struct map *map__new2(u64 start, struct dso *dso)
                /*
                 * ->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;
@@ -1333,7 +1344,7 @@ static int kernel_maps__create_module_maps(void)
                if (dso == NULL)
                        goto out_delete_line;
 
-               map = map__new2(start, dso);
+               map = map__new2(start, dso, MAP__FUNCTION);
                if (map == NULL) {
                        dso__delete(dso);
                        goto out_delete_line;
@@ -1394,7 +1405,7 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
        if (fd < 0)
                return -1;
 
-       self->loaded = 1;
+       dso__set_loaded(self, map->type);
        err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0);
 
        close(fd);
@@ -1522,7 +1533,7 @@ static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
        if (kernel == NULL)
                return -1;
 
-       kernel_map__functions = map__new2(0, kernel);
+       kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION);
        if (kernel_map__functions == NULL)
                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]");
        if (vdso == NULL)
                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,
                                 sizeof(kernel->build_id)) == 0)
index fb0be9e92bf379fa319f8f5ae282036e27d43272..11d41952ce04984e84e06c179273914afc2cd407 100644 (file)
@@ -69,10 +69,10 @@ struct dso {
        struct symbol    *(*find_function)(struct dso *, u64 ip);
        u8               adjust_symbols:1;
        u8               slen_calculated:1;
-       u8               loaded:1;
        u8               has_build_id:1;
        u8               kernel:1;
        unsigned char    origin;
+       u8               loaded;
        u8               build_id[BUILD_ID_SIZE];
        u16              long_name_len;
        const char       *short_name;
@@ -85,6 +85,8 @@ void dso__delete(struct dso *self);
 
 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);
 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
 void dsos__fprintf(FILE *fp);