perf_counter tools: Optionally pass a symbol filter to the dso load routines
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 28 May 2009 17:55:26 +0000 (14:55 -0300)
committerIngo Molnar <mingo@elte.hu>
Thu, 28 May 2009 21:25:44 +0000 (23:25 +0200)
Will be used by perf top.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20090528175526.GF4747@ghostprotocols.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Documentation/perf_counter/builtin-report.c
Documentation/perf_counter/util/symbol.c
Documentation/perf_counter/util/symbol.h

index 4e9f2bc104527d9860cd9adf52bf75251860d70f..412d524dd6581e7b572b0bdc6b0b54edbb8020e9 100644 (file)
@@ -87,7 +87,7 @@ static struct dso *dsos__findnew(const char *name)
                if (!dso)
                        goto out_delete_dso;
 
-               nr = dso__load(dso);
+               nr = dso__load(dso, NULL);
                if (nr < 0) {
                        fprintf(stderr, "Failed to open: %s\n", name);
                        goto out_delete_dso;
@@ -124,7 +124,7 @@ static int load_kernel(void)
        if (!kernel_dso)
                return -1;
 
-       err = dso__load_kernel(kernel_dso, vmlinux);
+       err = dso__load_kernel(kernel_dso, vmlinux, NULL);
        if (err) {
                dso__delete(kernel_dso);
                kernel_dso = NULL;
index 504ac3132019ea866ac012333acb31a3c8087e0b..47281210443de2165e5da89399660873af5a5ab3 100644 (file)
@@ -155,7 +155,7 @@ static int hex2long(char *ptr, unsigned long *long_val)
        return p - ptr;
 }
 
-static int dso__load_kallsyms(struct dso *self)
+static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter)
 {
        struct rb_node *nd, *prevnd;
        char *line = NULL;
@@ -201,7 +201,10 @@ static int dso__load_kallsyms(struct dso *self)
                if (sym == NULL)
                        goto out_delete_line;
 
-               dso__insert_symbol(self, sym);
+               if (filter && filter(self, sym))
+                       symbol__delete(sym, self->sym_priv_size);
+               else
+                       dso__insert_symbol(self, sym);
        }
 
        /*
@@ -286,7 +289,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
        return sec;
 }
 
-static int dso__load_sym(struct dso *self, int fd, const char *name)
+static int dso__load_sym(struct dso *self, int fd, const char *name,
+                        symbol_filter_t filter)
 {
        Elf_Data *symstrs;
        uint32_t nr_syms;
@@ -352,9 +356,12 @@ static int dso__load_sym(struct dso *self, int fd, const char *name)
                if (!f)
                        goto out_elf_end;
 
-               dso__insert_symbol(self, f);
-
-               nr++;
+               if (filter && filter(self, f))
+                       symbol__delete(f, self->sym_priv_size);
+               else {
+                       dso__insert_symbol(self, f);
+                       nr++;
+               }
        }
 
        err = nr;
@@ -364,7 +371,7 @@ out_close:
        return err;
 }
 
-int dso__load(struct dso *self)
+int dso__load(struct dso *self, symbol_filter_t filter)
 {
        int size = strlen(self->name) + sizeof("/usr/lib/debug%s.debug");
        char *name = malloc(size);
@@ -396,7 +403,7 @@ more:
                fd = open(name, O_RDONLY);
        } while (fd < 0);
 
-       ret = dso__load_sym(self, fd, name);
+       ret = dso__load_sym(self, fd, name, filter);
        close(fd);
 
        /*
@@ -410,28 +417,29 @@ out:
        return ret;
 }
 
-static int dso__load_vmlinux(struct dso *self, const char *vmlinux)
+static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
+                            symbol_filter_t filter)
 {
        int err, fd = open(vmlinux, O_RDONLY);
 
        if (fd < 0)
                return -1;
 
-       err = dso__load_sym(self, fd, vmlinux);
+       err = dso__load_sym(self, fd, vmlinux, filter);
        close(fd);
 
        return err;
 }
 
-int dso__load_kernel(struct dso *self, const char *vmlinux)
+int dso__load_kernel(struct dso *self, const char *vmlinux, symbol_filter_t filter)
 {
        int err = -1;
 
        if (vmlinux)
-               err = dso__load_vmlinux(self, vmlinux);
+               err = dso__load_vmlinux(self, vmlinux, filter);
 
        if (err)
-               err = dso__load_kallsyms(self);
+               err = dso__load_kallsyms(self, filter);
 
        return err;
 }
index db2fdf9f70a20eff869ad9126328e82133f099a3..b0299bc0cf50e799b6bf95415c0087063259757b 100644 (file)
@@ -19,6 +19,8 @@ struct dso {
        char             name[0];
 };
 
+typedef int (*symbol_filter_t)(struct dso *self, struct symbol *sym);
+
 struct dso *dso__new(const char *name, unsigned int sym_priv_size);
 void dso__delete(struct dso *self);
 
@@ -29,8 +31,9 @@ static inline void *dso__sym_priv(struct dso *self, struct symbol *sym)
 
 struct symbol *dso__find_symbol(struct dso *self, uint64_t ip);
 
-int dso__load_kernel(struct dso *self, const char *vmlinux);
-int dso__load(struct dso *self);
+int dso__load_kernel(struct dso *self, const char *vmlinux,
+                    symbol_filter_t filter);
+int dso__load(struct dso *self, symbol_filter_t filter);
 
 size_t dso__fprintf(struct dso *self, FILE *fp);