2012-10-27 21:18:58

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 0/5] perf dso: Separate dso symbols to separate object

hi,
separating dso related stuff into dso object plus some other symbol
object cleanup. It's just a code moving, no actual change was done.

Attached patches:
1/5 perf tool: Move build_id__sprintf into build-id object
2/5 perf tool: Move BUILD_ID_SIZE into build-id object
3/5 perf tool: Move hex2u64 into util object
4/5 perf tool: Move strxfrchar into string object
5/5 perf tool: Move dso_* related functions into dso object

Also available in:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
perf/dso1

thanks,
jirka

Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Makefile | 2 +
tools/perf/builtin-buildid-cache.c | 1 +
tools/perf/util/annotate.c | 1 +
tools/perf/util/build-id.c | 15 ++
tools/perf/util/build-id.h | 7 +-
tools/perf/util/dso.c | 594 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/dso.h | 148 +++++++++++++++
tools/perf/util/event.h | 3 +-
tools/perf/util/header.c | 1 +
tools/perf/util/map.c | 1 +
tools/perf/util/string.c | 18 ++
tools/perf/util/symbol.c | 657 +------------------------------------------------------------------
tools/perf/util/symbol.h | 141 +--------------
tools/perf/util/util.c | 33 ++++
tools/perf/util/util.h | 2 +
15 files changed, 831 insertions(+), 793 deletions(-)


2012-10-27 21:18:59

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 2/5] perf tool: Move BUILD_ID_SIZE into build-id object

Moving BUILD_ID_SIZE define into build-id object,
plus include related changes.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-buildid-cache.c | 1 +
tools/perf/util/annotate.c | 1 +
tools/perf/util/build-id.h | 6 +++++-
tools/perf/util/event.h | 3 +--
tools/perf/util/symbol.h | 3 +--
5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index edb26ea..fae8b25 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -14,6 +14,7 @@
#include "util/parse-options.h"
#include "util/strlist.h"
#include "util/build-id.h"
+#include "util/symbol.h"

static int build_id_cache__add_file(const char *filename, const char *debugdir)
{
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index f0a9103..7a34dd1 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -15,6 +15,7 @@
#include "debug.h"
#include "annotate.h"
#include <pthread.h>
+#include <linux/bitops.h>

const char *disassembler_style;
const char *objdump_path;
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index f6d9ff9..a811f5c 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -1,9 +1,13 @@
#ifndef PERF_BUILD_ID_H_
#define PERF_BUILD_ID_H_ 1

-#include "session.h"
+#define BUILD_ID_SIZE 20
+
+#include "tool.h"
+#include "types.h"

extern struct perf_tool build_id__mark_dso_hit_ops;
+struct dso;

int build_id__sprintf(const u8 *build_id, int len, char *bf);
char *dso__build_id_filename(struct dso *self, char *bf, size_t size);
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index da97aff..0d573ff 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -6,6 +6,7 @@

#include "../perf.h"
#include "map.h"
+#include "build-id.h"

/*
* PERF_SAMPLE_IP | PERF_SAMPLE_TID | *
@@ -96,8 +97,6 @@ struct perf_sample {
struct stack_dump user_stack;
};

-#define BUILD_ID_SIZE 20
-
struct build_id_event {
struct perf_event_header header;
pid_t pid;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index d70f676..6eb7d3b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <byteswap.h>
#include <libgen.h>
+#include "build-id.h"

#ifdef LIBELF_SUPPORT
#include <libelf.h>
@@ -57,8 +58,6 @@ char *strxfrchar(char *s, char from, char to);
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#endif

-#define BUILD_ID_SIZE 20
-
/** struct symbol - symtab entry
*
* @ignore - resolvable but tools ignore it (e.g. idle routines)
--
1.7.11.7

2012-10-27 21:19:08

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 5/5] perf tool: Move dso_* related functions into dso object

Moving dso_* related functions into dso object.

Keeping symbol loading related functions still in the symbol
object as it seems more convenient.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Makefile | 2 +
tools/perf/util/dso.c | 594 ++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/dso.h | 148 ++++++++++++
tools/perf/util/symbol.c | 599 +----------------------------------------------
tools/perf/util/symbol.h | 134 +----------
5 files changed, 751 insertions(+), 726 deletions(-)
create mode 100644 tools/perf/util/dso.c
create mode 100644 tools/perf/util/dso.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 629fc6a..ec63d53 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -327,6 +327,7 @@ LIB_H += util/svghelper.h
LIB_H += util/tool.h
LIB_H += util/run-command.h
LIB_H += util/sigchain.h
+LIB_H += util/dso.h
LIB_H += util/symbol.h
LIB_H += util/color.h
LIB_H += util/values.h
@@ -385,6 +386,7 @@ LIB_OBJS += $(OUTPUT)util/top.o
LIB_OBJS += $(OUTPUT)util/usage.o
LIB_OBJS += $(OUTPUT)util/wrapper.o
LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/dso.o
LIB_OBJS += $(OUTPUT)util/symbol.o
LIB_OBJS += $(OUTPUT)util/symbol-elf.o
LIB_OBJS += $(OUTPUT)util/dso-test-data.o
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
new file mode 100644
index 0000000..bec91fd
--- /dev/null
+++ b/tools/perf/util/dso.c
@@ -0,0 +1,594 @@
+#include <symbol.h>
+#include "dso.h"
+#include "util.h"
+#include "debug.h"
+
+char dso__symtab_origin(const struct dso *dso)
+{
+ static const char origin[] = {
+ [DSO_BINARY_TYPE__KALLSYMS] = 'k',
+ [DSO_BINARY_TYPE__VMLINUX] = 'v',
+ [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
+ [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
+ [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
+ [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
+ [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
+ [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
+ [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
+ [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
+ [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
+ };
+
+ if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
+ return '!';
+ return origin[dso->symtab_type];
+}
+
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size)
+{
+ char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+ int ret = 0;
+
+ switch (type) {
+ case DSO_BINARY_TYPE__DEBUGLINK: {
+ char *debuglink;
+
+ strncpy(file, dso->long_name, size);
+ debuglink = file + dso->long_name_len;
+ while (debuglink != file && *debuglink != '/')
+ debuglink--;
+ if (*debuglink == '/')
+ debuglink++;
+ filename__read_debuglink(dso->long_name, debuglink,
+ size - (debuglink - file));
+ }
+ break;
+ case DSO_BINARY_TYPE__BUILD_ID_CACHE:
+ /* skip the locally configured cache if a symfs is given */
+ if (symbol_conf.symfs[0] ||
+ (dso__build_id_filename(dso, file, size) == NULL))
+ ret = -1;
+ break;
+
+ case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s.debug",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
+ if (!dso->has_build_id) {
+ ret = -1;
+ break;
+ }
+
+ build_id__sprintf(dso->build_id,
+ sizeof(dso->build_id),
+ build_id_hex);
+ snprintf(file, size,
+ "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+ symbol_conf.symfs, build_id_hex, build_id_hex + 2);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+ snprintf(file, size, "%s%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__GUEST_KMODULE:
+ snprintf(file, size, "%s%s%s", symbol_conf.symfs,
+ root_dir, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+ snprintf(file, size, "%s%s", symbol_conf.symfs,
+ dso->long_name);
+ break;
+
+ default:
+ case DSO_BINARY_TYPE__KALLSYMS:
+ case DSO_BINARY_TYPE__VMLINUX:
+ case DSO_BINARY_TYPE__GUEST_KALLSYMS:
+ case DSO_BINARY_TYPE__GUEST_VMLINUX:
+ case DSO_BINARY_TYPE__JAVA_JIT:
+ case DSO_BINARY_TYPE__NOT_FOUND:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int open_dso(struct dso *dso, struct machine *machine)
+{
+ char *root_dir = (char *) "";
+ char *name;
+ int fd;
+
+ name = malloc(PATH_MAX);
+ if (!name)
+ return -ENOMEM;
+
+ if (machine)
+ root_dir = machine->root_dir;
+
+ if (dso__binary_type_file(dso, dso->data_type,
+ root_dir, name, PATH_MAX)) {
+ free(name);
+ return -EINVAL;
+ }
+
+ fd = open(name, O_RDONLY);
+ free(name);
+ return fd;
+}
+
+int dso__data_fd(struct dso *dso, struct machine *machine)
+{
+ static enum dso_binary_type binary_type_data[] = {
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__NOT_FOUND,
+ };
+ int i = 0;
+
+ if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
+ return open_dso(dso, machine);
+
+ do {
+ int fd;
+
+ dso->data_type = binary_type_data[i++];
+
+ fd = open_dso(dso, machine);
+ if (fd >= 0)
+ return fd;
+
+ } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
+
+ return -EINVAL;
+}
+
+static void
+dso_cache__free(struct rb_root *root)
+{
+ struct rb_node *next = rb_first(root);
+
+ while (next) {
+ struct dso_cache *cache;
+
+ cache = rb_entry(next, struct dso_cache, rb_node);
+ next = rb_next(&cache->rb_node);
+ rb_erase(&cache->rb_node, root);
+ free(cache);
+ }
+}
+
+static struct dso_cache*
+dso_cache__find(struct rb_root *root, u64 offset)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ else
+ return cache;
+ }
+ return NULL;
+}
+
+static void
+dso_cache__insert(struct rb_root *root, struct dso_cache *new)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+ u64 offset = new->offset;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&new->rb_node, parent, p);
+ rb_insert_color(&new->rb_node, root);
+}
+
+static ssize_t
+dso_cache__memcpy(struct dso_cache *cache, u64 offset,
+ u8 *data, u64 size)
+{
+ u64 cache_offset = offset - cache->offset;
+ u64 cache_size = min(cache->size - cache_offset, size);
+
+ memcpy(data, cache->data + cache_offset, cache_size);
+ return cache_size;
+}
+
+static ssize_t
+dso_cache__read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+ ssize_t ret;
+ int fd;
+
+ fd = dso__data_fd(dso, machine);
+ if (fd < 0)
+ return -1;
+
+ do {
+ u64 cache_offset;
+
+ ret = -ENOMEM;
+
+ cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
+ if (!cache)
+ break;
+
+ cache_offset = offset & DSO__DATA_CACHE_MASK;
+ ret = -EINVAL;
+
+ if (-1 == lseek(fd, cache_offset, SEEK_SET))
+ break;
+
+ ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
+ if (ret <= 0)
+ break;
+
+ cache->offset = cache_offset;
+ cache->size = ret;
+ dso_cache__insert(&dso->cache, cache);
+
+ ret = dso_cache__memcpy(cache, offset, data, size);
+
+ } while (0);
+
+ if (ret <= 0)
+ free(cache);
+
+ close(fd);
+ return ret;
+}
+
+static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+
+ cache = dso_cache__find(&dso->cache, offset);
+ if (cache)
+ return dso_cache__memcpy(cache, offset, data, size);
+ else
+ return dso_cache__read(dso, machine, offset, data, size);
+}
+
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ ssize_t r = 0;
+ u8 *p = data;
+
+ do {
+ ssize_t ret;
+
+ ret = dso_cache_read(dso, machine, offset, p, size);
+ if (ret < 0)
+ return ret;
+
+ /* Reached EOF, return what we have. */
+ if (!ret)
+ break;
+
+ BUG_ON(ret > size);
+
+ r += ret;
+ p += ret;
+ offset += ret;
+ size -= ret;
+
+ } while (size);
+
+ return r;
+}
+
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size)
+{
+ u64 offset = map->map_ip(map, addr);
+ return dso__data_read_offset(dso, machine, offset, data, size);
+}
+
+struct map *dso__new_map(const char *name)
+{
+ struct map *map = NULL;
+ struct dso *dso = dso__new(name);
+
+ if (dso)
+ map = map__new2(0, dso, MAP__FUNCTION);
+
+ return map;
+}
+
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type)
+{
+ /*
+ * The kernel dso could be created by build_id processing.
+ */
+ struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
+
+ /*
+ * We need to run this in all cases, since during the build_id
+ * processing we had no idea this was the kernel dso.
+ */
+ if (dso != NULL) {
+ dso__set_short_name(dso, short_name);
+ dso->kernel = dso_type;
+ }
+
+ return dso;
+}
+
+void dso__set_long_name(struct dso *dso, char *name)
+{
+ if (name == NULL)
+ return;
+ dso->long_name = name;
+ dso->long_name_len = strlen(name);
+}
+
+void dso__set_short_name(struct dso *dso, const char *name)
+{
+ if (name == NULL)
+ return;
+ dso->short_name = name;
+ dso->short_name_len = strlen(name);
+}
+
+static void dso__set_basename(struct dso *dso)
+{
+ dso__set_short_name(dso, basename(dso->long_name));
+}
+
+int dso__name_len(const struct dso *dso)
+{
+ if (!dso)
+ return strlen("[unknown]");
+ if (verbose)
+ return dso->long_name_len;
+
+ return dso->short_name_len;
+}
+
+bool dso__loaded(const struct dso *dso, enum map_type type)
+{
+ return dso->loaded & (1 << type);
+}
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
+{
+ return dso->sorted_by_name & (1 << type);
+}
+
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
+{
+ dso->sorted_by_name |= (1 << type);
+}
+
+struct dso *dso__new(const char *name)
+{
+ struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
+
+ if (dso != NULL) {
+ int i;
+ strcpy(dso->name, name);
+ dso__set_long_name(dso, dso->name);
+ dso__set_short_name(dso, dso->name);
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
+ dso->cache = RB_ROOT;
+ dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->loaded = 0;
+ dso->sorted_by_name = 0;
+ dso->has_build_id = 0;
+ dso->kernel = DSO_TYPE_USER;
+ dso->needs_swap = DSO_SWAP__UNSET;
+ INIT_LIST_HEAD(&dso->node);
+ }
+
+ return dso;
+}
+
+void dso__delete(struct dso *dso)
+{
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ symbols__delete(&dso->symbols[i]);
+ if (dso->sname_alloc)
+ free((char *)dso->short_name);
+ if (dso->lname_alloc)
+ free(dso->long_name);
+ dso_cache__free(&dso->cache);
+ free(dso);
+}
+
+void dso__set_build_id(struct dso *dso, void *build_id)
+{
+ memcpy(dso->build_id, build_id, sizeof(dso->build_id));
+ dso->has_build_id = 1;
+}
+
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
+{
+ return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
+}
+
+void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
+{
+ char path[PATH_MAX];
+
+ if (machine__is_default_guest(machine))
+ return;
+ sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+ if (sysfs__read_build_id(path, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+}
+
+int dso__kernel_module_get_build_id(struct dso *dso,
+ const char *root_dir)
+{
+ char filename[PATH_MAX];
+ /*
+ * kernel module short names are of the form "[module]" and
+ * we need just "module" here.
+ */
+ const char *name = dso->short_name + 1;
+
+ snprintf(filename, sizeof(filename),
+ "%s/sys/module/%.*s/notes/.note.gnu.build-id",
+ root_dir, (int)strlen(name) - 1, name);
+
+ if (sysfs__read_build_id(filename, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+
+ return 0;
+}
+
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
+{
+ bool have_build_id = false;
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ if (pos->has_build_id) {
+ have_build_id = true;
+ continue;
+ }
+ if (filename__read_build_id(pos->long_name, pos->build_id,
+ sizeof(pos->build_id)) > 0) {
+ have_build_id = true;
+ pos->has_build_id = true;
+ }
+ }
+
+ return have_build_id;
+}
+
+void dsos__add(struct list_head *head, struct dso *dso)
+{
+ list_add_tail(&dso->node, head);
+}
+
+struct dso *dsos__find(struct list_head *head, const char *name)
+{
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node)
+ if (strcmp(pos->long_name, name) == 0)
+ return pos;
+ return NULL;
+}
+
+struct dso *__dsos__findnew(struct list_head *head, const char *name)
+{
+ struct dso *dso = dsos__find(head, name);
+
+ if (!dso) {
+ dso = dso__new(name);
+ if (dso != NULL) {
+ dsos__add(head, dso);
+ dso__set_basename(dso);
+ }
+ }
+
+ return dso;
+}
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ ret += dso__fprintf_buildid(pos, fp);
+ ret += fprintf(fp, " %s\n", pos->long_name);
+ }
+ return ret;
+}
+
+size_t __dsos__fprintf(struct list_head *head, FILE *fp)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ ret += dso__fprintf(pos, i, fp);
+ }
+
+ return ret;
+}
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
+{
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
+ return fprintf(fp, "%s", sbuild_id);
+}
+
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
+{
+ struct rb_node *nd;
+ size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
+
+ if (dso->short_name != dso->long_name)
+ ret += fprintf(fp, "%s, ", dso->long_name);
+ ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
+ dso->loaded ? "" : "NOT ");
+ ret += dso__fprintf_buildid(dso, fp);
+ ret += fprintf(fp, ")\n");
+ for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
+ struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
+ ret += symbol__fprintf(pos, fp);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
new file mode 100644
index 0000000..e032769
--- /dev/null
+++ b/tools/perf/util/dso.h
@@ -0,0 +1,148 @@
+#ifndef __PERF_DSO
+#define __PERF_DSO
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include "types.h"
+#include "map.h"
+
+enum dso_binary_type {
+ DSO_BINARY_TYPE__KALLSYMS = 0,
+ DSO_BINARY_TYPE__GUEST_KALLSYMS,
+ DSO_BINARY_TYPE__VMLINUX,
+ DSO_BINARY_TYPE__GUEST_VMLINUX,
+ DSO_BINARY_TYPE__JAVA_JIT,
+ DSO_BINARY_TYPE__DEBUGLINK,
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
+ DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
+ DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__GUEST_KMODULE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+ DSO_BINARY_TYPE__NOT_FOUND,
+};
+
+enum dso_kernel_type {
+ DSO_TYPE_USER = 0,
+ DSO_TYPE_KERNEL,
+ DSO_TYPE_GUEST_KERNEL
+};
+
+enum dso_swap_type {
+ DSO_SWAP__UNSET,
+ DSO_SWAP__NO,
+ DSO_SWAP__YES,
+};
+
+#define DSO__SWAP(dso, type, val) \
+({ \
+ type ____r = val; \
+ BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
+ if (dso->needs_swap == DSO_SWAP__YES) { \
+ switch (sizeof(____r)) { \
+ case 2: \
+ ____r = bswap_16(val); \
+ break; \
+ case 4: \
+ ____r = bswap_32(val); \
+ break; \
+ case 8: \
+ ____r = bswap_64(val); \
+ break; \
+ default: \
+ BUG_ON(1); \
+ } \
+ } \
+ ____r; \
+})
+
+#define DSO__DATA_CACHE_SIZE 4096
+#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
+
+struct dso_cache {
+ struct rb_node rb_node;
+ u64 offset;
+ u64 size;
+ char data[0];
+};
+
+struct dso {
+ struct list_head node;
+ struct rb_root symbols[MAP__NR_TYPES];
+ struct rb_root symbol_names[MAP__NR_TYPES];
+ struct rb_root cache;
+ enum dso_kernel_type kernel;
+ enum dso_swap_type needs_swap;
+ enum dso_binary_type symtab_type;
+ enum dso_binary_type data_type;
+ u8 adjust_symbols:1;
+ u8 has_build_id:1;
+ u8 hit:1;
+ u8 annotate_warned:1;
+ u8 sname_alloc:1;
+ u8 lname_alloc:1;
+ u8 sorted_by_name;
+ u8 loaded;
+ u8 build_id[BUILD_ID_SIZE];
+ const char *short_name;
+ char *long_name;
+ u16 long_name_len;
+ u16 short_name_len;
+ char name[0];
+};
+
+static inline void dso__set_loaded(struct dso *dso, enum map_type type)
+{
+ dso->loaded |= (1 << type);
+}
+
+struct dso *dso__new(const char *name);
+void dso__delete(struct dso *dso);
+
+void dso__set_short_name(struct dso *dso, const char *name);
+void dso__set_long_name(struct dso *dso, char *name);
+
+int dso__name_len(const struct dso *dso);
+
+bool dso__loaded(const struct dso *dso, enum map_type type);
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type);
+void dso__sort_by_name(struct dso *dso, enum map_type type);
+
+void dso__set_build_id(struct dso *dso, void *build_id);
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
+void dso__read_running_kernel_build_id(struct dso *dso,
+ struct machine *machine);
+int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
+
+char dso__symtab_origin(const struct dso *dso);
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size);
+
+int dso__data_fd(struct dso *dso, struct machine *machine);
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size);
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size);
+
+struct map *dso__new_map(const char *name);
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type);
+
+void dsos__add(struct list_head *head, struct dso *dso);
+struct dso *dsos__find(struct list_head *head, const char *name);
+struct dso *__dsos__findnew(struct list_head *head, const char *name);
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits);
+size_t __dsos__fprintf(struct list_head *head, FILE *fp);
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
+size_t dso__fprintf_symbols_by_name(struct dso *dso,
+ enum map_type type, FILE *fp);
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
+#endif /* __PERF_DSO */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index d3b1ecc..624c65e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -23,7 +23,6 @@
#define KSYM_NAME_LEN 256
#endif

-static void dso_cache__free(struct rb_root *root);
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
symbol_filter_t filter);
static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
@@ -56,39 +55,6 @@ static enum dso_binary_type binary_type_symtab[] = {

#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)

-static enum dso_binary_type binary_type_data[] = {
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
-
-int dso__name_len(const struct dso *dso)
-{
- if (!dso)
- return strlen("[unknown]");
- if (verbose)
- return dso->long_name_len;
-
- return dso->short_name_len;
-}
-
-bool dso__loaded(const struct dso *dso, enum map_type type)
-{
- return dso->loaded & (1 << type);
-}
-
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
-{
- return dso->sorted_by_name & (1 << type);
-}
-
-static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
-{
- dso->sorted_by_name |= (1 << type);
-}
-
bool symbol_type__is_a(char symbol_type, enum map_type map_type)
{
symbol_type = toupper(symbol_type);
@@ -270,7 +236,7 @@ void symbol__delete(struct symbol *sym)
free(((void *)sym) - symbol_conf.priv_size);
}

-static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
+size_t symbol__fprintf(struct symbol *sym, FILE *fp)
{
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
sym->start, sym->end,
@@ -301,53 +267,7 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
return symbol__fprintf_symname_offs(sym, NULL, fp);
}

-void dso__set_long_name(struct dso *dso, char *name)
-{
- if (name == NULL)
- return;
- dso->long_name = name;
- dso->long_name_len = strlen(name);
-}
-
-static void dso__set_short_name(struct dso *dso, const char *name)
-{
- if (name == NULL)
- return;
- dso->short_name = name;
- dso->short_name_len = strlen(name);
-}
-
-static void dso__set_basename(struct dso *dso)
-{
- dso__set_short_name(dso, basename(dso->long_name));
-}
-
-struct dso *dso__new(const char *name)
-{
- struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
-
- if (dso != NULL) {
- int i;
- strcpy(dso->name, name);
- dso__set_long_name(dso, dso->name);
- dso__set_short_name(dso, dso->name);
- for (i = 0; i < MAP__NR_TYPES; ++i)
- dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
- dso->cache = RB_ROOT;
- dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->loaded = 0;
- dso->sorted_by_name = 0;
- dso->has_build_id = 0;
- dso->kernel = DSO_TYPE_USER;
- dso->needs_swap = DSO_SWAP__UNSET;
- INIT_LIST_HEAD(&dso->node);
- }
-
- return dso;
-}
-
-static void symbols__delete(struct rb_root *symbols)
+void symbols__delete(struct rb_root *symbols)
{
struct symbol *pos;
struct rb_node *next = rb_first(symbols);
@@ -360,25 +280,6 @@ static void symbols__delete(struct rb_root *symbols)
}
}

-void dso__delete(struct dso *dso)
-{
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- symbols__delete(&dso->symbols[i]);
- if (dso->sname_alloc)
- free((char *)dso->short_name);
- if (dso->lname_alloc)
- free(dso->long_name);
- dso_cache__free(&dso->cache);
- free(dso);
-}
-
-void dso__set_build_id(struct dso *dso, void *build_id)
-{
- memcpy(dso->build_id, build_id, sizeof(dso->build_id));
- dso->has_build_id = 1;
-}
-
void symbols__insert(struct rb_root *symbols, struct symbol *sym)
{
struct rb_node **p = &symbols->rb_node;
@@ -504,14 +405,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
&dso->symbols[type]);
}

-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
-{
- char sbuild_id[BUILD_ID_SIZE * 2 + 1];
-
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
- return fprintf(fp, "%s", sbuild_id);
-}
-
size_t dso__fprintf_symbols_by_name(struct dso *dso,
enum map_type type, FILE *fp)
{
@@ -527,25 +420,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
return ret;
}

-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
-{
- struct rb_node *nd;
- size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
-
- if (dso->short_name != dso->long_name)
- ret += fprintf(fp, "%s, ", dso->long_name);
- ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
- dso->loaded ? "" : "NOT ");
- ret += dso__fprintf_buildid(dso, fp);
- ret += fprintf(fp, ")\n");
- for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
- struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
- ret += symbol__fprintf(pos, fp);
- }
-
- return ret;
-}
-
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start))
@@ -877,136 +751,6 @@ out_failure:
return -1;
}

-bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
-{
- return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
-}
-
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
-{
- bool have_build_id = false;
- struct dso *pos;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- if (pos->has_build_id) {
- have_build_id = true;
- continue;
- }
- if (filename__read_build_id(pos->long_name, pos->build_id,
- sizeof(pos->build_id)) > 0) {
- have_build_id = true;
- pos->has_build_id = true;
- }
- }
-
- return have_build_id;
-}
-
-char dso__symtab_origin(const struct dso *dso)
-{
- static const char origin[] = {
- [DSO_BINARY_TYPE__KALLSYMS] = 'k',
- [DSO_BINARY_TYPE__VMLINUX] = 'v',
- [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
- [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
- [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
- [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
- [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
- [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
- [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
- [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
- [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
- [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
- [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
- };
-
- if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
- return '!';
- return origin[dso->symtab_type];
-}
-
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size)
-{
- char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- int ret = 0;
-
- switch (type) {
- case DSO_BINARY_TYPE__DEBUGLINK: {
- char *debuglink;
-
- strncpy(file, dso->long_name, size);
- debuglink = file + dso->long_name_len;
- while (debuglink != file && *debuglink != '/')
- debuglink--;
- if (*debuglink == '/')
- debuglink++;
- filename__read_debuglink(dso->long_name, debuglink,
- size - (debuglink - file));
- }
- break;
- case DSO_BINARY_TYPE__BUILD_ID_CACHE:
- /* skip the locally configured cache if a symfs is given */
- if (symbol_conf.symfs[0] ||
- (dso__build_id_filename(dso, file, size) == NULL))
- ret = -1;
- break;
-
- case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s.debug",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
- if (!dso->has_build_id) {
- ret = -1;
- break;
- }
-
- build_id__sprintf(dso->build_id,
- sizeof(dso->build_id),
- build_id_hex);
- snprintf(file, size,
- "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
- symbol_conf.symfs, build_id_hex, build_id_hex + 2);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
- snprintf(file, size, "%s%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__GUEST_KMODULE:
- snprintf(file, size, "%s%s%s", symbol_conf.symfs,
- root_dir, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
- snprintf(file, size, "%s%s", symbol_conf.symfs,
- dso->long_name);
- break;
-
- default:
- case DSO_BINARY_TYPE__KALLSYMS:
- case DSO_BINARY_TYPE__VMLINUX:
- case DSO_BINARY_TYPE__GUEST_KALLSYMS:
- case DSO_BINARY_TYPE__GUEST_VMLINUX:
- case DSO_BINARY_TYPE__JAVA_JIT:
- case DSO_BINARY_TYPE__NOT_FOUND:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
{
char *name;
@@ -1142,27 +886,6 @@ struct map *map_groups__find_by_name(struct map_groups *mg,
return NULL;
}

-static int dso__kernel_module_get_build_id(struct dso *dso,
- const char *root_dir)
-{
- char filename[PATH_MAX];
- /*
- * kernel module short names are of the form "[module]" and
- * we need just "module" here.
- */
- const char *name = dso->short_name + 1;
-
- snprintf(filename, sizeof(filename),
- "%s/sys/module/%.*s/notes/.note.gnu.build-id",
- root_dir, (int)strlen(name) - 1, name);
-
- if (sysfs__read_build_id(filename, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-
- return 0;
-}
-
static int map_groups__set_modules_path_dir(struct map_groups *mg,
const char *dir_name)
{
@@ -1576,50 +1299,6 @@ out_try_fixup:
return err;
}

-void dsos__add(struct list_head *head, struct dso *dso)
-{
- list_add_tail(&dso->node, head);
-}
-
-struct dso *dsos__find(struct list_head *head, const char *name)
-{
- struct dso *pos;
-
- list_for_each_entry(pos, head, node)
- if (strcmp(pos->long_name, name) == 0)
- return pos;
- return NULL;
-}
-
-struct dso *__dsos__findnew(struct list_head *head, const char *name)
-{
- struct dso *dso = dsos__find(head, name);
-
- if (!dso) {
- dso = dso__new(name);
- if (dso != NULL) {
- dsos__add(head, dso);
- dso__set_basename(dso);
- }
- }
-
- return dso;
-}
-
-size_t __dsos__fprintf(struct list_head *head, FILE *fp)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- ret += dso__fprintf(pos, i, fp);
- }
-
- return ret;
-}
-
size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
{
struct rb_node *nd;
@@ -1634,21 +1313,6 @@ size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
return ret;
}

-static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
- bool with_hits)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- ret += dso__fprintf_buildid(pos, fp);
- ret += fprintf(fp, " %s\n", pos->long_name);
- }
- return ret;
-}
-
size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
bool with_hits)
{
@@ -1669,39 +1333,6 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
return ret;
}

-static struct dso*
-dso__kernel_findnew(struct machine *machine, const char *name,
- const char *short_name, int dso_type)
-{
- /*
- * The kernel dso could be created by build_id processing.
- */
- struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
-
- /*
- * We need to run this in all cases, since during the build_id
- * processing we had no idea this was the kernel dso.
- */
- if (dso != NULL) {
- dso__set_short_name(dso, short_name);
- dso->kernel = dso_type;
- }
-
- return dso;
-}
-
-void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
-{
- char path[PATH_MAX];
-
- if (machine__is_default_guest(machine))
- return;
- sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
- if (sysfs__read_build_id(path, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-}
-
static struct dso *machine__get_kernel(struct machine *machine)
{
const char *vmlinux_name = NULL;
@@ -2144,229 +1775,3 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,

return ret;
}
-
-struct map *dso__new_map(const char *name)
-{
- struct map *map = NULL;
- struct dso *dso = dso__new(name);
-
- if (dso)
- map = map__new2(0, dso, MAP__FUNCTION);
-
- return map;
-}
-
-static int open_dso(struct dso *dso, struct machine *machine)
-{
- char *root_dir = (char *) "";
- char *name;
- int fd;
-
- name = malloc(PATH_MAX);
- if (!name)
- return -ENOMEM;
-
- if (machine)
- root_dir = machine->root_dir;
-
- if (dso__binary_type_file(dso, dso->data_type,
- root_dir, name, PATH_MAX)) {
- free(name);
- return -EINVAL;
- }
-
- fd = open(name, O_RDONLY);
- free(name);
- return fd;
-}
-
-int dso__data_fd(struct dso *dso, struct machine *machine)
-{
- int i = 0;
-
- if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
- return open_dso(dso, machine);
-
- do {
- int fd;
-
- dso->data_type = binary_type_data[i++];
-
- fd = open_dso(dso, machine);
- if (fd >= 0)
- return fd;
-
- } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
-
- return -EINVAL;
-}
-
-static void
-dso_cache__free(struct rb_root *root)
-{
- struct rb_node *next = rb_first(root);
-
- while (next) {
- struct dso_cache *cache;
-
- cache = rb_entry(next, struct dso_cache, rb_node);
- next = rb_next(&cache->rb_node);
- rb_erase(&cache->rb_node, root);
- free(cache);
- }
-}
-
-static struct dso_cache*
-dso_cache__find(struct rb_root *root, u64 offset)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- else
- return cache;
- }
- return NULL;
-}
-
-static void
-dso_cache__insert(struct rb_root *root, struct dso_cache *new)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
- u64 offset = new->offset;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&new->rb_node, parent, p);
- rb_insert_color(&new->rb_node, root);
-}
-
-static ssize_t
-dso_cache__memcpy(struct dso_cache *cache, u64 offset,
- u8 *data, u64 size)
-{
- u64 cache_offset = offset - cache->offset;
- u64 cache_size = min(cache->size - cache_offset, size);
-
- memcpy(data, cache->data + cache_offset, cache_size);
- return cache_size;
-}
-
-static ssize_t
-dso_cache__read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
- ssize_t ret;
- int fd;
-
- fd = dso__data_fd(dso, machine);
- if (fd < 0)
- return -1;
-
- do {
- u64 cache_offset;
-
- ret = -ENOMEM;
-
- cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
- if (!cache)
- break;
-
- cache_offset = offset & DSO__DATA_CACHE_MASK;
- ret = -EINVAL;
-
- if (-1 == lseek(fd, cache_offset, SEEK_SET))
- break;
-
- ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
- if (ret <= 0)
- break;
-
- cache->offset = cache_offset;
- cache->size = ret;
- dso_cache__insert(&dso->cache, cache);
-
- ret = dso_cache__memcpy(cache, offset, data, size);
-
- } while (0);
-
- if (ret <= 0)
- free(cache);
-
- close(fd);
- return ret;
-}
-
-static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
-
- cache = dso_cache__find(&dso->cache, offset);
- if (cache)
- return dso_cache__memcpy(cache, offset, data, size);
- else
- return dso_cache__read(dso, machine, offset, data, size);
-}
-
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- ssize_t r = 0;
- u8 *p = data;
-
- do {
- ssize_t ret;
-
- ret = dso_cache_read(dso, machine, offset, p, size);
- if (ret < 0)
- return ret;
-
- /* Reached EOF, return what we have. */
- if (!ret)
- break;
-
- BUG_ON(ret > size);
-
- r += ret;
- p += ret;
- offset += ret;
- size -= ret;
-
- } while (size);
-
- return r;
-}
-
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size)
-{
- u64 offset = map->map_ip(map, addr);
- return dso__data_read_offset(dso, machine, offset, data, size);
-}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 45d3df8..863b05b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -19,6 +19,8 @@
#include <elf.h>
#endif

+#include "dso.h"
+
#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);

@@ -70,6 +72,7 @@ struct symbol {
};

void symbol__delete(struct symbol *sym);
+void symbols__delete(struct rb_root *symbols);

static inline size_t symbol__size(const struct symbol *sym)
{
@@ -160,70 +163,6 @@ struct addr_location {
s32 cpu;
};

-enum dso_binary_type {
- DSO_BINARY_TYPE__KALLSYMS = 0,
- DSO_BINARY_TYPE__GUEST_KALLSYMS,
- DSO_BINARY_TYPE__VMLINUX,
- DSO_BINARY_TYPE__GUEST_VMLINUX,
- DSO_BINARY_TYPE__JAVA_JIT,
- DSO_BINARY_TYPE__DEBUGLINK,
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
- DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
- DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__GUEST_KMODULE,
- DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-enum dso_kernel_type {
- DSO_TYPE_USER = 0,
- DSO_TYPE_KERNEL,
- DSO_TYPE_GUEST_KERNEL
-};
-
-enum dso_swap_type {
- DSO_SWAP__UNSET,
- DSO_SWAP__NO,
- DSO_SWAP__YES,
-};
-
-#define DSO__DATA_CACHE_SIZE 4096
-#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
-
-struct dso_cache {
- struct rb_node rb_node;
- u64 offset;
- u64 size;
- char data[0];
-};
-
-struct dso {
- struct list_head node;
- struct rb_root symbols[MAP__NR_TYPES];
- struct rb_root symbol_names[MAP__NR_TYPES];
- struct rb_root cache;
- enum dso_kernel_type kernel;
- enum dso_swap_type needs_swap;
- enum dso_binary_type symtab_type;
- enum dso_binary_type data_type;
- u8 adjust_symbols:1;
- u8 has_build_id:1;
- u8 hit:1;
- u8 annotate_warned:1;
- u8 sname_alloc:1;
- u8 lname_alloc:1;
- u8 sorted_by_name;
- u8 loaded;
- u8 build_id[BUILD_ID_SIZE];
- const char *short_name;
- char *long_name;
- u16 long_name_len;
- u16 short_name_len;
- char name[0];
-};
-
struct symsrc {
char *name;
int fd;
@@ -254,47 +193,6 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
bool symsrc__has_symtab(struct symsrc *ss);
bool symsrc__possibly_runtime(struct symsrc *ss);

-#define DSO__SWAP(dso, type, val) \
-({ \
- type ____r = val; \
- BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
- if (dso->needs_swap == DSO_SWAP__YES) { \
- switch (sizeof(____r)) { \
- case 2: \
- ____r = bswap_16(val); \
- break; \
- case 4: \
- ____r = bswap_32(val); \
- break; \
- case 8: \
- ____r = bswap_64(val); \
- break; \
- default: \
- BUG_ON(1); \
- } \
- } \
- ____r; \
-})
-
-struct dso *dso__new(const char *name);
-void dso__delete(struct dso *dso);
-
-int dso__name_len(const struct dso *dso);
-
-bool dso__loaded(const struct dso *dso, enum map_type type);
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
-
-static inline void dso__set_loaded(struct dso *dso, enum map_type type)
-{
- dso->loaded |= (1 << type);
-}
-
-void dso__sort_by_name(struct dso *dso, enum map_type type);
-
-void dsos__add(struct list_head *head, struct dso *dso);
-struct dso *dsos__find(struct list_head *head, const char *name);
-struct dso *__dsos__findnew(struct list_head *head, const char *name);
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
int dso__load_vmlinux(struct dso *dso, struct map *map,
const char *vmlinux, symbol_filter_t filter);
@@ -307,25 +205,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename,
int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
symbol_filter_t filter);

-size_t __dsos__fprintf(struct list_head *head, FILE *fp);
-
size_t machine__fprintf_dsos_buildid(struct machine *machine,
FILE *fp, bool with_hits);
size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
FILE *fp, bool with_hits);
-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
-size_t dso__fprintf_symbols_by_name(struct dso *dso,
- enum map_type type, FILE *fp);
-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
-
-char dso__symtab_origin(const struct dso *dso);
-void dso__set_long_name(struct dso *dso, char *name);
-void dso__set_build_id(struct dso *dso, void *build_id);
-bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
-void dso__read_running_kernel_build_id(struct dso *dso,
- struct machine *machine);
-struct map *dso__new_map(const char *name);
+
struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
u64 addr);
struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
@@ -333,7 +218,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,

int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
@@ -355,19 +239,11 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
size_t symbol__fprintf_symname_offs(const struct symbol *sym,
const struct addr_location *al, FILE *fp);
size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
+size_t symbol__fprintf(struct symbol *sym, FILE *fp);
bool symbol_type__is_a(char symbol_type, enum map_type map_type);

size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);

-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size);
-
-int dso__data_fd(struct dso *dso, struct machine *machine);
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size);
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size);
int dso__test_data(void);
int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
struct symsrc *runtime_ss, symbol_filter_t filter,
--
1.7.11.7

2012-10-27 21:18:55

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 1/5] perf tool: Move build_id__sprintf into build-id object

Moving build_id__sprintf function into build-id object.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-buildid-cache.c | 2 +-
tools/perf/util/build-id.c | 15 +++++++++++++++
tools/perf/util/build-id.h | 1 +
tools/perf/util/header.c | 1 +
tools/perf/util/map.c | 1 +
tools/perf/util/symbol.c | 15 ---------------
tools/perf/util/symbol.h | 1 -
7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index d37e077..edb26ea 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -13,7 +13,7 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/strlist.h"
-#include "util/symbol.h"
+#include "util/build-id.h"

static int build_id_cache__add_file(const char *filename, const char *debugdir)
{
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 94ca117..5295625 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -70,6 +70,21 @@ struct perf_tool build_id__mark_dso_hit_ops = {
.build_id = perf_event__process_build_id,
};

+int build_id__sprintf(const u8 *build_id, int len, char *bf)
+{
+ char *bid = bf;
+ const u8 *raw = build_id;
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ sprintf(bid, "%02x", *raw);
+ ++raw;
+ bid += 2;
+ }
+
+ return raw - build_id;
+}
+
char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 45c500b..f6d9ff9 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -5,6 +5,7 @@

extern struct perf_tool build_id__mark_dso_hit_ops;

+int build_id__sprintf(const u8 *build_id, int len, char *bf);
char *dso__build_id_filename(struct dso *self, char *bf, size_t size);

