Skip to content

Commit

Permalink
perf symbols: Add interface to read DSO image data
Browse files Browse the repository at this point in the history
Adding following interface for DSO object to allow
reading of DSO image data:

  dso__data_fd
    - opens DSO and returns file descriptor
      Binary types are used to locate/open DSO in following order:
        DSO_BINARY_TYPE__BUILD_ID_CACHE
        DSO_BINARY_TYPE__SYSTEM_PATH_DSO
      In other word we first try to open DSO build-id path,
      and if that fails we try to open DSO system path.

  dso__data_read_offset
    - reads DSO data from specified offset

  dso__data_read_addr
    - reads DSO data from specified address/map.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Benjamin Redelings <benjamin.redelings@nescent.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Ulrich Drepper <drepper@gmail.com>
Link: http://lkml.kernel.org/r/1342959280-5361-11-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Jul 25, 2012
1 parent 44f24cb commit 949d160
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
109 changes: 109 additions & 0 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ static enum dso_binary_type binary_type_symtab[] = {

#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(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 sizeof(binary_type_data)

int dso__name_len(const struct dso *dso)
{
if (!dso)
Expand Down Expand Up @@ -336,6 +344,7 @@ struct dso *dso__new(const char *name)
for (i = 0; i < MAP__NR_TYPES; ++i)
dso->symbols[i] = dso->symbol_names[i] = 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;
Expand Down Expand Up @@ -2953,3 +2962,103 @@ struct map *dso__new_map(const char *name)

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 ssize_t dso_cache_read(struct dso *dso __used, u64 offset __used,
u8 *data __used, ssize_t size __used)
{
return -EINVAL;
}

static int dso_cache_add(struct dso *dso __used, u64 offset __used,
u8 *data __used, ssize_t size __used)
{
return 0;
}

static ssize_t read_dso_data(struct dso *dso, struct machine *machine,
u64 offset, u8 *data, ssize_t size)
{
ssize_t rsize = -1;
int fd;

fd = dso__data_fd(dso, machine);
if (fd < 0)
return -1;

do {
if (-1 == lseek(fd, offset, SEEK_SET))
break;

rsize = read(fd, data, size);
if (-1 == rsize)
break;

if (dso_cache_add(dso, offset, data, size))
pr_err("Failed to add data int dso cache.");

} while (0);

close(fd);
return rsize;
}

ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
u64 offset, u8 *data, ssize_t size)
{
if (dso_cache_read(dso, offset, data, size))
return read_dso_data(dso, machine, offset, data, size);
return 0;
}

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);
}
8 changes: 8 additions & 0 deletions tools/perf/util/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ struct dso {
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;
Expand Down Expand Up @@ -306,4 +307,11 @@ 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);
#endif /* __PERF_SYMBOL */

0 comments on commit 949d160

Please sign in to comment.