diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-05-28 13:55:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-28 17:25:43 -0400 |
commit | 0085c954140d27937ada29d139c16341075d45e4 (patch) | |
tree | cb7a8e94077a26f7eb567eba832436df037f8f13 /Documentation/perf_counter/util | |
parent | a2928c42a5d69328c3578b41bd4d72f6658cf7dc (diff) |
perf_counter tools: struct symbol priv area
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>
Diffstat (limited to 'Documentation/perf_counter/util')
-rw-r--r-- | Documentation/perf_counter/util/symbol.c | 26 | ||||
-rw-r--r-- | Documentation/perf_counter/util/symbol.h | 8 |
2 files changed, 24 insertions, 10 deletions
diff --git a/Documentation/perf_counter/util/symbol.c b/Documentation/perf_counter/util/symbol.c index d06de2cfcdc6..7088206244ac 100644 --- a/Documentation/perf_counter/util/symbol.c +++ b/Documentation/perf_counter/util/symbol.c | |||
@@ -7,22 +7,27 @@ | |||
7 | #include <elf.h> | 7 | #include <elf.h> |
8 | 8 | ||
9 | static struct symbol *symbol__new(uint64_t start, uint64_t len, | 9 | static struct symbol *symbol__new(uint64_t start, uint64_t len, |
10 | const char *name) | 10 | const char *name, unsigned int priv_size) |
11 | { | 11 | { |
12 | struct symbol *self = malloc(sizeof(*self) + strlen(name) + 1); | 12 | size_t namelen = strlen(name) + 1; |
13 | struct symbol *self = malloc(priv_size + sizeof(*self) + namelen); | ||
13 | 14 | ||
14 | if (self != NULL) { | 15 | if (self != NULL) { |
16 | if (priv_size) { | ||
17 | memset(self, 0, priv_size); | ||
18 | self = ((void *)self) + priv_size; | ||
19 | } | ||
15 | self->start = start; | 20 | self->start = start; |
16 | self->end = start + len; | 21 | self->end = start + len; |
17 | strcpy(self->name, name); | 22 | memcpy(self->name, name, namelen); |
18 | } | 23 | } |
19 | 24 | ||
20 | return self; | 25 | return self; |
21 | } | 26 | } |
22 | 27 | ||
23 | static void symbol__delete(struct symbol *self) | 28 | static void symbol__delete(struct symbol *self, unsigned int priv_size) |
24 | { | 29 | { |
25 | free(self); | 30 | free(((void *)self) - priv_size); |
26 | } | 31 | } |
27 | 32 | ||
28 | static size_t symbol__fprintf(struct symbol *self, FILE *fp) | 33 | static size_t symbol__fprintf(struct symbol *self, FILE *fp) |
@@ -31,13 +36,14 @@ static size_t symbol__fprintf(struct symbol *self, FILE *fp) | |||
31 | self->start, self->end, self->name); | 36 | self->start, self->end, self->name); |
32 | } | 37 | } |
33 | 38 | ||
34 | struct dso *dso__new(const char *name) | 39 | struct dso *dso__new(const char *name, unsigned int sym_priv_size) |
35 | { | 40 | { |
36 | struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); | 41 | struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); |
37 | 42 | ||
38 | if (self != NULL) { | 43 | if (self != NULL) { |
39 | strcpy(self->name, name); | 44 | strcpy(self->name, name); |
40 | self->syms = RB_ROOT; | 45 | self->syms = RB_ROOT; |
46 | self->sym_priv_size = sym_priv_size; | ||
41 | } | 47 | } |
42 | 48 | ||
43 | return self; | 49 | return self; |
@@ -51,7 +57,7 @@ static void dso__delete_symbols(struct dso *self) | |||
51 | while (next) { | 57 | while (next) { |
52 | pos = rb_entry(next, struct symbol, rb_node); | 58 | pos = rb_entry(next, struct symbol, rb_node); |
53 | next = rb_next(&pos->rb_node); | 59 | next = rb_next(&pos->rb_node); |
54 | symbol__delete(pos); | 60 | symbol__delete(pos, self->sym_priv_size); |
55 | } | 61 | } |
56 | } | 62 | } |
57 | 63 | ||
@@ -189,7 +195,8 @@ int dso__load_kallsyms(struct dso *self) | |||
189 | /* | 195 | /* |
190 | * Well fix up the end later, when we have all sorted. | 196 | * Well fix up the end later, when we have all sorted. |
191 | */ | 197 | */ |
192 | sym = symbol__new(start, 0xdead, line + len + 2); | 198 | sym = symbol__new(start, 0xdead, line + len + 2, |
199 | self->sym_priv_size); | ||
193 | 200 | ||
194 | if (sym == NULL) | 201 | if (sym == NULL) |
195 | goto out_delete_line; | 202 | goto out_delete_line; |
@@ -340,7 +347,8 @@ static int dso__load_sym(struct dso *self, int fd, const char *name) | |||
340 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; | 347 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; |
341 | 348 | ||
342 | f = symbol__new(sym.st_value, sym.st_size, | 349 | f = symbol__new(sym.st_value, sym.st_size, |
343 | elf_sym__name(&sym, symstrs)); | 350 | elf_sym__name(&sym, symstrs), |
351 | self->sym_priv_size); | ||
344 | if (!f) | 352 | if (!f) |
345 | goto out_elf_end; | 353 | goto out_elf_end; |
346 | 354 | ||
diff --git a/Documentation/perf_counter/util/symbol.h b/Documentation/perf_counter/util/symbol.h index 6dffe76a28f0..9e120af9c71f 100644 --- a/Documentation/perf_counter/util/symbol.h +++ b/Documentation/perf_counter/util/symbol.h | |||
@@ -15,12 +15,18 @@ struct symbol { | |||
15 | struct dso { | 15 | struct dso { |
16 | struct list_head node; | 16 | struct list_head node; |
17 | struct rb_root syms; | 17 | struct rb_root syms; |
18 | unsigned int sym_priv_size; | ||
18 | char name[0]; | 19 | char name[0]; |
19 | }; | 20 | }; |
20 | 21 | ||
21 | struct dso *dso__new(const char *name); | 22 | struct dso *dso__new(const char *name, unsigned int sym_priv_size); |
22 | void dso__delete(struct dso *self); | 23 | void dso__delete(struct dso *self); |
23 | 24 | ||
25 | static inline void *dso__sym_priv(struct dso *self, struct symbol *sym) | ||
26 | { | ||
27 | return ((void *)sym) - self->sym_priv_size; | ||
28 | } | ||
29 | |||
24 | struct symbol *dso__find_symbol(struct dso *self, uint64_t ip); | 30 | struct symbol *dso__find_symbol(struct dso *self, uint64_t ip); |
25 | 31 | ||
26 | int dso__load_kallsyms(struct dso *self); | 32 | int dso__load_kallsyms(struct dso *self); |