int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7daad23..514ed1b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -23,6 +23,7 @@
#include "pmu.h"
#include "vdso.h"
#include "strbuf.h"
+#include "build-id.h"

static bool no_buildid_cache = false;

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 6109fa4..9b40c44 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -10,6 +10,7 @@
#include "thread.h"
#include "strlist.h"
#include "vdso.h"
+#include "build-id.h"

const char *map_type__name[MAP__NR_TYPES] = {
[MAP__FUNCTION] = "Functions",
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e2e8c69..e36e8c2 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -504,21 +504,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
&dso->symbols[type]);
}

-int build_id__sprintf(const u8 *build_id, int len, char *bf)
-{
- char *bid = bf;
- const u8 *raw = build_id;
- int i;
-
- for (i = 0; i < len; ++i) {
- sprintf(bid, "%02x", *raw);
- ++raw;
- bid += 2;
- }
-
- return raw - build_id;
-}
-
size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
{
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 8b6ef7f..d70f676 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -338,7 +338,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
-int build_id__sprintf(const u8 *build_id, int len, char *bf);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
--
1.7.11.7

2012-10-27 21:18:54

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 3/5] perf tool: Move hex2u64 into util object

Moving hex2u64 function into util object.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/symbol.c | 33 ---------------------------------
tools/perf/util/symbol.h | 1 -
tools/perf/util/util.c | 33 +++++++++++++++++++++++++++++++++
tools/perf/util/util.h | 1 +
4 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e36e8c2..08b8257 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2050,39 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
return machine__create_kernel_maps(machine);
}

-static int hex(char ch)
-{
- if ((ch >= '0') && (ch <= '9'))
- return ch - '0';
- if ((ch >= 'a') && (ch <= 'f'))
- return ch - 'a' + 10;
- if ((ch >= 'A') && (ch <= 'F'))
- return ch - 'A' + 10;
- return -1;
-}
-
-/*
- * While we find nice hex chars, build a long_val.
- * Return number of chars processed.
- */
-int hex2u64(const char *ptr, u64 *long_val)
-{
- const char *p = ptr;
- *long_val = 0;
-
- while (*p) {
- const int hex_val = hex(*p);
-
- if (hex_val < 0)
- break;
-
- *long_val = (*long_val << 4) | hex_val;
- p++;
- }
-
- return p - ptr;
-}
-
char *strxfrchar(char *s, char from, char to)
{
char *p = s;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6eb7d3b..bc34dc1 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -40,7 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v,
#endif
#endif

-int hex2u64(const char *ptr, u64 *val);
char *strxfrchar(char *s, char from, char to);

/*
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 637b5cc..5906e84 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -166,6 +166,39 @@ size_t hex_width(u64 v)
return n;
}

+static int hex(char ch)
+{
+ if ((ch >= '0') && (ch <= '9'))
+ return ch - '0';
+ if ((ch >= 'a') && (ch <= 'f'))
+ return ch - 'a' + 10;
+ if ((ch >= 'A') && (ch <= 'F'))
+ return ch - 'A' + 10;
+ return -1;
+}
+
+/*
+ * While we find nice hex chars, build a long_val.
+ * Return number of chars processed.
+ */
+int hex2u64(const char *ptr, u64 *long_val)
+{
+ const char *p = ptr;
+ *long_val = 0;
+
+ while (*p) {
+ const int hex_val = hex(*p);
+
+ if (hex_val < 0)
+ break;
+
+ *long_val = (*long_val << 4) | hex_val;
+ p++;
+ }
+
+ return p - ptr;
+}
+
/* Obtain a backtrace and print it to stdout. */
#ifdef BACKTRACE_SUPPORT
void dump_stack(void)
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 0d85209..d6c22c5 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -262,6 +262,7 @@ bool is_power_of_2(unsigned long n)
}

size_t hex_width(u64 v);
+int hex2u64(const char *ptr, u64 *val);

char *rtrim(char *s);

--
1.7.11.7

2012-10-27 21:20:17

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 4/5] perf tool: Move strxfrchar into string object

Moving strxfrchar function into string object.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/string.c | 18 ++++++++++++++++++
tools/perf/util/symbol.c | 10 ----------
tools/perf/util/symbol.h | 2 --
tools/perf/util/util.h | 1 +
4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 3217059..346707d 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -314,6 +314,24 @@ int strtailcmp(const char *s1, const char *s2)
}

