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 | |
| 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')
| -rw-r--r-- | tools/perf/util/symbol.c | 109 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 8 |
2 files changed, 117 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 | } | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index dc474f07bb2d..9b9ea00173af 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -189,6 +189,7 @@ struct dso { | |||
| 189 | enum dso_kernel_type kernel; | 189 | enum dso_kernel_type kernel; |
| 190 | enum dso_swap_type needs_swap; | 190 | enum dso_swap_type needs_swap; |
| 191 | enum dso_binary_type symtab_type; | 191 | enum dso_binary_type symtab_type; |
| 192 | enum dso_binary_type data_type; | ||
| 192 | u8 adjust_symbols:1; | 193 | u8 adjust_symbols:1; |
| 193 | u8 has_build_id:1; | 194 | u8 has_build_id:1; |
| 194 | u8 hit:1; | 195 | u8 hit:1; |
| @@ -306,4 +307,11 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); | |||
| 306 | 307 | ||
| 307 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | 308 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, |
| 308 | char *root_dir, char *file, size_t size); | 309 | char *root_dir, char *file, size_t size); |
| 310 | |||
| 311 | int dso__data_fd(struct dso *dso, struct machine *machine); | ||
| 312 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
| 313 | u64 offset, u8 *data, ssize_t size); | ||
| 314 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | ||
| 315 | struct machine *machine, u64 addr, | ||
| 316 | u8 *data, ssize_t size); | ||
| 309 | #endif /* __PERF_SYMBOL */ | 317 | #endif /* __PERF_SYMBOL */ |
