perf symbols: Add interface to read DSO image data
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>
This commit is contained in:
parent
44f24cb315
commit
949d160b69
2 changed files with 117 additions and 0 deletions
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue