summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-annotate.c73
-rw-r--r--tools/perf/builtin-report.c79
-rw-r--r--tools/perf/builtin-top.c74
-rw-r--r--tools/perf/util/event.h6
-rw-r--r--tools/perf/util/module.c545
-rw-r--r--tools/perf/util/module.h53
-rw-r--r--tools/perf/util/sort.c38
-rw-r--r--tools/perf/util/sort.h7
-rw-r--r--tools/perf/util/symbol.c447
-rw-r--r--tools/perf/util/symbol.h20
-rw-r--r--tools/perf/util/thread.c34
-rw-r--r--tools/perf/util/thread.h4
13 files changed, 453 insertions, 929 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 055290a5b835..8e7509f2d882 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -336,7 +336,6 @@ LIB_H += util/strlist.h
LIB_H += util/run-command.h
LIB_H += util/sigchain.h
LIB_H += util/symbol.h
-LIB_H += util/module.h
LIB_H += util/color.h
LIB_H += util/values.h
LIB_H += util/sort.h
@@ -364,7 +363,6 @@ LIB_OBJS += util/usage.o
LIB_OBJS += util/wrapper.o
LIB_OBJS += util/sigchain.o
LIB_OBJS += util/symbol.o
-LIB_OBJS += util/module.o
LIB_OBJS += util/color.o
LIB_OBJS += util/pager.o
LIB_OBJS += util/header.o
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index df516dce9540..7d5a3b1bcda9 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -63,6 +63,7 @@ static void hist_hit(struct hist_entry *he, u64 ip)
return;
sym_size = sym->end - sym->start;
+ ip = he->map->map_ip(he->map, ip);
offset = ip - sym->start;
if (offset >= sym_size)
@@ -80,7 +81,7 @@ static void hist_hit(struct hist_entry *he, u64 ip)
}
static int
-hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
+hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, u64 ip, char level)
{
struct rb_node **p = &hist.rb_node;
@@ -89,7 +90,6 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
struct hist_entry entry = {
.thread = thread,
.map = map,
- .dso = dso,
.sym = sym,
.ip = ip,
.level = level,
@@ -130,10 +130,10 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
{
char level;
int show = 0;
- struct dso *dso = NULL;
struct thread *thread;
u64 ip = event->ip.ip;
struct map *map = NULL;
+ struct symbol *sym = NULL;
thread = threads__findnew(event->ip.pid, &threads, &last_match);
@@ -155,32 +155,35 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
show = SHOW_KERNEL;
level = 'k';
-
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
+ sym = kernel_maps__find_symbol(ip, &map);
+ dump_printf(" ...... dso: %s\n",
+ map ? map->dso->long_name : "<not found>");
} else if (event->header.misc & PERF_RECORD_MISC_USER) {
-
show = SHOW_USER;
level = '.';
-
map = thread__find_map(thread, ip);
if (map != NULL) {
+got_map:
ip = map->map_ip(map, ip);
- dso = map->dso;
+ sym = map->dso->find_symbol(map->dso, ip);
} else {
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
- * vsyscall (which executes in user-mode):
+ * vsyscall or vdso (which executes in user-mode).
+ *
+ * XXX This is nasty, we should have a symbol list in
+ * the "[vdso]" dso, but for now lets use the old
+ * trick of looking in the whole kernel symbol list.
*/
- if ((long long)ip < 0)
- dso = kernel_dso;
+ if ((long long)ip < 0) {
+ map = kernel_map;
+ goto got_map;
+ }
}
- dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
-
+ dump_printf(" ...... dso: %s\n",
+ map ? map->dso->long_name : "<not found>");
} else {
show = SHOW_HV;
level = 'H';
@@ -188,12 +191,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
}
if (show & show_mask) {
- struct symbol *sym = NULL;
-
- if (dso)
- sym = dso->find_symbol(dso, ip);
-
- if (hist_entry__add(thread, map, dso, sym, ip, level)) {
+ if (hist_entry__add(thread, map, sym, ip, level)) {
fprintf(stderr,
"problem incrementing symbol count, skipping event\n");
return -1;
@@ -313,7 +311,7 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
}
static int
-parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
+parse_line(FILE *file, struct symbol *sym, u64 len)
{
char *line = NULL, *tmp, *tmp2;
static const char *prev_line;
@@ -363,7 +361,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
const char *color;
struct sym_ext *sym_ext = sym->priv;
- offset = line_ip - start;
+ offset = line_ip - sym->start;
if (offset < len)
hits = sym->hist[offset];
@@ -442,7 +440,7 @@ static void free_source_line(struct symbol *sym, int len)
/* Get the filename:line for the colored entries */
static void
-get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
+get_source_line(struct symbol *sym, int len, const char *filename)
{
int i;
char cmd[PATH_MAX * 2];
@@ -467,7 +465,7 @@ get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
if (sym_ext[i].percent <= 0.5)
continue;
- offset = start + i;
+ offset = sym->start + i;
sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
fp = popen(cmd, "r");
if (!fp)
@@ -519,31 +517,23 @@ static void print_summary(const char *filename)
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
- const char *filename = dso->name, *d_filename;
- u64 start, end, len;
+ const char *filename = dso->long_name, *d_filename;
+ u64 len;
char command[PATH_MAX*2];
FILE *file;
if (!filename)
return;
- if (sym->module)
- filename = sym->module->path;
- else if (dso == kernel_dso)
- filename = vmlinux_name;
-
- start = sym->obj_start;
- if (!start)
- start = sym->start;
+
if (full_paths)
d_filename = filename;
else
d_filename = basename(filename);
- end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
if (print_line) {
- get_source_line(sym, start, len, filename);
+ get_source_line(sym, len, filename);
print_summary(filename);
}
@@ -552,10 +542,11 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
printf("------------------------------------------------\n");
if (verbose >= 2)
- printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
+ printf("annotating [%p] %30s : [%p] %30s\n",
+ dso, dso->long_name, sym, sym->name);
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
- (u64)start, (u64)end, filename, filename);
+ sym->start, sym->end, filename, filename);
if (verbose >= 3)
printf("doing: %s\n", command);
@@ -565,7 +556,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
return;
while (!feof(file)) {
- if (parse_line(file, sym, start, len) < 0)
+ if (parse_line(file, sym, len) < 0)
break;
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c1a54fc8527a..3ed3baf96ffb 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -349,22 +349,17 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
static struct symbol *
-resolve_symbol(struct thread *thread, struct map **mapp,
- struct dso **dsop, u64 *ipp)
+resolve_symbol(struct thread *thread, struct map **mapp, u64 *ipp)
{
- struct dso *dso = dsop ? *dsop : NULL;
struct map *map = mapp ? *mapp : NULL;
u64 ip = *ipp;
- if (!thread)
- return NULL;
-
- if (dso)
- goto got_dso;
-
if (map)
goto got_map;
+ if (!thread)
+ return NULL;
+
map = thread__find_map(thread, ip);
if (map != NULL) {
/*
@@ -379,29 +374,29 @@ resolve_symbol(struct thread *thread, struct map **mapp,
*mapp = map;
got_map:
ip = map->map_ip(map, ip);
-
- dso = map->dso;
} else {
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
- * vsyscall (which executes in user-mode):
+ * vsyscall or vdso (which executes in user-mode).
+ *
+ * XXX This is nasty, we should have a symbol list in
+ * the "[vdso]" dso, but for now lets use the old
+ * trick of looking in the whole kernel symbol list.
*/
- if ((long long)ip < 0)
- dso = kernel_dso;
+ if ((long long)ip < 0) {
+ map = kernel_map;
+ if (mapp)
+ *mapp = map;
+ }
}
- dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
+ dump_printf(" ...... dso: %s\n",
+ map ? map->dso->long_name : "<not found>");
dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
*ipp = ip;
- if (dsop)
- *dsop = dso;
-
- if (!dso)
- return NULL;
-got_dso:
- return dso->find_symbol(dso, ip);
+ return map ? map->dso->find_symbol(map->dso, ip) : NULL;
}
static int call__match(struct symbol *sym)
@@ -413,7 +408,7 @@ static int call__match(struct symbol *sym)
}
static struct symbol **
-resolve_callchain(struct thread *thread, struct map *map __used,
+resolve_callchain(struct thread *thread, struct map *map,
struct ip_callchain *chain, struct hist_entry *entry)
{
u64 context = PERF_CONTEXT_MAX;
@@ -430,8 +425,7 @@ resolve_callchain(struct thread *thread, struct map *map __used,
for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
- struct dso *dso = NULL;
- struct symbol *sym;
+ struct symbol *sym = NULL;
if (ip >= PERF_CONTEXT_MAX) {
context = ip;
@@ -440,17 +434,15 @@ resolve_callchain(struct thread *thread, struct map *map __used,
switch (context) {
case PERF_CONTEXT_HV:
- dso = hypervisor_dso;
break;
case PERF_CONTEXT_KERNEL:
- dso = kernel_dso;
+ sym = kernel_maps__find_symbol(ip, &map);
break;
default:
+ sym = resolve_symbol(thread, &map, &ip);
break;
}
- sym = resolve_symbol(thread, NULL, &dso, &ip);
-
if (sym) {
if (sort__has_parent && call__match(sym) &&
!entry->parent)
@@ -469,7 +461,7 @@ resolve_callchain(struct thread *thread, struct map *map __used,
*/
static int
-hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
+hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, u64 ip, struct ip_callchain *chain,
char level, u64 count)
{
@@ -480,7 +472,6 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
struct hist_entry entry = {
.thread = thread,
.map = map,
- .dso = dso,
.sym = sym,
.ip = ip,
.level = level,
@@ -641,7 +632,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
{
char level;
int show = 0;
- struct dso *dso = NULL;
+ struct symbol *sym = NULL;
struct thread *thread;
u64 ip = event->ip.ip;
u64 period = 1;
@@ -700,35 +691,35 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
show = SHOW_KERNEL;
level = 'k';
- dso = kernel_dso;
-
- dump_printf(" ...... dso: %s\n", dso->name);
-
+ sym = kernel_maps__find_symbol(ip, &map);
+ dump_printf(" ...... dso: %s\n",
+ map ? map->dso->long_name : "<not found>");
} else if (cpumode == PERF_RECORD_MISC_USER) {
show = SHOW_USER;
level = '.';
+ sym = resolve_symbol(thread, &map, &ip);
} else {
show = SHOW_HV;
level = 'H';
- dso = hypervisor_dso;
-
dump_printf(" ...... dso: [hypervisor]\n");
}
if (show & show_mask) {
- struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
-
- if (dso_list && (!dso || !dso->name ||
- !strlist__has_entry(dso_list, dso->name)))
+ if (dso_list &&
+ (!map || !map->dso ||
+ !(strlist__has_entry(dso_list, map->dso->short_name) ||
+ (map->dso->short_name != map->dso->long_name &&
+ strlist__has_entry(dso_list, map->dso->long_name)))))
return 0;
- if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name)))
+ if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
return 0;
- if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
+ if (hist_entry__add(thread, map, sym, ip,
+ chain, level, period)) {
eprintf("problem incrementing symbol count, skipping event\n");
return -1;
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index bf464ce7e3e2..befef842757e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -22,6 +22,7 @@
#include "util/symbol.h"
#include "util/color.h"
+#include "util/thread.h"
#include "util/util.h"
#include <linux/rbtree.h>
#include "util/parse-options.h"
@@ -103,6 +104,7 @@ struct sym_entry {
unsigned long snap_count;
double weight;
int skip;
+ struct map *map;
struct source_line *source;
struct source_line *lines;
struct source_line **lines_tail;
@@ -116,12 +118,11 @@ struct sym_entry {
static void parse_source(struct sym_entry *syme)
{
struct symbol *sym;
- struct module *module;
- struct section *section = NULL;
+ struct map *map;
FILE *file;
char command[PATH_MAX*2];
- const char *path = vmlinux_name;
- u64 start, end, len;
+ const char *path;
+ u64 len;
if (!syme)
return;
@@ -132,27 +133,15 @@ static void parse_source(struct sym_entry *syme)
}
sym = (struct symbol *)(syme + 1);
- module = sym->module;
+ map = syme->map;
+ path = map->dso->long_name;
- if (module)
- path = module->path;
- if (!path)
- return;
-
- start = sym->obj_start;
- if (!start)
- start = sym->start;
-
- if (module) {
- section = module->sections->find_section(module->sections, ".text");
- if (section)
- start -= section->vma;
- }
-
- end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
- sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", start, end, path);
+ sprintf(command,
+ "objdump --start-address=0x%016Lx "
+ "--stop-address=0x%016Lx -dS %s",
+ sym->start, sym->end, path);
file = popen(command, "r");
if (!file)
@@ -184,13 +173,11 @@ static void parse_source(struct sym_entry *syme)
if (strlen(src->line)>8 && src->line[8] == ':') {
src->eip = strtoull(src->line, NULL, 16);
- if (section)
- src->eip += section->vma;
+ src->eip += map->start;
}
if (strlen(src->line)>8 && src->line[16] == ':') {
src->eip = strtoull(src->line, NULL, 16);
- if (section)
- src->eip += section->vma;
+ src->eip += map->start;
}
}
pclose(file);
@@ -242,16 +229,9 @@ static void lookup_sym_source(struct sym_entry *syme)
struct symbol *symbol = (struct symbol *)(syme + 1);
struct source_line *line;
char pattern[PATH_MAX];
- char *idx;
sprintf(pattern, "<%s>:", symbol->name);
- if (symbol->module) {
- idx = strstr(pattern, "\t");
- if (idx)
- *idx = 0;
- }
-
pthread_mutex_lock(&syme->source_lock);
for (line = syme->lines; line; line = line->next) {
if (strstr(line->line, pattern)) {
@@ -513,8 +493,8 @@ static void print_sym_table(void)
if (verbose)
printf(" - %016llx", sym->start);
printf(" : %s", sym->name);
- if (sym->module)
- printf("\t[%s]", sym->module->name);
+ if (syme->map->dso->name[0] == '[')
+ printf(" \t%s", syme->map->dso->name);
printf("\n");
}
}
@@ -784,7 +764,7 @@ static const char *skip_symbols[] = {
NULL
};
-static int symbol_filter(struct dso *self, struct symbol *sym)
+static int symbol_filter(struct map *map, struct symbol *sym)
{
struct sym_entry *syme;
const char *name = sym->name;
@@ -806,7 +786,8 @@ static int symbol_filter(struct dso *self, struct symbol *sym)
strstr(name, "_text_end"))
return 1;
- syme = dso__sym_priv(self, sym);
+ syme = dso__sym_priv(map->dso, sym);
+ syme->map = map;
pthread_mutex_init(&syme->source_lock, NULL);
if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter))
sym_filter_entry = syme;
@@ -825,22 +806,14 @@ static int parse_symbols(void)
{
int use_modules = vmlinux_name ? 1 : 0;
- kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry));
- if (kernel_dso == NULL)
+ if (dsos__load_kernel(vmlinux_name, sizeof(struct sym_entry),
+ symbol_filter, verbose, use_modules) <= 0)
return -1;
- if (dso__load_kernel(kernel_dso, vmlinux_name, symbol_filter, verbose, use_modules) <= 0)
- goto out_delete_dso;
-
if (dump_symtab)
- dso__fprintf(kernel_dso, stderr);
+ dsos__fprintf(stderr);
return 0;
-
-out_delete_dso:
- dso__delete(kernel_dso);
- kernel_dso = NULL;
- return -1;
}
/*
@@ -848,10 +821,11 @@ out_delete_dso:
*/
static void record_ip(u64 ip, int counter)
{
- struct symbol *sym = dso__find_symbol(kernel_dso, ip);
+ struct map *map;
+ struct symbol *sym = kernel_maps__find_symbol(ip, &map);
if (sym != NULL) {
- struct sym_entry *syme = dso__sym_priv(kernel_dso, sym);
+ struct sym_entry *syme = dso__sym_priv(map->dso, sym);
if (!syme->skip) {
syme->count[counter]++;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 4c69eb553807..a39520e6ae8f 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -3,6 +3,7 @@
#include "../perf.h"
#include "util.h"
+#include <linux/list.h>
#include <linux/rbtree.h>
enum {
@@ -79,7 +80,10 @@ typedef union event_union {
} event_t;
struct map {
- struct rb_node rb_node;
+ union {
+ struct rb_node rb_node;
+ struct list_head node;
+ };
u64 start;
u64 end;
u64 pgoff;
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c
deleted file mode 100644
index 0d8c85defcd2..000000000000
--- a/tools/perf/util/module.c
+++ /dev/null
@@ -1,545 +0,0 @@
-#include "util.h"
-#include "../perf.h"
-#include "string.h"
-#include "module.h"
-
-#include <libelf.h>
-#include <libgen.h>
-#include <gelf.h>
-#include <elf.h>
-#include <dirent.h>
-#include <sys/utsname.h>
-
-static unsigned int crc32(const char *p, unsigned int len)
-{
- int i;
- unsigned int crc = 0;
-
- while (len--) {
- crc ^= *p++;
- for (i = 0; i < 8; i++)
- crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
- }
- return crc;
-}
-
-/* module section methods */
-
-struct sec_dso *sec_dso__new_dso(const char *name)
-{
- struct sec_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
-
- if (self != NULL) {
- strcpy(self->name, name);
- self->secs = RB_ROOT;
- self->find_section = sec_dso__find_section;
- }
-
- return self;
-}
-
-static void sec_dso__delete_section(struct section *self)
-{
- free(((void *)self));
-}
-
-void sec_dso__delete_sections(struct sec_dso *self)
-{
- struct section *pos;
- struct rb_node *next = rb_first(&self->secs);
-
- while (next) {
- pos = rb_entry(next, struct section, rb_node);
- next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, &self->secs);
- sec_dso__delete_section(pos);
- }
-}
-
-void sec_dso__delete_self(struct sec_dso *self)
-{
- sec_dso__delete_sections(self);
- free(self);
-}
-
-static void sec_dso__insert_section(struct sec_dso *self, struct section *sec)
-{
- struct rb_node **p = &self->secs.rb_node;
- struct rb_node *parent = NULL;
- const u64 hash = sec->hash;
- struct section *s;
-
- while (*p != NULL) {
- parent = *p;
- s = rb_entry(parent, struct section, rb_node);
- if (hash < s->hash)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
- rb_link_node(&sec->rb_node, parent, p);
- rb_insert_color(&sec->rb_node, &self->secs);
-}
-
-struct section *sec_dso__find_section(struct sec_dso *self, const char *name)
-{
- struct rb_node *n;
- u64 hash;
- int len;
-
- if (self == NULL)
- return NULL;
-
- len = strlen(name);
- hash = crc32(name, len);
-
- n = self->secs.rb_node;
-
- while (n) {
- struct section *s = rb_entry(n, struct section, rb_node);
-
- if (hash < s->hash)
- n = n->rb_left;
- else if (hash > s->hash)
- n = n->rb_right;
- else {
- if (!strcmp(name, s->name))
- return s;
- else
- n = rb_next(&s->rb_node);
- }
- }
-
- return NULL;
-}
-
-static size_t sec_dso__fprintf_section(struct section *self, FILE *fp)
-{
- return fprintf(fp, "name:%s vma:%llx path:%s\n",
- self->name, self->vma, self->path);
-}
-
-size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp)
-{
- size_t ret = fprintf(fp, "dso: %s\n", self->name);
-
- struct rb_node *nd;
- for (nd = rb_first(&self->secs); nd; nd = rb_next(nd)) {
- struct section *pos = rb_entry(nd, struct section, rb_node);
- ret += sec_dso__fprintf_section(pos, fp);
- }
-
- return ret;
-}
-
-static struct section *section__new(const char *name, const char *path)
-{
- struct section *self = calloc(1, sizeof(*self));
-
- if (!self)
- goto out_failure;
-
- self->name = calloc(1, strlen(name) + 1);
- if (!self->name)
- goto out_failure;
-
- self->path = calloc(1, strlen(path) + 1);
- if (!self->path)
- goto out_failure;
-
- strcpy(self->name, name);
- strcpy(self->path, path);
- self->hash = crc32(self->name, strlen(name));
-
- return self;
-
-out_failure:
- if (self) {
- if (self->name)
- free(self->name);
- if (self->path)
- free(self->path);
- free(self);
- }
-
- return NULL;
-}
-
-/* module methods */
-
-struct mod_dso *mod_dso__new_dso(const char *name)
-{
- struct mod_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
-
- if (self != NULL) {
- strcpy(self->name, name);
- self->mods = RB_ROOT;
- self->find_module = mod_dso__find_module;
- }
-
- return self;
-}
-
-static void mod_dso__delete_module(struct module *self)
-{
- free(((void *)self));
-}
-
-void mod_dso__delete_modules(struct mod_dso *self)
-{
- struct module *pos;
- struct rb_node *next = rb_first(&self->mods);
-
- while (next) {
- pos = rb_entry(next, struct module, rb_node);
- next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, &self->mods);
- mod_dso__delete_module(pos);
- }
-}
-
-void mod_dso__delete_self(struct mod_dso *self)
-{
- mod_dso__delete_modules(self);
- free(self);
-}
-
-static void mod_dso__insert_module(struct mod_dso *self, struct module *mod)
-{
- struct rb_node **p = &self->mods.rb_node;
- struct rb_node *parent = NULL;
- const u64 hash = mod->hash;
- struct module *m;
-
- while (*p != NULL) {
- parent = *p;
- m = rb_entry(parent, struct module, rb_node);
- if (hash < m->hash)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
- rb_link_node(&mod->rb_node, parent, p);
- rb_insert_color(&mod->rb_node, &self->mods);
-}
-
-struct module *mod_dso__find_module(struct mod_dso *self, const char *name)
-{
- struct rb_node *n;
- u64 hash;
- int len;
-
- if (self == NULL)
- return NULL;
-
- len = strlen(name);
- hash = crc32(name, len);
-
- n = self->mods.rb_node;
-
- while (n) {
- struct module *m = rb_entry(n, struct module, rb_node);
-
- if (hash < m->hash)
- n = n->rb_left;
- else if (hash > m->hash)
- n = n->rb_right;
- else {
- if (!strcmp(name, m->name))
- return m;
- else
- n = rb_next(&m->rb_node);
- }
- }
-
- return NULL;
-}
-
-static size_t mod_dso__fprintf_module(struct module *self, FILE *fp)
-{
- return fprintf(fp, "name:%s path:%s\n", self->name, self->path);
-}
-
-size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp)
-{
- struct rb_node *nd;
- size_t ret;
-
- ret = fprintf(fp, "dso: %s\n", self->name);
-
- for (nd = rb_first(&self->mods); nd; nd = rb_next(nd)) {
- struct module *pos = rb_entry(nd, struct module, rb_node);
-
- ret += mod_dso__fprintf_module(pos, fp);
- }
-
- return ret;
-}
-
-static struct module *module__new(const char *name, const char *path)
-{
- struct module *self = calloc(1, sizeof(*self));
-
- if (!self)
- goto out_failure;
-
- self->name = calloc(1, strlen(name) + 1);
- if (!self->name)
- goto out_failure;
-
- self->path = calloc(1, strlen(path) + 1);
- if (!self->path)
- goto out_failure;
-
- strcpy(self->name, name);
- strcpy(self->path, path);
- self->hash = crc32(self->name, strlen(name));
-
- return self;
-
-out_failure:
- if (self) {
- if (self->name)
- free(self->name);
- if (self->path)
- free(self->path);
- free(self);
- }
-
- return NULL;
-}
-
-static int mod_dso__load_sections(struct module *mod)
-{
- int count = 0, path_len;
- struct dirent *entry;
- char *line = NULL;
- char *dir_path;
- DIR *dir;
- size_t n;
-
- path_len = strlen("/sys/module/");
- path_len += strlen(mod->name);
- path_len += strlen("/sections/");
-
- dir_path = calloc(1, path_len + 1);
- if (dir_path == NULL)
- goto out_failure;
-
- strcat(dir_path, "/sys/module/");
- strcat(dir_path, mod->name);
- strcat(dir_path, "/sections/");
-
- dir = opendir(dir_path);
- if (dir == NULL)
- goto out_free;
-
- while ((entry = readdir(dir))) {
- struct section *section;
- char *path, *vma;
- int line_len;
- FILE *file;
-
- if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name))
- continue;
-
- path = calloc(1, path_len + strlen(entry->d_name) + 1);
- if (path == NULL)
- break;
- strcat(path, dir_path);
- strcat(path, entry->d_name);
-
- file = fopen(path, "r");
- if (file == NULL) {
- free(path);
- break;
- }
-
- line_len = getline(&line, &n, file);
- if (line_len < 0) {
- free(path);
- fclose(file);
- break;
- }
-
- if (!line) {
- free(path);
- fclose(file);
- break;
- }
-
- line[--line_len] = '\0'; /* \n */
-
- vma = strstr(line, "0x");
- if (!vma) {
- free(path);
- fclose(file);
- break;
- }
- vma += 2;
-
- section = section__new(entry->d_name, path);
- if (!section) {
- fprintf(stderr, "load_sections: allocation error\n");
- free(path);
- fclose(file);
- break;
- }
-
- hex2u64(vma, &section->vma);
- sec_dso__insert_section(mod->sections, section);
-
- free(path);
- fclose(file);
- count++;
- }
-
- closedir(dir);
- free(line);
- free(dir_path);
-
- return count;
-
-out_free:
- free(dir_path);
-
-out_failure:
- return count;
-}
-
-static int mod_dso__load_module_paths(struct mod_dso *self)
-{
- struct utsname uts;
- int count = 0, len, err = -1;
- char *line = NULL;
- FILE *file;
- char *dpath, *dir;
- size_t n;
-
- if (uname(&uts) < 0)
- return err;
-
- len = strlen("/lib/modules/");
- len += strlen(uts.release);
- len += strlen("/modules.dep");
-
- dpath = calloc(1, len + 1);
- if (dpath == NULL)
- return err;
-
- strcat(dpath, "/lib/modules/");
- strcat(dpath, uts.release);
- strcat(dpath, "/modules.dep");
-
- file = fopen(dpath, "r");
- if (file == NULL)
- goto out_failure;
-
- dir = dirname(dpath);
- if (!dir)
- goto out_failure;
- strcat(dir, "/");
-
- while (!feof(file)) {
- struct module *module;
- char *name, *path, *tmp;
- FILE *modfile;
- int line_len;
-
- line_len = getline(&line, &n, file);
- if (line_len < 0)
- break;
-
- if (!line)
- break;
-
- line[--line_len] = '\0'; /* \n */
-
- path = strchr(line, ':');
- if (!path)
- break;
- *path = '\0';
-
- path = strdup(line);
- if (!path)
- break;
-
- if (!strstr(path, dir)) {
- if (strncmp(path, "kernel/", 7))
- break;
-
- free(path);
- path = calloc(1, strlen(dir) + strlen(line) + 1);
- if (!path)
- break;
- strcat(path, dir);
- strcat(path, line);
- }
-
- modfile = fopen(path, "r");
- if (modfile == NULL)
- break;
- fclose(modfile);
-
- name = strdup(path);
- if (!name)
- break;
-
- name = strtok(name, "/");
- tmp = name;
-
- while (tmp) {
- tmp = strtok(NULL, "/");
- if (tmp)
- name = tmp;
- }
-
- name = strsep(&name, ".");
- if (!name)
- break;
-
- /* Quirk: replace '-' with '_' in all modules */
- for (len = strlen(name); len; len--) {
- if (*(name+len) == '-')
- *(name+len) = '_';
- }
-
- module = module__new(name, path);
- if (!module)
- break;
- mod_dso__insert_module(self, module);
-
- module->sections = sec_dso__new_dso("sections");
- if (!module->sections)
- break;
-
- module->active = mod_dso__load_sections(module);
-
- if (module->active > 0)
- count++;
- }
-
- if (feof(file))
- err = count;
- else
- fprintf(stderr, "load_module_paths: modules.dep parsing failure!\n");
-
-out_failure:
- if (dpath)
- free(dpath);
- if (file)
- fclose(file);
- if (line)
- free(line);
-
- return err;
-}
-
-int mod_dso__load_modules(struct mod_dso *dso)
-{
- int err;
-
- err = mod_dso__load_module_paths(dso);
-
- return err;
-}
diff --git a/tools/perf/util/module.h b/tools/perf/util/module.h
deleted file mode 100644
index 098e0412bc22..000000000000
--- a/tools/perf/util/module.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __PERF_MODULE_
-#define __PERF_MODULE_ 1
-
-#include <linux/types.h>
-#include "../types.h"
-#include <linux/list.h>
-#include <linux/rbtree.h>
-
-struct section {
- struct rb_node rb_node;
- u64 hash;
- u64 vma;
- char *name;
- char *path;
-};
-
-struct sec_dso {
- struct list_head node;
- struct rb_root secs;
- struct section *(*find_section)(struct sec_dso *, const cha