aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-07-22 08:14:33 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-07-25 10:32:49 -0400
commit949d160b6962c13fc071afefa22997780fcc94a5 (patch)
tree8a408684bc293bf1b448872afef250684e375d37 /tools/perf/util/symbol.c
parent44f24cb3156a1e7d2b6bb501b7f6153aed08994c (diff)
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>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 60677a63bc7d..8131949d10f3 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -65,6 +65,14 @@ static enum dso_binary_type binary_type_symtab[] = {
65 65
66#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) 66#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
67 67
68static enum dso_binary_type binary_type_data[] = {
69 DSO_BINARY_TYPE__BUILD_ID_CACHE,
70 DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
71 DSO_BINARY_TYPE__NOT_FOUND,
72};
73
74#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data)
75
68int dso__name_len(const struct dso *dso) 76int dso__name_len(const struct dso *dso)
69{ 77{
70 if (!dso) 78 if (!dso)
@@ -336,6 +344,7 @@ struct dso *dso__new(const char *name)
336 for (i = 0; i < MAP__NR_TYPES; ++i) 344 for (i = 0; i < MAP__NR_TYPES; ++i)
337 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; 345 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
338 dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; 346 dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
347 dso->data_type = DSO_BINARY_TYPE__NOT_FOUND;
339 dso->loaded = 0; 348 dso->loaded = 0;
340 dso->sorted_by_name = 0; 349 dso->sorted_by_name = 0;
341 dso->has_build_id = 0; 350 dso->has_build_id = 0;
@@ -2953,3 +2962,103 @@ struct map *dso__new_map(const char *name)
2953 2962
2954 return map; 2963 return map;
2955} 2964}
2965
2966static int open_dso(struct dso *dso, struct machine *machine)
2967{
2968 char *root_dir = (char *) "";
2969 char *name;
2970 int fd;
2971
2972 name = malloc(PATH_MAX);
2973 if (!name)
2974 return -ENOMEM;
2975
2976 if (machine)
2977 root_dir = machine->root_dir;
2978
2979 if (dso__binary_type_file(dso, dso->data_type,
2980 root_dir, name, PATH_MAX)) {
2981 free(name);
2982 return -EINVAL;
2983 }
2984
2985 fd = open(name, O_RDONLY);
2986 free(name);
2987 return fd;
2988}
2989
2990int dso__data_fd(struct dso *dso, struct machine *machine)
2991{
2992 int i = 0;
2993
2994 if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
2995 return open_dso(dso, machine);
2996
2997 do {
2998 int fd;
2999
3000 dso->data_type = binary_type_data[i++];
3001
3002 fd = open_dso(dso, machine);
3003 if (fd >= 0)
3004 return fd;
3005
3006 } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
3007
3008 return -EINVAL;
3009}
3010
3011static ssize_t dso_cache_read(struct dso *dso __used, u64 offset __used,
3012 u8 *data __used, ssize_t size __used)
3013{
3014 return -EINVAL;
3015}
3016
3017static int dso_cache_add(struct dso *dso __used, u64 offset __used,
3018 u8 *data __used, ssize_t size __used)
3019{
3020 return 0;
3021}
3022
3023static ssize_t read_dso_data(struct dso *dso, struct machine *machine,
3024 u64 offset, u8 *data, ssize_t size)
3025{
3026 ssize_t rsize = -1;
3027 int fd;
3028
3029 fd = dso__data_fd(dso, machine);
3030 if (fd < 0)
3031 return -1;
3032
3033 do {
3034 if (-1 == lseek(fd, offset, SEEK_SET))
3035 break;
3036
3037 rsize = read(fd, data, size);
3038 if (-1 == rsize)
3039 break;
3040
3041 if (dso_cache_add(dso, offset, data, size))
3042 pr_err("Failed to add data int dso cache.");
3043
3044 } while (0);
3045
3046 close(fd);
3047 return rsize;
3048}
3049
3050ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
3051 u64 offset, u8 *data, ssize_t size)
3052{
3053 if (dso_cache_read(dso, offset, data, size))
3054 return read_dso_data(dso, machine, offset, data, size);
3055 return 0;
3056}
3057
3058ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
3059 struct machine *machine, u64 addr,
3060 u8 *data, ssize_t size)
3061{
3062 u64 offset = map->map_ip(map, addr);
3063 return dso__data_read_offset(dso, machine, offset, data, size);
3064}