/**
+ * strxfrchar - Locate and replace character in @s
+ * @s: The string to be searched/changed.
+ * @from: Source character to be replaced.
+ * @to: Destination character.
+ *
+ * Return pointer to the changed string.
+ */
+char *strxfrchar(char *s, char from, char to)
+{
+ char *p = s;
+
+ while ((p = strchr(p, from)) != NULL)
+ *p++ = to;
+
+ return s;
+}
+
+/**
* rtrim - Removes trailing whitespace from @s.
* @s: The string to be stripped.
*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 08b8257..d3b1ecc 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2050,16 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
return machine__create_kernel_maps(machine);
}

-char *strxfrchar(char *s, char from, char to)
-{
- char *p = s;
-
- while ((p = strchr(p, from)) != NULL)
- *p++ = to;
-
- return s;
-}
-
int machines__create_guest_kernel_maps(struct rb_root *machines)
{
int ret = 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bc34dc1..45d3df8 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -40,8 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v,
#endif
#endif

-char *strxfrchar(char *s, char from, char to);
-
/*
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index d6c22c5..c233091 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -240,6 +240,7 @@ void argv_free(char **argv);
bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
int strtailcmp(const char *s1, const char *s2);
+char *strxfrchar(char *s, char from, char to);
unsigned long convert_unit(unsigned long value, char *unit);
int readn(int fd, void *buf, size_t size);

--
1.7.11.7

2012-10-28 13:37:26

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 5/5] perf tool: Move dso_* related functions into dso object

Em Sat, Oct 27, 2012 at 11:18:32PM +0200, Jiri Olsa escreveu:
> Moving dso_* related functions into dso object.
>
> Keeping symbol loading related functions still in the symbol
> object as it seems more convenient.

Please resubmit after you fix this: The other 4 patches I already applied to my local tree.

- Arnaldo

CC /home/acme/git/build/perf/util/dso-test-data.o
In file included from util/dso.c:2:
util/dso.h:87: error: ‘BUILD_ID_SIZE’ undeclared here (not in a function)
CC /home/acme/git/build/perf/util/color.o
cc1: warnings being treated as errors
util/dso.c: In function ‘dso__binary_type_file’:
util/dso.c:45: error: implicit declaration of function ‘filename__read_debuglink’
util/dso.c:45: error: nested extern declaration of ‘filename__read_debuglink’
util/dso.c:51: error: ‘symbol_conf’ undeclared (first use in this function)
util/dso.c:51: error: (Each undeclared identifier is reported only once
util/dso.c:51: error: for each function it appears in.)
util/dso.c: In function ‘dso__delete’:
util/dso.c:435: error: implicit declaration of function ‘symbols__delete’
util/dso.c:435: error: nested extern declaration of ‘symbols__delete’
util/dso.c: In function ‘dso__read_running_kernel_build_id’:
util/dso.c:462: error: implicit declaration of function ‘sysfs__read_build_id’
util/dso.c:462: error: nested extern declaration of ‘sysfs__read_build_id’
util/dso.c: In function ‘__dsos__read_build_ids’:
util/dso.c:500: error: implicit declaration of function ‘filename__read_build_id’
util/dso.c:500: error: nested extern declaration of ‘filename__read_build_id’
util/dso.c: In function ‘dso__fprintf’:
util/dso.c:589: error: dereferencing pointer to incomplete type
util/dso.c:589: error: type defaults to ‘int’ in declaration of ‘__mptr’
util/dso.c:589: error: initialization from incompatible pointer type
util/dso.c:589: error: invalid use of undefined type ‘struct symbol’
util/dso.c:590: error: implicit declaration of function ‘symbol__fprintf’
util/dso.c:590: error: nested extern declaration of ‘symbol__fprintf’
make: *** [/home/acme/git/build/perf/util/dso.o] Error 1
make: *** Waiting for unfinished jobs....
make: Leaving directory `/home/git/linux/tools/perf'
[acme@sandy linux]$

2012-10-28 18:42:27

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 5/5] perf tool: Move dso_* related functions into dso object

On Sun, Oct 28, 2012 at 11:37:02AM -0200, Arnaldo Carvalho de Melo wrote:
> Em Sat, Oct 27, 2012 at 11:18:32PM +0200, Jiri Olsa escreveu:
> > Moving dso_* related functions into dso object.
> >
> > Keeping symbol loading related functions still in the symbol
> > object as it seems more convenient.
>
> Please resubmit after you fix this: The other 4 patches I already applied to my local tree.
>
> - Arnaldo
>
> CC /home/acme/git/build/perf/util/dso-test-data.o
> In file included from util/dso.c:2:
> util/dso.h:87: error: ‘BUILD_ID_SIZE’ undeclared here (not in a function)
> CC /home/acme/git/build/perf/util/color.o
> cc1: warnings being treated as errors
> util/dso.c: In function ‘dso__binary_type_file’:
> util/dso.c:45: error: implicit declaration of function ‘filename__read_debuglink’
> util/dso.c:45: error: nested extern declaration of ‘filename__read_debuglink’
> util/dso.c:51: error: ‘symbol_conf’ undeclared (first use in this function)
> util/dso.c:51: error: (Each undeclared identifier is reported only once
> util/dso.c:51: error: for each function it appears in.)
> util/dso.c: In function ‘dso__delete’:
> util/dso.c:435: error: implicit declaration of function ‘symbols__delete’
> util/dso.c:435: error: nested extern declaration of ‘symbols__delete’
> util/dso.c: In function ‘dso__read_running_kernel_build_id’:
> util/dso.c:462: error: implicit declaration of function ‘sysfs__read_build_id’
> util/dso.c:462: error: nested extern declaration of ‘sysfs__read_build_id’
> util/dso.c: In function ‘__dsos__read_build_ids’:
> util/dso.c:500: error: implicit declaration of function ‘filename__read_build_id’
> util/dso.c:500: error: nested extern declaration of ‘filename__read_build_id’
> util/dso.c: In function ‘dso__fprintf’:
> util/dso.c:589: error: dereferencing pointer to incomplete type
> util/dso.c:589: error: type defaults to ‘int’ in declaration of ‘__mptr’
> util/dso.c:589: error: initialization from incompatible pointer type
> util/dso.c:589: error: invalid use of undefined type ‘struct symbol’
> util/dso.c:590: error: implicit declaration of function ‘symbol__fprintf’
> util/dso.c:590: error: nested extern declaration of ‘symbol__fprintf’
> make: *** [/home/acme/git/build/perf/util/dso.o] Error 1

ugh.. I have it rebased to your perf/core and it builds cleanly

Any chance there's something not pushed yet?

thanks,
jirka

2012-10-28 21:17:09

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 5/5] perf tool: Move dso_* related functions into dso object

Em Sun, Oct 28, 2012 at 07:42:01PM +0100, Jiri Olsa escreveu:
> On Sun, Oct 28, 2012 at 11:37:02AM -0200, Arnaldo Carvalho de Melo wrote:
> > CC /home/acme/git/build/perf/util/dso-test-data.o
> > In file included from util/dso.c:2:
> > util/dso.h:87: error: ‘BUILD_ID_SIZE’ undeclared here (not in a function)
> > CC /home/acme/git/build/perf/util/color.o
> > cc1: warnings being treated as errors
> > util/dso.c: In function ‘dso__binary_type_file’:
> > util/dso.c:45: error: implicit declaration of function ‘filename__read_debuglink’
> > util/dso.c:45: error: nested extern declaration of ‘filename__read_debuglink’
> > util/dso.c:51: error: ‘symbol_conf’ undeclared (first use in this function)
> > util/dso.c:51: error: (Each undeclared identifier is reported only once
> > util/dso.c:51: error: for each function it appears in.)
> > util/dso.c: In function ‘dso__delete’:
> > util/dso.c:435: error: implicit declaration of function ‘symbols__delete’
> > util/dso.c:435: error: nested extern declaration of ‘symbols__delete’
> > util/dso.c: In function ‘dso__read_running_kernel_build_id’:
> > util/dso.c:462: error: implicit declaration of function ‘sysfs__read_build_id’
> > util/dso.c:462: error: nested extern declaration of ‘sysfs__read_build_id’
> > util/dso.c: In function ‘__dsos__read_build_ids’:
> > util/dso.c:500: error: implicit declaration of function ‘filename__read_build_id’
> > util/dso.c:500: error: nested extern declaration of ‘filename__read_build_id’
> > util/dso.c: In function ‘dso__fprintf’:
> > util/dso.c:589: error: dereferencing pointer to incomplete type
> > util/dso.c:589: error: type defaults to ‘int’ in declaration of ‘__mptr’
> > util/dso.c:589: error: initialization from incompatible pointer type
> > util/dso.c:589: error: invalid use of undefined type ‘struct symbol’
> > util/dso.c:590: error: implicit declaration of function ‘symbol__fprintf’
> > util/dso.c:590: error: nested extern declaration of ‘symbol__fprintf’
> > make: *** [/home/acme/git/build/perf/util/dso.o] Error 1
>
> ugh.. I have it rebased to your perf/core and it builds cleanly
>
> Any chance there's something not pushed yet?

The only thing besides the four first patches in your series is one that
you acked:

commit 9175ce1f1244edd9f4d39605aa06ce5b0a50b8e0
Author: Andi Kleen <[email protected]>
Date: Fri Oct 26 13:30:06 2012 -0700

perf tools: Move parse_events error printing to parse_events_options


---------------




[acme@sandy linux]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.3 (Santiago)

- Arnaldo

2012-10-29 11:07:51

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH 0/5] perf dso: Separate dso symbols to separate object

Hi Jiri,

On Sat, 27 Oct 2012 23:18:27 +0200, Jiri Olsa wrote:
> hi,
> separating dso related stuff into dso object plus some other symbol
> object cleanup. It's just a code moving, no actual change was done.
>
> Attached patches:
> 1/5 perf tool: Move build_id__sprintf into build-id object
> 2/5 perf tool: Move BUILD_ID_SIZE into build-id object
> 3/5 perf tool: Move hex2u64 into util object
> 4/5 perf tool: Move strxfrchar into string object
> 5/5 perf tool: Move dso_* related functions into dso object

Looks good to me.

Arnaldo, if you want, you can add my Reviewed- or Tested-by tags for this
series.

Thanks,
Namhyung

2012-10-29 11:14:14

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 0/5] perf dso: Separate dso symbols to separate object

On Mon, Oct 29, 2012 at 08:07:48PM +0900, Namhyung Kim wrote:
> Hi Jiri,
>
> On Sat, 27 Oct 2012 23:18:27 +0200, Jiri Olsa wrote:
> > hi,
> > separating dso related stuff into dso object plus some other symbol
> > object cleanup. It's just a code moving, no actual change was done.
> >
> > Attached patches:
> > 1/5 perf tool: Move build_id__sprintf into build-id object
> > 2/5 perf tool: Move BUILD_ID_SIZE into build-id object
> > 3/5 perf tool: Move hex2u64 into util object
> > 4/5 perf tool: Move strxfrchar into string object
> > 5/5 perf tool: Move dso_* related functions into dso object
>
> Looks good to me.
>
> Arnaldo, if you want, you can add my Reviewed- or Tested-by tags for this
> series.

humm, so you could compile it wth no problem..? what system are you? ;)

thanks,
jirka

2012-10-29 11:20:32

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH 0/5] perf dso: Separate dso symbols to separate object

On Mon, 29 Oct 2012 12:13:28 +0100, Jiri Olsa wrote:
> On Mon, Oct 29, 2012 at 08:07:48PM +0900, Namhyung Kim wrote:
>> Hi Jiri,
>>
>> On Sat, 27 Oct 2012 23:18:27 +0200, Jiri Olsa wrote:
>> > hi,
>> > separating dso related stuff into dso object plus some other symbol
>> > object cleanup. It's just a code moving, no actual change was done.
>> >
>> > Attached patches:
>> > 1/5 perf tool: Move build_id__sprintf into build-id object
>> > 2/5 perf tool: Move BUILD_ID_SIZE into build-id object
>> > 3/5 perf tool: Move hex2u64 into util object
>> > 4/5 perf tool: Move strxfrchar into string object
>> > 5/5 perf tool: Move dso_* related functions into dso object
>>
>> Looks good to me.
>>
>> Arnaldo, if you want, you can add my Reviewed- or Tested-by tags for this
>> series.
>
> humm, so you could compile it wth no problem..? what system are you? ;)

I just compiled your branch. :)

I'll check it again if you send out the v2.

Thanks,
Namhyung

2012-10-29 13:34:47

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 0/5] perf dso: Separate dso symbols to separate object

Em Mon, Oct 29, 2012 at 12:13:28PM +0100, Jiri Olsa escreveu:
> On Mon, Oct 29, 2012 at 08:07:48PM +0900, Namhyung Kim wrote:
> > On Sat, 27 Oct 2012 23:18:27 +0200, Jiri Olsa wrote:

> > > separating dso related stuff into dso object plus some other symbol
> > > object cleanup. It's just a code moving, no actual change was done.

> > Looks good to me.

> > Arnaldo, if you want, you can add my Reviewed- or Tested-by tags for this
> > series.

> humm, so you could compile it wth no problem..? what system are you? ;)

util/dso.c:1:20: error: symbol.h: No such file or directory

[acme@sandy linux]$ head -4 tools/perf/util/dso.c
#include <symbol.h>
#include "dso.h"
#include "util.h"
#include "debug.h"
[acme@sandy linux]$

If I use "symbol.h" it builds, I've fixed this one here, thanks.

The problem is that I use O=, building it without it works.

- ARnaldo

2012-10-30 12:01:04

by Jiri Olsa

[permalink] [raw]
Subject: [tip:perf/core] perf tools: Move build_id__sprintf into build-id object

Commit-ID: ebb296c276ca19798c3116220eb8d0b2c0975ae0
Gitweb: http://git.kernel.org/tip/ebb296c276ca19798c3116220eb8d0b2c0975ae0
Author: Jiri Olsa <[email protected]>
AuthorDate: Sat, 27 Oct 2012 23:18:28 +0200
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 29 Oct 2012 11:34:46 -0200

perf tools: Move build_id__sprintf into build-id object

Moving build_id__sprintf function into build-id object.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Namhyung Kim <[email protected]>
Tested-by: Namhyung Kim <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-buildid-cache.c | 2 +-
tools/perf/util/build-id.c | 15 +++++++++++++++
tools/perf/util/build-id.h | 1 +
tools/perf/util/header.c | 1 +
tools/perf/util/map.c | 1 +
tools/perf/util/symbol.c | 15 ---------------
tools/perf/util/symbol.h | 1 -
7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index d37e077..edb26ea 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -13,7 +13,7 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/strlist.h"
-#include "util/symbol.h"
+#include "util/build-id.h"

static int build_id_cache__add_file(const char *filename, const char *debugdir)
{
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 94ca117..5295625 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -70,6 +70,21 @@ struct perf_tool build_id__mark_dso_hit_ops = {
.build_id = perf_event__process_build_id,
};

+int build_id__sprintf(const u8 *build_id, int len, char *bf)
+{
+ char *bid = bf;
+ const u8 *raw = build_id;
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ sprintf(bid, "%02x", *raw);
+ ++raw;
+ bid += 2;
+ }
+
+ return raw - build_id;
+}
+
char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 45c500b..f6d9ff9 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -5,6 +5,7 @@

extern struct perf_tool build_id__mark_dso_hit_ops;

+int build_id__sprintf(const u8 *build_id, int len, char *bf);
char *dso__build_id_filename(struct dso *self, char *bf, size_t size);

int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7daad23..514ed1b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -23,6 +23,7 @@
#include "pmu.h"
#include "vdso.h"
#include "strbuf.h"
+#include "build-id.h"

static bool no_buildid_cache = false;

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 6109fa4..9b40c44 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -10,6 +10,7 @@
#include "thread.h"
#include "strlist.h"
#include "vdso.h"
+#include "build-id.h"

const char *map_type__name[MAP__NR_TYPES] = {
[MAP__FUNCTION] = "Functions",
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e2e8c69..e36e8c2 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -504,21 +504,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
&dso->symbols[type]);
}

-int build_id__sprintf(const u8 *build_id, int len, char *bf)
-{
- char *bid = bf;
- const u8 *raw = build_id;
- int i;
-
- for (i = 0; i < len; ++i) {
- sprintf(bid, "%02x", *raw);
- ++raw;
- bid += 2;
- }
-
- return raw - build_id;
-}
-
size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
{
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 8b6ef7f..d70f676 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -338,7 +338,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
-int build_id__sprintf(const u8 *build_id, int len, char *bf);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));

2012-10-30 12:02:13

by Jiri Olsa

[permalink] [raw]
Subject: [tip:perf/core] perf tools: Move BUILD_ID_SIZE into build-id object

Commit-ID: 4383db88a7afb2664941ef1e82d41f5aad8be2ec
Gitweb: http://git.kernel.org/tip/4383db88a7afb2664941ef1e82d41f5aad8be2ec
Author: Jiri Olsa <[email protected]>
AuthorDate: Sat, 27 Oct 2012 23:18:29 +0200
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 29 Oct 2012 11:35:32 -0200

perf tools: Move BUILD_ID_SIZE into build-id object

Moving BUILD_ID_SIZE define into build-id object, plus include related
changes.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Namhyung Kim <[email protected]>
Tested-by: Namhyung Kim <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-buildid-cache.c | 1 +
tools/perf/util/annotate.c | 1 +
tools/perf/util/build-id.h | 6 +++++-
tools/perf/util/event.h | 3 +--
tools/perf/util/symbol.h | 3 +--
5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index edb26ea..fae8b25 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -14,6 +14,7 @@
#include "util/parse-options.h"
#include "util/strlist.h"
#include "util/build-id.h"
+#include "util/symbol.h"

static int build_id_cache__add_file(const char *filename, const char *debugdir)
{
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index f0a9103..7a34dd1 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -15,6 +15,7 @@
#include "debug.h"
#include "annotate.h"
#include <pthread.h>
+#include <linux/bitops.h>

const char *disassembler_style;
const char *objdump_path;
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index f6d9ff9..a811f5c 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -1,9 +1,13 @@
#ifndef PERF_BUILD_ID_H_
#define PERF_BUILD_ID_H_ 1

-#include "session.h"
+#define BUILD_ID_SIZE 20
+
+#include "tool.h"
+#include "types.h"

extern struct perf_tool build_id__mark_dso_hit_ops;
+struct dso;

int build_id__sprintf(const u8 *build_id, int len, char *bf);
char *dso__build_id_filename(struct dso *self, char *bf, size_t size);
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index da97aff..0d573ff 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -6,6 +6,7 @@

#include "../perf.h"
#include "map.h"
+#include "build-id.h"

/*
* PERF_SAMPLE_IP | PERF_SAMPLE_TID | *
@@ -96,8 +97,6 @@ struct perf_sample {
struct stack_dump user_stack;
};

-#define BUILD_ID_SIZE 20
-
struct build_id_event {
struct perf_event_header header;
pid_t pid;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index d70f676..6eb7d3b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <byteswap.h>
#include <libgen.h>
+#include "build-id.h"

#ifdef LIBELF_SUPPORT
#include <libelf.h>
@@ -57,8 +58,6 @@ char *strxfrchar(char *s, char from, char to);
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#endif

-#define BUILD_ID_SIZE 20
-
/** struct symbol - symtab entry
*
* @ignore - resolvable but tools ignore it (e.g. idle routines)

2012-10-30 12:02:33

by Jiri Olsa

[permalink] [raw]
Subject: [tip:perf/core] perf tools: Move hex2u64 into util object

Commit-ID: b2aff5f615793fa4c1313d82635b83cd7de8d9fd
Gitweb: http://git.kernel.org/tip/b2aff5f615793fa4c1313d82635b83cd7de8d9fd
Author: Jiri Olsa <[email protected]>
AuthorDate: Sat, 27 Oct 2012 23:18:30 +0200
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 29 Oct 2012 11:36:02 -0200

perf tools: Move hex2u64 into util object

Moving hex2u64 function into util object.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Namhyung Kim <[email protected]>
Tested-by: Namhyung Kim <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/symbol.c | 33 ---------------------------------
tools/perf/util/symbol.h | 1 -
tools/perf/util/util.c | 33 +++++++++++++++++++++++++++++++++
tools/perf/util/util.h | 1 +
4 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e36e8c2..08b8257 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2050,39 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
return machine__create_kernel_maps(machine);
}

-static int hex(char ch)
-{
- if ((ch >= '0') && (ch <= '9'))
- return ch - '0';
- if ((ch >= 'a') && (ch <= 'f'))
- return ch - 'a' + 10;
- if ((ch >= 'A') && (ch <= 'F'))
- return ch - 'A' + 10;
- return -1;
-}
-
-/*
- * While we find nice hex chars, build a long_val.
- * Return number of chars processed.
- */
-int hex2u64(const char *ptr, u64 *long_val)
-{
- const char *p = ptr;
- *long_val = 0;
-
- while (*p) {
- const int hex_val = hex(*p);
-
- if (hex_val < 0)
- break;
-
- *long_val = (*long_val << 4) | hex_val;
- p++;
- }
-
- return p - ptr;
-}
-
char *strxfrchar(char *s, char from, char to)
{
char *p = s;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6eb7d3b..bc34dc1 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -40,7 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v,
#endif
#endif

-int hex2u64(const char *ptr, u64 *val);
char *strxfrchar(char *s, char from, char to);

/*
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 637b5cc..5906e84 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -166,6 +166,39 @@ size_t hex_width(u64 v)
return n;
}

+static int hex(char ch)
+{
+ if ((ch >= '0') && (ch <= '9'))
+ return ch - '0';
+ if ((ch >= 'a') && (ch <= 'f'))
+ return ch - 'a' + 10;
+ if ((ch >= 'A') && (ch <= 'F'))
+ return ch - 'A' + 10;
+ return -1;
+}
+
+/*
+ * While we find nice hex chars, build a long_val.
+ * Return number of chars processed.
+ */
+int hex2u64(const char *ptr, u64 *long_val)
+{
+ const char *p = ptr;
+ *long_val = 0;
+
+ while (*p) {
+ const int hex_val = hex(*p);
+
+ if (hex_val < 0)
+ break;
+
+ *long_val = (*long_val << 4) | hex_val;
+ p++;
+ }
+
+ return p - ptr;
+}
+
/* Obtain a backtrace and print it to stdout. */
#ifdef BACKTRACE_SUPPORT
void dump_stack(void)
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 0d85209..d6c22c5 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -262,6 +262,7 @@ bool is_power_of_2(unsigned long n)
}

size_t hex_width(u64 v);
+int hex2u64(const char *ptr, u64 *val);

char *rtrim(char *s);

2012-10-30 12:03:29

by Jiri Olsa

[permalink] [raw]
Subject: [tip:perf/core] perf tools: Move strxfrchar into string object

Commit-ID: ea36c46be69c6e49c877971c4b3b3876b24b6082
Gitweb: http://git.kernel.org/tip/ea36c46be69c6e49c877971c4b3b3876b24b6082
Author: Jiri Olsa <[email protected]>
AuthorDate: Sat, 27 Oct 2012 23:18:31 +0200
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 29 Oct 2012 11:36:28 -0200

perf tools: Move strxfrchar into string object

Moving strxfrchar function into string object.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Namhyung Kim <[email protected]>
Tested-by: Namhyung Kim <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/string.c | 18 ++++++++++++++++++
tools/perf/util/symbol.c | 10 ----------
tools/perf/util/symbol.h | 2 --
tools/perf/util/util.h | 1 +
4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 3217059..346707d 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -314,6 +314,24 @@ int strtailcmp(const char *s1, const char *s2)
}

/**
+ * strxfrchar - Locate and replace character in @s
+ * @s: The string to be searched/changed.
+ * @from: Source character to be replaced.
+ * @to: Destination character.
+ *
+ * Return pointer to the changed string.
+ */
+char *strxfrchar(char *s, char from, char to)
+{
+ char *p = s;
+
+ while ((p = strchr(p, from)) != NULL)
+ *p++ = to;
+
+ return s;
+}
+
+/**
* rtrim - Removes trailing whitespace from @s.
* @s: The string to be stripped.
*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 08b8257..d3b1ecc 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2050,16 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
return machine__create_kernel_maps(machine);
}

-char *strxfrchar(char *s, char from, char to)
-{
- char *p = s;
-
- while ((p = strchr(p, from)) != NULL)
- *p++ = to;
-
- return s;
-}
-
int machines__create_guest_kernel_maps(struct rb_root *machines)
{
int ret = 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bc34dc1..45d3df8 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -40,8 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v,
#endif
#endif

-char *strxfrchar(char *s, char from, char to);
-
/*
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index d6c22c5..c233091 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -240,6 +240,7 @@ void argv_free(char **argv);
bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
int strtailcmp(const char *s1, const char *s2);
+char *strxfrchar(char *s, char from, char to);
unsigned long convert_unit(unsigned long value, char *unit);
int readn(int fd, void *buf, size_t size);

2012-10-30 12:05:36

by Jiri Olsa

[permalink] [raw]
Subject: [tip:perf/core] perf tools: Move dso_* related functions into dso object

Commit-ID: cdd059d731eeb466f51a404ee6cbfafb0fc7c20b
Gitweb: http://git.kernel.org/tip/cdd059d731eeb466f51a404ee6cbfafb0fc7c20b
Author: Jiri Olsa <[email protected]>
AuthorDate: Sat, 27 Oct 2012 23:18:32 +0200
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 29 Oct 2012 11:37:25 -0200

perf tools: Move dso_* related functions into dso object

Moving dso_* related functions into dso object.

Keeping symbol loading related functions still in the symbol object as
it seems more convenient.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Namhyung Kim <[email protected]>
Tested-by: Namhyung Kim <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
[ committer note: Use "symbol.h" instead of <symbol.h> to make it build with O= ]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Makefile | 2 +
tools/perf/util/dso.c | 594 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/dso.h | 148 ++++++++++++
tools/perf/util/symbol.c | 599 +---------------------------------------------
tools/perf/util/symbol.h | 134 +----------
5 files changed, 751 insertions(+), 726 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 629fc6a..ec63d53 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -327,6 +327,7 @@ LIB_H += util/svghelper.h
LIB_H += util/tool.h
LIB_H += util/run-command.h
LIB_H += util/sigchain.h
+LIB_H += util/dso.h
LIB_H += util/symbol.h
LIB_H += util/color.h
LIB_H += util/values.h
@@ -385,6 +386,7 @@ LIB_OBJS += $(OUTPUT)util/top.o
LIB_OBJS += $(OUTPUT)util/usage.o
LIB_OBJS += $(OUTPUT)util/wrapper.o
LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/dso.o
LIB_OBJS += $(OUTPUT)util/symbol.o
LIB_OBJS += $(OUTPUT)util/symbol-elf.o
LIB_OBJS += $(OUTPUT)util/dso-test-data.o
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
new file mode 100644
index 0000000..db24a3f
--- /dev/null
+++ b/tools/perf/util/dso.c
@@ -0,0 +1,594 @@
+#include "symbol.h"
+#include "dso.h"
+#include "util.h"
+#include "debug.h"
+
+char dso__symtab_origin(const struct dso *dso)
+{
+ static const char origin[] = {
+ [DSO_BINARY_TYPE__KALLSYMS] = 'k',
+ [DSO_BINARY_TYPE__VMLINUX] = 'v',
+ [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
+ [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
+ [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
+ [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
+ [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
+ [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
+ [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
+ [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
+ [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
+ };
+
+ if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
+ return '!';
+ return origin[dso->symtab_type];
+}
+
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size)
+{
+ char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+ int ret = 0;
+
+ switch (type) {
+ case DSO_BINARY_TYPE__DEBUGLINK: {
+ char *debuglink;
+
+ strncpy(file, dso->long_name, size);
+ debuglink = file + dso->long_name_len;
+ while (debuglink != file && *debuglink != '/')
+ debuglink--;
+ if (*debuglink == '/')
+ debuglink++;
+ filename__read_debuglink(dso->long_name, debuglink,
+ size - (debuglink - file));
+ }
+ break;
+ case DSO_BINARY_TYPE__BUILD_ID_CACHE:
+ /* skip the locally configured cache if a symfs is given */
+ if (symbol_conf.symfs[0] ||
+ (dso__build_id_filename(dso, file, size) == NULL))
+ ret = -1;
+ break;
+
+ case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s.debug",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
+ snprintf(file, size, "%s/usr/lib/debug%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
+ if (!dso->has_build_id) {
+ ret = -1;
+ break;
+ }
+
+ build_id__sprintf(dso->build_id,
+ sizeof(dso->build_id),
+ build_id_hex);
+ snprintf(file, size,
+ "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+ symbol_conf.symfs, build_id_hex, build_id_hex + 2);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+ snprintf(file, size, "%s%s",
+ symbol_conf.symfs, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__GUEST_KMODULE:
+ snprintf(file, size, "%s%s%s", symbol_conf.symfs,
+ root_dir, dso->long_name);
+ break;
+
+ case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+ snprintf(file, size, "%s%s", symbol_conf.symfs,
+ dso->long_name);
+ break;
+
+ default:
+ case DSO_BINARY_TYPE__KALLSYMS:
+ case DSO_BINARY_TYPE__VMLINUX:
+ case DSO_BINARY_TYPE__GUEST_KALLSYMS:
+ case DSO_BINARY_TYPE__GUEST_VMLINUX:
+ case DSO_BINARY_TYPE__JAVA_JIT:
+ case DSO_BINARY_TYPE__NOT_FOUND:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int open_dso(struct dso *dso, struct machine *machine)
+{
+ char *root_dir = (char *) "";
+ char *name;
+ int fd;
+
+ name = malloc(PATH_MAX);
+ if (!name)
+ return -ENOMEM;
+
+ if (machine)
+ root_dir = machine->root_dir;
+
+ if (dso__binary_type_file(dso, dso->data_type,
+ root_dir, name, PATH_MAX)) {
+ free(name);
+ return -EINVAL;
+ }
+
+ fd = open(name, O_RDONLY);
+ free(name);
+ return fd;
+}
+
+int dso__data_fd(struct dso *dso, struct machine *machine)
+{
+ static enum dso_binary_type binary_type_data[] = {
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__NOT_FOUND,
+ };
+ int i = 0;
+
+ if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
+ return open_dso(dso, machine);
+
+ do {
+ int fd;
+
+ dso->data_type = binary_type_data[i++];
+
+ fd = open_dso(dso, machine);
+ if (fd >= 0)
+ return fd;
+
+ } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
+
+ return -EINVAL;
+}
+
+static void
+dso_cache__free(struct rb_root *root)
+{
+ struct rb_node *next = rb_first(root);
+
+ while (next) {
+ struct dso_cache *cache;
+
+ cache = rb_entry(next, struct dso_cache, rb_node);
+ next = rb_next(&cache->rb_node);
+ rb_erase(&cache->rb_node, root);
+ free(cache);
+ }
+}
+
+static struct dso_cache*
+dso_cache__find(struct rb_root *root, u64 offset)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ else
+ return cache;
+ }
+ return NULL;
+}
+
+static void
+dso_cache__insert(struct rb_root *root, struct dso_cache *new)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct dso_cache *cache;
+ u64 offset = new->offset;
+
+ while (*p != NULL) {
+ u64 end;
+
+ parent = *p;
+ cache = rb_entry(parent, struct dso_cache, rb_node);
+ end = cache->offset + DSO__DATA_CACHE_SIZE;
+
+ if (offset < cache->offset)
+ p = &(*p)->rb_left;
+ else if (offset >= end)
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&new->rb_node, parent, p);
+ rb_insert_color(&new->rb_node, root);
+}
+
+static ssize_t
+dso_cache__memcpy(struct dso_cache *cache, u64 offset,
+ u8 *data, u64 size)
+{
+ u64 cache_offset = offset - cache->offset;
+ u64 cache_size = min(cache->size - cache_offset, size);
+
+ memcpy(data, cache->data + cache_offset, cache_size);
+ return cache_size;
+}
+
+static ssize_t
+dso_cache__read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+ ssize_t ret;
+ int fd;
+
+ fd = dso__data_fd(dso, machine);
+ if (fd < 0)
+ return -1;
+
+ do {
+ u64 cache_offset;
+
+ ret = -ENOMEM;
+
+ cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
+ if (!cache)
+ break;
+
+ cache_offset = offset & DSO__DATA_CACHE_MASK;
+ ret = -EINVAL;
+
+ if (-1 == lseek(fd, cache_offset, SEEK_SET))
+ break;
+
+ ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
+ if (ret <= 0)
+ break;
+
+ cache->offset = cache_offset;
+ cache->size = ret;
+ dso_cache__insert(&dso->cache, cache);
+
+ ret = dso_cache__memcpy(cache, offset, data, size);
+
+ } while (0);
+
+ if (ret <= 0)
+ free(cache);
+
+ close(fd);
+ return ret;
+}
+
+static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ struct dso_cache *cache;
+
+ cache = dso_cache__find(&dso->cache, offset);
+ if (cache)
+ return dso_cache__memcpy(cache, offset, data, size);
+ else
+ return dso_cache__read(dso, machine, offset, data, size);
+}
+
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size)
+{
+ ssize_t r = 0;
+ u8 *p = data;
+
+ do {
+ ssize_t ret;
+
+ ret = dso_cache_read(dso, machine, offset, p, size);
+ if (ret < 0)
+ return ret;
+
+ /* Reached EOF, return what we have. */
+ if (!ret)
+ break;
+
+ BUG_ON(ret > size);
+
+ r += ret;
+ p += ret;
+ offset += ret;
+ size -= ret;
+
+ } while (size);
+
+ return r;
+}
+
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size)
+{
+ u64 offset = map->map_ip(map, addr);
+ return dso__data_read_offset(dso, machine, offset, data, size);
+}
+
+struct map *dso__new_map(const char *name)
+{
+ struct map *map = NULL;
+ struct dso *dso = dso__new(name);
+
+ if (dso)
+ map = map__new2(0, dso, MAP__FUNCTION);
+
+ return map;
+}
+
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type)
+{
+ /*
+ * The kernel dso could be created by build_id processing.
+ */
+ struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
+
+ /*
+ * We need to run this in all cases, since during the build_id
+ * processing we had no idea this was the kernel dso.
+ */
+ if (dso != NULL) {
+ dso__set_short_name(dso, short_name);
+ dso->kernel = dso_type;
+ }
+
+ return dso;
+}
+
+void dso__set_long_name(struct dso *dso, char *name)
+{
+ if (name == NULL)
+ return;
+ dso->long_name = name;
+ dso->long_name_len = strlen(name);
+}
+
+void dso__set_short_name(struct dso *dso, const char *name)
+{
+ if (name == NULL)
+ return;
+ dso->short_name = name;
+ dso->short_name_len = strlen(name);
+}
+
+static void dso__set_basename(struct dso *dso)
+{
+ dso__set_short_name(dso, basename(dso->long_name));
+}
+
+int dso__name_len(const struct dso *dso)
+{
+ if (!dso)
+ return strlen("[unknown]");
+ if (verbose)
+ return dso->long_name_len;
+
+ return dso->short_name_len;
+}
+
+bool dso__loaded(const struct dso *dso, enum map_type type)
+{
+ return dso->loaded & (1 << type);
+}
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
+{
+ return dso->sorted_by_name & (1 << type);
+}
+
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
+{
+ dso->sorted_by_name |= (1 << type);
+}
+
+struct dso *dso__new(const char *name)
+{
+ struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
+
+ if (dso != NULL) {
+ int i;
+ strcpy(dso->name, name);
+ dso__set_long_name(dso, dso->name);
+ dso__set_short_name(dso, dso->name);
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
+ dso->cache = RB_ROOT;
+ dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
+ dso->loaded = 0;
+ dso->sorted_by_name = 0;
+ dso->has_build_id = 0;
+ dso->kernel = DSO_TYPE_USER;
+ dso->needs_swap = DSO_SWAP__UNSET;
+ INIT_LIST_HEAD(&dso->node);
+ }
+
+ return dso;
+}
+
+void dso__delete(struct dso *dso)
+{
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ symbols__delete(&dso->symbols[i]);
+ if (dso->sname_alloc)
+ free((char *)dso->short_name);
+ if (dso->lname_alloc)
+ free(dso->long_name);
+ dso_cache__free(&dso->cache);
+ free(dso);
+}
+
+void dso__set_build_id(struct dso *dso, void *build_id)
+{
+ memcpy(dso->build_id, build_id, sizeof(dso->build_id));
+ dso->has_build_id = 1;
+}
+
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
+{
+ return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
+}
+
+void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
+{
+ char path[PATH_MAX];
+
+ if (machine__is_default_guest(machine))
+ return;
+ sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+ if (sysfs__read_build_id(path, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+}
+
+int dso__kernel_module_get_build_id(struct dso *dso,
+ const char *root_dir)
+{
+ char filename[PATH_MAX];
+ /*
+ * kernel module short names are of the form "[module]" and
+ * we need just "module" here.
+ */
+ const char *name = dso->short_name + 1;
+
+ snprintf(filename, sizeof(filename),
+ "%s/sys/module/%.*s/notes/.note.gnu.build-id",
+ root_dir, (int)strlen(name) - 1, name);
+
+ if (sysfs__read_build_id(filename, dso->build_id,
+ sizeof(dso->build_id)) == 0)
+ dso->has_build_id = true;
+
+ return 0;
+}
+
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
+{
+ bool have_build_id = false;
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ if (pos->has_build_id) {
+ have_build_id = true;
+ continue;
+ }
+ if (filename__read_build_id(pos->long_name, pos->build_id,
+ sizeof(pos->build_id)) > 0) {
+ have_build_id = true;
+ pos->has_build_id = true;
+ }
+ }
+
+ return have_build_id;
+}
+
+void dsos__add(struct list_head *head, struct dso *dso)
+{
+ list_add_tail(&dso->node, head);
+}
+
+struct dso *dsos__find(struct list_head *head, const char *name)
+{
+ struct dso *pos;
+
+ list_for_each_entry(pos, head, node)
+ if (strcmp(pos->long_name, name) == 0)
+ return pos;
+ return NULL;
+}
+
+struct dso *__dsos__findnew(struct list_head *head, const char *name)
+{
+ struct dso *dso = dsos__find(head, name);
+
+ if (!dso) {
+ dso = dso__new(name);
+ if (dso != NULL) {
+ dsos__add(head, dso);
+ dso__set_basename(dso);
+ }
+ }
+
+ return dso;
+}
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ if (with_hits && !pos->hit)
+ continue;
+ ret += dso__fprintf_buildid(pos, fp);
+ ret += fprintf(fp, " %s\n", pos->long_name);
+ }
+ return ret;
+}
+
+size_t __dsos__fprintf(struct list_head *head, FILE *fp)
+{
+ struct dso *pos;
+ size_t ret = 0;
+
+ list_for_each_entry(pos, head, node) {
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ ret += dso__fprintf(pos, i, fp);
+ }
+
+ return ret;
+}
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
+{
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
+ return fprintf(fp, "%s", sbuild_id);
+}
+
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
+{
+ struct rb_node *nd;
+ size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
+
+ if (dso->short_name != dso->long_name)
+ ret += fprintf(fp, "%s, ", dso->long_name);
+ ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
+ dso->loaded ? "" : "NOT ");
+ ret += dso__fprintf_buildid(dso, fp);
+ ret += fprintf(fp, ")\n");
+ for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
+ struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
+ ret += symbol__fprintf(pos, fp);
+ }
+
+ return ret;
+}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
new file mode 100644
index 0000000..e032769
--- /dev/null
+++ b/tools/perf/util/dso.h
@@ -0,0 +1,148 @@
+#ifndef __PERF_DSO
+#define __PERF_DSO
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include "types.h"
+#include "map.h"
+
+enum dso_binary_type {
+ DSO_BINARY_TYPE__KALLSYMS = 0,
+ DSO_BINARY_TYPE__GUEST_KALLSYMS,
+ DSO_BINARY_TYPE__VMLINUX,
+ DSO_BINARY_TYPE__GUEST_VMLINUX,
+ DSO_BINARY_TYPE__JAVA_JIT,
+ DSO_BINARY_TYPE__DEBUGLINK,
+ DSO_BINARY_TYPE__BUILD_ID_CACHE,
+ DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
+ DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
+ DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
+ DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+ DSO_BINARY_TYPE__GUEST_KMODULE,
+ DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+ DSO_BINARY_TYPE__NOT_FOUND,
+};
+
+enum dso_kernel_type {
+ DSO_TYPE_USER = 0,
+ DSO_TYPE_KERNEL,
+ DSO_TYPE_GUEST_KERNEL
+};
+
+enum dso_swap_type {
+ DSO_SWAP__UNSET,
+ DSO_SWAP__NO,
+ DSO_SWAP__YES,
+};
+
+#define DSO__SWAP(dso, type, val) \
+({ \
+ type ____r = val; \
+ BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
+ if (dso->needs_swap == DSO_SWAP__YES) { \
+ switch (sizeof(____r)) { \
+ case 2: \
+ ____r = bswap_16(val); \
+ break; \
+ case 4: \
+ ____r = bswap_32(val); \
+ break; \
+ case 8: \
+ ____r = bswap_64(val); \
+ break; \
+ default: \
+ BUG_ON(1); \
+ } \
+ } \
+ ____r; \
+})
+
+#define DSO__DATA_CACHE_SIZE 4096
+#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
+
+struct dso_cache {
+ struct rb_node rb_node;
+ u64 offset;
+ u64 size;
+ char data[0];
+};
+
+struct dso {
+ struct list_head node;
+ struct rb_root symbols[MAP__NR_TYPES];
+ struct rb_root symbol_names[MAP__NR_TYPES];
+ struct rb_root cache;
+ enum dso_kernel_type kernel;
+ enum dso_swap_type needs_swap;
+ enum dso_binary_type symtab_type;
+ enum dso_binary_type data_type;
+ u8 adjust_symbols:1;
+ u8 has_build_id:1;
+ u8 hit:1;
+ u8 annotate_warned:1;
+ u8 sname_alloc:1;
+ u8 lname_alloc:1;
+ u8 sorted_by_name;
+ u8 loaded;
+ u8 build_id[BUILD_ID_SIZE];
+ const char *short_name;
+ char *long_name;
+ u16 long_name_len;
+ u16 short_name_len;
+ char name[0];
+};
+
+static inline void dso__set_loaded(struct dso *dso, enum map_type type)
+{
+ dso->loaded |= (1 << type);
+}
+
+struct dso *dso__new(const char *name);
+void dso__delete(struct dso *dso);
+
+void dso__set_short_name(struct dso *dso, const char *name);
+void dso__set_long_name(struct dso *dso, char *name);
+
+int dso__name_len(const struct dso *dso);
+
+bool dso__loaded(const struct dso *dso, enum map_type type);
+
+bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
+void dso__set_sorted_by_name(struct dso *dso, enum map_type type);
+void dso__sort_by_name(struct dso *dso, enum map_type type);
+
+void dso__set_build_id(struct dso *dso, void *build_id);
+bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
+void dso__read_running_kernel_build_id(struct dso *dso,
+ struct machine *machine);
+int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
+
+char dso__symtab_origin(const struct dso *dso);
+int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
+ char *root_dir, char *file, size_t size);
+
+int dso__data_fd(struct dso *dso, struct machine *machine);
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+ u64 offset, u8 *data, ssize_t size);
+ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
+ struct machine *machine, u64 addr,
+ u8 *data, ssize_t size);
+
+struct map *dso__new_map(const char *name);
+struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
+ const char *short_name, int dso_type);
+
+void dsos__add(struct list_head *head, struct dso *dso);
+struct dso *dsos__find(struct list_head *head, const char *name);
+struct dso *__dsos__findnew(struct list_head *head, const char *name);
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
+
+size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
+ bool with_hits);
+size_t __dsos__fprintf(struct list_head *head, FILE *fp);
+
+size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
+size_t dso__fprintf_symbols_by_name(struct dso *dso,
+ enum map_type type, FILE *fp);
+size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
+#endif /* __PERF_DSO */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index d3b1ecc..624c65e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -23,7 +23,6 @@
#define KSYM_NAME_LEN 256
#endif

