perf_counter tools: struct symbol priv area
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 28 May 2009 17:55:13 +0000 (14:55 -0300)
committerIngo Molnar <mingo@elte.hu>
Thu, 28 May 2009 21:25:43 +0000 (23:25 +0200)
When creating a dso instance allow asking that all symbols in this dso
have a private area just before the symbol.

perf top will use this for its counters, etc.

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: <20090528175513.GD4747@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 04fc7ec0c3597dbd7ad4c56ede7e9176313a876c..889067eb2b690daee1904ea209374d9a2b98f72b 100644 (file)
@@ -83,7 +83,7 @@ static struct dso *dsos__findnew(const char *name)
        int nr;
 
        if (dso == NULL) {
-               dso = dso__new(name);
+               dso = dso__new(name, 0);
                if (!dso)
                        goto out_delete_dso;
 
@@ -120,7 +120,7 @@ static int load_kernel(void)
 {
        int err = -1;
 
-       kernel_dso = dso__new("[kernel]");
+       kernel_dso = dso__new("[kernel]", 0);
        if (!kernel_dso)
                return -1;
 
index d06de2cfcdc64bbcd1a6a2e9dda9a2f18e283385..7088206244ac7b294262d8ed0372291633e83b56 100644 (file)
@@ -7,22 +7,27 @@
 #include <elf.h>
 
 static struct symbol *symbol__new(uint64_t start, uint64_t len,
-                                 const char *name)
+                                 const char *name, unsigned int priv_size)
 {
-       struct symbol *self = malloc(sizeof(*self) + strlen(name) + 1);
+       size_t namelen = strlen(name) + 1;
+       struct symbol *self = malloc(priv_size + sizeof(*self) + namelen);
 
        if (self != NULL) {
+               if (priv_size) {
+                       memset(self, 0, priv_size);
+                       self = ((void *)self) + priv_size;
+               }
                self->start = start;
                self->end   = start + len;
-               strcpy(self->name, name);
+               memcpy(self->name, name, namelen);
        }
 
        return self;
 }
 
-static void symbol__delete(struct symbol *self)
+static void symbol__delete(struct symbol *self, unsigned int priv_size)
 {
-       free(self);
+       free(((void *)self) - priv_size);
 }
 
 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
@@ -31,13 +36,14 @@ static size_t symbol__fprintf(struct symbol *self, FILE *fp)
                       self->start, self->end, self->name);
 }
 
-struct dso *dso__new(const char *name)
+struct dso *dso__new(const char *name, unsigned int sym_priv_size)
 {
        struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
 
        if (self != NULL) {
                strcpy(self->name, name);
                self->syms = RB_ROOT;
+               self->sym_priv_size = sym_priv_size;
        }
 
        return self;
@@ -51,7 +57,7 @@ static void dso__delete_symbols(struct dso *self)
        while (next) {
                pos = rb_entry(next, struct symbol, rb_node);
                next = rb_next(&pos->rb_node);
-               symbol__delete(pos);
+               symbol__delete(pos, self->sym_priv_size);
        }
 }
 
@@ -189,7 +195,8 @@ int dso__load_kallsyms(struct dso *self)
                /*
                 * Well fix up the end later, when we have all sorted.
                 */
-               sym = symbol__new(start, 0xdead, line + len + 2);
+               sym = symbol__new(start, 0xdead, line + len + 2,
+                                 self->sym_priv_size);
 
                if (sym == NULL)
                        goto out_delete_line;
@@ -340,7 +347,8 @@ static int dso__load_sym(struct dso *self, int fd, const char *name)
                sym.st_value -= shdr.sh_addr - shdr.sh_offset;
 
                f = symbol__new(sym.st_value, sym.st_size,
-                               elf_sym__name(&sym, symstrs));
+                               elf_sym__name(&sym, symstrs),
+                               self->sym_priv_size);
                if (!f)
                        goto out_elf_end;
 
index 6dffe76a28f07806f85c6095610378528eea95e9..9e120af9c71f93f026152ed5230ef1bc15329dbf 100644 (file)
@@ -15,12 +15,18 @@ struct symbol {
 struct dso {
        struct list_head node;
        struct rb_root   syms;
+       unsigned int     sym_priv_size;
        char             name[0];
 };
 
-struct dso *dso__new(const char *name);
+struct dso *dso__new(const char *name, unsigned int sym_priv_size);
 void dso__delete(struct dso *self);
 
+static inline void *dso__sym_priv(struct dso *self, struct symbol *sym)
+{
+       return ((void *)sym) - self->sym_priv_size;
+}
+
 struct symbol *dso__find_symbol(struct dso *self, uint64_t ip);
 
 int dso__load_kallsyms(struct dso *self);