diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-07-22 08:14:33 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-07-25 10:32:49 -0400 |
commit | 949d160b6962c13fc071afefa22997780fcc94a5 (patch) | |
tree | 8a408684bc293bf1b448872afef250684e375d37 /tools/perf/util/symbol.c | |
parent | 44f24cb3156a1e7d2b6bb501b7f6153aed08994c (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.c | 109 |
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 | ||
68 | static 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 | |||
68 | int dso__name_len(const struct dso *dso) | 76 | int 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 | |||
2966 | static 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 | |||
2990 | int 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 | |||
3011 | static 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 | |||
3017 | static 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 | |||
3023 | static 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 | |||
3050 | ssize_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 | |||
3058 | ssize_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 | } | ||