-static void dso_cache__free(struct rb_root *root);
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
symbol_filter_t filter);
static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
@@ -56,39 +55,6 @@ static enum dso_binary_type binary_type_symtab[] = {

#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)

-static enum dso_binary_type binary_type_data[] = {
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
-
-int dso__name_len(const struct dso *dso)
-{
- if (!dso)
- return strlen("[unknown]");
- if (verbose)
- return dso->long_name_len;
-
- return dso->short_name_len;
-}
-
-bool dso__loaded(const struct dso *dso, enum map_type type)
-{
- return dso->loaded & (1 << type);
-}
-
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
-{
- return dso->sorted_by_name & (1 << type);
-}
-
-static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
-{
- dso->sorted_by_name |= (1 << type);
-}
-
bool symbol_type__is_a(char symbol_type, enum map_type map_type)
{
symbol_type = toupper(symbol_type);
@@ -270,7 +236,7 @@ void symbol__delete(struct symbol *sym)
free(((void *)sym) - symbol_conf.priv_size);
}

-static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
+size_t symbol__fprintf(struct symbol *sym, FILE *fp)
{
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
sym->start, sym->end,
@@ -301,53 +267,7 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
return symbol__fprintf_symname_offs(sym, NULL, fp);
}

-void dso__set_long_name(struct dso *dso, char *name)
-{
- if (name == NULL)
- return;
- dso->long_name = name;
- dso->long_name_len = strlen(name);
-}
-
-static void dso__set_short_name(struct dso *dso, const char *name)
-{
- if (name == NULL)
- return;
- dso->short_name = name;
- dso->short_name_len = strlen(name);
-}
-
-static void dso__set_basename(struct dso *dso)
-{
- dso__set_short_name(dso, basename(dso->long_name));
-}
-
-struct dso *dso__new(const char *name)
-{
- struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
-
- if (dso != NULL) {
- int i;
- strcpy(dso->name, name);
- dso__set_long_name(dso, dso->name);
- dso__set_short_name(dso, dso->name);
- for (i = 0; i < MAP__NR_TYPES; ++i)
- dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
- dso->cache = RB_ROOT;
- dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
- dso->loaded = 0;
- dso->sorted_by_name = 0;
- dso->has_build_id = 0;
- dso->kernel = DSO_TYPE_USER;
- dso->needs_swap = DSO_SWAP__UNSET;
- INIT_LIST_HEAD(&dso->node);
- }
-
- return dso;
-}
-
-static void symbols__delete(struct rb_root *symbols)
+void symbols__delete(struct rb_root *symbols)
{
struct symbol *pos;
struct rb_node *next = rb_first(symbols);
@@ -360,25 +280,6 @@ static void symbols__delete(struct rb_root *symbols)
}
}

-void dso__delete(struct dso *dso)
-{
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- symbols__delete(&dso->symbols[i]);
- if (dso->sname_alloc)
- free((char *)dso->short_name);
- if (dso->lname_alloc)
- free(dso->long_name);
- dso_cache__free(&dso->cache);
- free(dso);
-}
-
-void dso__set_build_id(struct dso *dso, void *build_id)
-{
- memcpy(dso->build_id, build_id, sizeof(dso->build_id));
- dso->has_build_id = 1;
-}
-
void symbols__insert(struct rb_root *symbols, struct symbol *sym)
{
struct rb_node **p = &symbols->rb_node;
@@ -504,14 +405,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
&dso->symbols[type]);
}

-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
-{
- char sbuild_id[BUILD_ID_SIZE * 2 + 1];
-
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
- return fprintf(fp, "%s", sbuild_id);
-}
-
size_t dso__fprintf_symbols_by_name(struct dso *dso,
enum map_type type, FILE *fp)
{
@@ -527,25 +420,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
return ret;
}

-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
-{
- struct rb_node *nd;
- size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
-
- if (dso->short_name != dso->long_name)
- ret += fprintf(fp, "%s, ", dso->long_name);
- ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
- dso->loaded ? "" : "NOT ");
- ret += dso__fprintf_buildid(dso, fp);
- ret += fprintf(fp, ")\n");
- for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
- struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
- ret += symbol__fprintf(pos, fp);
- }
-
- return ret;
-}
-
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start))
@@ -877,136 +751,6 @@ out_failure:
return -1;
}

-bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
-{
- return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
-}
-
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
-{
- bool have_build_id = false;
- struct dso *pos;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- if (pos->has_build_id) {
- have_build_id = true;
- continue;
- }
- if (filename__read_build_id(pos->long_name, pos->build_id,
- sizeof(pos->build_id)) > 0) {
- have_build_id = true;
- pos->has_build_id = true;
- }
- }
-
- return have_build_id;
-}
-
-char dso__symtab_origin(const struct dso *dso)
-{
- static const char origin[] = {
- [DSO_BINARY_TYPE__KALLSYMS] = 'k',
- [DSO_BINARY_TYPE__VMLINUX] = 'v',
- [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
- [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
- [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
- [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
- [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
- [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
- [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
- [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
- [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
- [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
- [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
- };
-
- if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
- return '!';
- return origin[dso->symtab_type];
-}
-
-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size)
-{
- char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- int ret = 0;
-
- switch (type) {
- case DSO_BINARY_TYPE__DEBUGLINK: {
- char *debuglink;
-
- strncpy(file, dso->long_name, size);
- debuglink = file + dso->long_name_len;
- while (debuglink != file && *debuglink != '/')
- debuglink--;
- if (*debuglink == '/')
- debuglink++;
- filename__read_debuglink(dso->long_name, debuglink,
- size - (debuglink - file));
- }
- break;
- case DSO_BINARY_TYPE__BUILD_ID_CACHE:
- /* skip the locally configured cache if a symfs is given */
- if (symbol_conf.symfs[0] ||
- (dso__build_id_filename(dso, file, size) == NULL))
- ret = -1;
- break;
-
- case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s.debug",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
- snprintf(file, size, "%s/usr/lib/debug%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
- if (!dso->has_build_id) {
- ret = -1;
- break;
- }
-
- build_id__sprintf(dso->build_id,
- sizeof(dso->build_id),
- build_id_hex);
- snprintf(file, size,
- "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
- symbol_conf.symfs, build_id_hex, build_id_hex + 2);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
- snprintf(file, size, "%s%s",
- symbol_conf.symfs, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__GUEST_KMODULE:
- snprintf(file, size, "%s%s%s", symbol_conf.symfs,
- root_dir, dso->long_name);
- break;
-
- case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
- snprintf(file, size, "%s%s", symbol_conf.symfs,
- dso->long_name);
- break;
-
- default:
- case DSO_BINARY_TYPE__KALLSYMS:
- case DSO_BINARY_TYPE__VMLINUX:
- case DSO_BINARY_TYPE__GUEST_KALLSYMS:
- case DSO_BINARY_TYPE__GUEST_VMLINUX:
- case DSO_BINARY_TYPE__JAVA_JIT:
- case DSO_BINARY_TYPE__NOT_FOUND:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
{
char *name;
@@ -1142,27 +886,6 @@ struct map *map_groups__find_by_name(struct map_groups *mg,
return NULL;
}

-static int dso__kernel_module_get_build_id(struct dso *dso,
- const char *root_dir)
-{
- char filename[PATH_MAX];
- /*
- * kernel module short names are of the form "[module]" and
- * we need just "module" here.
- */
- const char *name = dso->short_name + 1;
-
- snprintf(filename, sizeof(filename),
- "%s/sys/module/%.*s/notes/.note.gnu.build-id",
- root_dir, (int)strlen(name) - 1, name);
-
- if (sysfs__read_build_id(filename, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-
- return 0;
-}
-
static int map_groups__set_modules_path_dir(struct map_groups *mg,
const char *dir_name)
{
@@ -1576,50 +1299,6 @@ out_try_fixup:
return err;
}

-void dsos__add(struct list_head *head, struct dso *dso)
-{
- list_add_tail(&dso->node, head);
-}
-
-struct dso *dsos__find(struct list_head *head, const char *name)
-{
- struct dso *pos;
-
- list_for_each_entry(pos, head, node)
- if (strcmp(pos->long_name, name) == 0)
- return pos;
- return NULL;
-}
-
-struct dso *__dsos__findnew(struct list_head *head, const char *name)
-{
- struct dso *dso = dsos__find(head, name);
-
- if (!dso) {
- dso = dso__new(name);
- if (dso != NULL) {
- dsos__add(head, dso);
- dso__set_basename(dso);
- }
- }
-
- return dso;
-}
-
-size_t __dsos__fprintf(struct list_head *head, FILE *fp)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- ret += dso__fprintf(pos, i, fp);
- }
-
- return ret;
-}
-
size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
{
struct rb_node *nd;
@@ -1634,21 +1313,6 @@ size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
return ret;
}

-static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
- bool with_hits)
-{
- struct dso *pos;
- size_t ret = 0;
-
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit)
- continue;
- ret += dso__fprintf_buildid(pos, fp);
- ret += fprintf(fp, " %s\n", pos->long_name);
- }
- return ret;
-}
-
size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
bool with_hits)
{
@@ -1669,39 +1333,6 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
return ret;
}

-static struct dso*
-dso__kernel_findnew(struct machine *machine, const char *name,
- const char *short_name, int dso_type)
-{
- /*
- * The kernel dso could be created by build_id processing.
- */
- struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
-
- /*
- * We need to run this in all cases, since during the build_id
- * processing we had no idea this was the kernel dso.
- */
- if (dso != NULL) {
- dso__set_short_name(dso, short_name);
- dso->kernel = dso_type;
- }
-
- return dso;
-}
-
-void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
-{
- char path[PATH_MAX];
-
- if (machine__is_default_guest(machine))
- return;
- sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
- if (sysfs__read_build_id(path, dso->build_id,
- sizeof(dso->build_id)) == 0)
- dso->has_build_id = true;
-}
-
static struct dso *machine__get_kernel(struct machine *machine)
{
const char *vmlinux_name = NULL;
@@ -2144,229 +1775,3 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,

return ret;
}
-
-struct map *dso__new_map(const char *name)
-{
- struct map *map = NULL;
- struct dso *dso = dso__new(name);
-
- if (dso)
- map = map__new2(0, dso, MAP__FUNCTION);
-
- return map;
-}
-
-static int open_dso(struct dso *dso, struct machine *machine)
-{
- char *root_dir = (char *) "";
- char *name;
- int fd;
-
- name = malloc(PATH_MAX);
- if (!name)
- return -ENOMEM;
-
- if (machine)
- root_dir = machine->root_dir;
-
- if (dso__binary_type_file(dso, dso->data_type,
- root_dir, name, PATH_MAX)) {
- free(name);
- return -EINVAL;
- }
-
- fd = open(name, O_RDONLY);
- free(name);
- return fd;
-}
-
-int dso__data_fd(struct dso *dso, struct machine *machine)
-{
- int i = 0;
-
- if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
- return open_dso(dso, machine);
-
- do {
- int fd;
-
- dso->data_type = binary_type_data[i++];
-
- fd = open_dso(dso, machine);
- if (fd >= 0)
- return fd;
-
- } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
-
- return -EINVAL;
-}
-
-static void
-dso_cache__free(struct rb_root *root)
-{
- struct rb_node *next = rb_first(root);
-
- while (next) {
- struct dso_cache *cache;
-
- cache = rb_entry(next, struct dso_cache, rb_node);
- next = rb_next(&cache->rb_node);
- rb_erase(&cache->rb_node, root);
- free(cache);
- }
-}
-
-static struct dso_cache*
-dso_cache__find(struct rb_root *root, u64 offset)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- else
- return cache;
- }
- return NULL;
-}
-
-static void
-dso_cache__insert(struct rb_root *root, struct dso_cache *new)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct dso_cache *cache;
- u64 offset = new->offset;
-
- while (*p != NULL) {
- u64 end;
-
- parent = *p;
- cache = rb_entry(parent, struct dso_cache, rb_node);
- end = cache->offset + DSO__DATA_CACHE_SIZE;
-
- if (offset < cache->offset)
- p = &(*p)->rb_left;
- else if (offset >= end)
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&new->rb_node, parent, p);
- rb_insert_color(&new->rb_node, root);
-}
-
-static ssize_t
-dso_cache__memcpy(struct dso_cache *cache, u64 offset,
- u8 *data, u64 size)
-{
- u64 cache_offset = offset - cache->offset;
- u64 cache_size = min(cache->size - cache_offset, size);
-
- memcpy(data, cache->data + cache_offset, cache_size);
- return cache_size;
-}
-
-static ssize_t
-dso_cache__read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
- ssize_t ret;
- int fd;
-
- fd = dso__data_fd(dso, machine);
- if (fd < 0)
- return -1;
-
- do {
- u64 cache_offset;
-
- ret = -ENOMEM;
-
- cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
- if (!cache)
- break;
-
- cache_offset = offset & DSO__DATA_CACHE_MASK;
- ret = -EINVAL;
-
- if (-1 == lseek(fd, cache_offset, SEEK_SET))
- break;
-
- ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
- if (ret <= 0)
- break;
-
- cache->offset = cache_offset;
- cache->size = ret;
- dso_cache__insert(&dso->cache, cache);
-
- ret = dso_cache__memcpy(cache, offset, data, size);
-
- } while (0);
-
- if (ret <= 0)
- free(cache);
-
- close(fd);
- return ret;
-}
-
-static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- struct dso_cache *cache;
-
- cache = dso_cache__find(&dso->cache, offset);
- if (cache)
- return dso_cache__memcpy(cache, offset, data, size);
- else
- return dso_cache__read(dso, machine, offset, data, size);
-}
-
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size)
-{
- ssize_t r = 0;
- u8 *p = data;
-
- do {
- ssize_t ret;
-
- ret = dso_cache_read(dso, machine, offset, p, size);
- if (ret < 0)
- return ret;
-
- /* Reached EOF, return what we have. */
- if (!ret)
- break;
-
- BUG_ON(ret > size);
-
- r += ret;
- p += ret;
- offset += ret;
- size -= ret;
-
- } while (size);
-
- return r;
-}
-
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size)
-{
- u64 offset = map->map_ip(map, addr);
- return dso__data_read_offset(dso, machine, offset, data, size);
-}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 45d3df8..863b05b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -19,6 +19,8 @@
#include <elf.h>
#endif

+#include "dso.h"
+
#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);

@@ -70,6 +72,7 @@ struct symbol {
};

void symbol__delete(struct symbol *sym);
+void symbols__delete(struct rb_root *symbols);

static inline size_t symbol__size(const struct symbol *sym)
{
@@ -160,70 +163,6 @@ struct addr_location {
s32 cpu;
};

-enum dso_binary_type {
- DSO_BINARY_TYPE__KALLSYMS = 0,
- DSO_BINARY_TYPE__GUEST_KALLSYMS,
- DSO_BINARY_TYPE__VMLINUX,
- DSO_BINARY_TYPE__GUEST_VMLINUX,
- DSO_BINARY_TYPE__JAVA_JIT,
- DSO_BINARY_TYPE__DEBUGLINK,
- DSO_BINARY_TYPE__BUILD_ID_CACHE,
- DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
- DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
- DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
- DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
- DSO_BINARY_TYPE__GUEST_KMODULE,
- DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
- DSO_BINARY_TYPE__NOT_FOUND,
-};
-
-enum dso_kernel_type {
- DSO_TYPE_USER = 0,
- DSO_TYPE_KERNEL,
- DSO_TYPE_GUEST_KERNEL
-};
-
-enum dso_swap_type {
- DSO_SWAP__UNSET,
- DSO_SWAP__NO,
- DSO_SWAP__YES,
-};
-
-#define DSO__DATA_CACHE_SIZE 4096
-#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1)
-
-struct dso_cache {
- struct rb_node rb_node;
- u64 offset;
- u64 size;
- char data[0];
-};
-
-struct dso {
- struct list_head node;
- struct rb_root symbols[MAP__NR_TYPES];
- struct rb_root symbol_names[MAP__NR_TYPES];
- struct rb_root cache;
- enum dso_kernel_type kernel;
- enum dso_swap_type needs_swap;
- enum dso_binary_type symtab_type;
- enum dso_binary_type data_type;
- u8 adjust_symbols:1;
- u8 has_build_id:1;
- u8 hit:1;
- u8 annotate_warned:1;
- u8 sname_alloc:1;
- u8 lname_alloc:1;
- u8 sorted_by_name;
- u8 loaded;
- u8 build_id[BUILD_ID_SIZE];
- const char *short_name;
- char *long_name;
- u16 long_name_len;
- u16 short_name_len;
- char name[0];
-};
-
struct symsrc {
char *name;
int fd;
@@ -254,47 +193,6 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
bool symsrc__has_symtab(struct symsrc *ss);
bool symsrc__possibly_runtime(struct symsrc *ss);

-#define DSO__SWAP(dso, type, val) \
-({ \
- type ____r = val; \
- BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \
- if (dso->needs_swap == DSO_SWAP__YES) { \
- switch (sizeof(____r)) { \
- case 2: \
- ____r = bswap_16(val); \
- break; \
- case 4: \
- ____r = bswap_32(val); \
- break; \
- case 8: \
- ____r = bswap_64(val); \
- break; \
- default: \
- BUG_ON(1); \
- } \
- } \
- ____r; \
-})
-
-struct dso *dso__new(const char *name);
-void dso__delete(struct dso *dso);
-
-int dso__name_len(const struct dso *dso);
-
-bool dso__loaded(const struct dso *dso, enum map_type type);
-bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
-
-static inline void dso__set_loaded(struct dso *dso, enum map_type type)
-{
- dso->loaded |= (1 << type);
-}
-
-void dso__sort_by_name(struct dso *dso, enum map_type type);
-
-void dsos__add(struct list_head *head, struct dso *dso);
-struct dso *dsos__find(struct list_head *head, const char *name);
-struct dso *__dsos__findnew(struct list_head *head, const char *name);
-
int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
int dso__load_vmlinux(struct dso *dso, struct map *map,
const char *vmlinux, symbol_filter_t filter);
@@ -307,25 +205,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename,
int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
symbol_filter_t filter);

-size_t __dsos__fprintf(struct list_head *head, FILE *fp);
-
size_t machine__fprintf_dsos_buildid(struct machine *machine,
FILE *fp, bool with_hits);
size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
FILE *fp, bool with_hits);
-size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
-size_t dso__fprintf_symbols_by_name(struct dso *dso,
- enum map_type type, FILE *fp);
-size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
-
-char dso__symtab_origin(const struct dso *dso);
-void dso__set_long_name(struct dso *dso, char *name);
-void dso__set_build_id(struct dso *dso, void *build_id);
-bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
-void dso__read_running_kernel_build_id(struct dso *dso,
- struct machine *machine);
-struct map *dso__new_map(const char *name);
+
struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
u64 addr);
struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
@@ -333,7 +218,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,

int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
@@ -355,19 +239,11 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
size_t symbol__fprintf_symname_offs(const struct symbol *sym,
const struct addr_location *al, FILE *fp);
size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
+size_t symbol__fprintf(struct symbol *sym, FILE *fp);
bool symbol_type__is_a(char symbol_type, enum map_type map_type);

size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);

-int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
- char *root_dir, char *file, size_t size);
-
-int dso__data_fd(struct dso *dso, struct machine *machine);
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
- u64 offset, u8 *data, ssize_t size);
-ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
- struct machine *machine, u64 addr,
- u8 *data, ssize_t size);
int dso__test_data(void);
int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
struct symsrc *runtime_ss, symbol_filter_t filter,