diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2014-07-22 09:17:59 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-07-23 16:36:36 -0400 |
commit | 2b5b8bb27b9ec899cfba686dabec113ea0d4cbda (patch) | |
tree | 1dbb729e798b6a42829c2c83de667eb07f3c3094 /tools/perf | |
parent | 51682dc744c3db89e515ac47a4c1f7003fd81d20 (diff) |
perf tools: Add dso__type()
dso__type() determines wheather a dso is 32-bit, x32 (32-bit with 64-bit
registers) or 64-bit.
dso__type() will be used to determine the VDSO a program maps.
Reviewed-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1406035081-14301-51-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/dso.c | 11 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 10 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 33 | ||||
-rw-r--r-- | tools/perf/util/symbol-minimal.c | 21 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
5 files changed, 77 insertions, 0 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e657d86e82b9..90d02c661dd4 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -940,3 +940,14 @@ size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) | |||
940 | 940 | ||
941 | return ret; | 941 | return ret; |
942 | } | 942 | } |
943 | |||
944 | enum dso_type dso__type(struct dso *dso, struct machine *machine) | ||
945 | { | ||
946 | int fd; | ||
947 | |||
948 | fd = dso__data_fd(dso, machine); | ||
949 | if (fd < 0) | ||
950 | return DSO__TYPE_UNKNOWN; | ||
951 | |||
952 | return dso__type_fd(fd); | ||
953 | } | ||
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index af1c256aad4f..5e463c0964d4 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/rbtree.h> | 5 | #include <linux/rbtree.h> |
6 | #include <stdbool.h> | 6 | #include <stdbool.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/bitops.h> | ||
8 | #include "map.h" | 9 | #include "map.h" |
9 | #include "build-id.h" | 10 | #include "build-id.h" |
10 | 11 | ||
@@ -50,6 +51,13 @@ enum dso_data_status_seen { | |||
50 | DSO_DATA_STATUS_SEEN_ITRACE, | 51 | DSO_DATA_STATUS_SEEN_ITRACE, |
51 | }; | 52 | }; |
52 | 53 | ||
54 | enum dso_type { | ||
55 | DSO__TYPE_UNKNOWN, | ||
56 | DSO__TYPE_64BIT, | ||
57 | DSO__TYPE_32BIT, | ||
58 | DSO__TYPE_X32BIT, | ||
59 | }; | ||
60 | |||
53 | #define DSO__SWAP(dso, type, val) \ | 61 | #define DSO__SWAP(dso, type, val) \ |
54 | ({ \ | 62 | ({ \ |
55 | type ____r = val; \ | 63 | type ____r = val; \ |
@@ -245,4 +253,6 @@ static inline bool dso__is_kcore(struct dso *dso) | |||
245 | 253 | ||
246 | void dso__free_a2l(struct dso *dso); | 254 | void dso__free_a2l(struct dso *dso); |
247 | 255 | ||
256 | enum dso_type dso__type(struct dso *dso, struct machine *machine); | ||
257 | |||
248 | #endif /* __PERF_DSO */ | 258 | #endif /* __PERF_DSO */ |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 61b9cd456310..d75349979e65 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -1028,6 +1028,39 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, | |||
1028 | return err; | 1028 | return err; |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | enum dso_type dso__type_fd(int fd) | ||
1032 | { | ||
1033 | enum dso_type dso_type = DSO__TYPE_UNKNOWN; | ||
1034 | GElf_Ehdr ehdr; | ||
1035 | Elf_Kind ek; | ||
1036 | Elf *elf; | ||
1037 | |||
1038 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
1039 | if (elf == NULL) | ||
1040 | goto out; | ||
1041 | |||
1042 | ek = elf_kind(elf); | ||
1043 | if (ek != ELF_K_ELF) | ||
1044 | goto out_end; | ||
1045 | |||
1046 | if (gelf_getclass(elf) == ELFCLASS64) { | ||
1047 | dso_type = DSO__TYPE_64BIT; | ||
1048 | goto out_end; | ||
1049 | } | ||
1050 | |||
1051 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
1052 | goto out_end; | ||
1053 | |||
1054 | if (ehdr.e_machine == EM_X86_64) | ||
1055 | dso_type = DSO__TYPE_X32BIT; | ||
1056 | else | ||
1057 | dso_type = DSO__TYPE_32BIT; | ||
1058 | out_end: | ||
1059 | elf_end(elf); | ||
1060 | out: | ||
1061 | return dso_type; | ||
1062 | } | ||
1063 | |||
1031 | static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len) | 1064 | static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len) |
1032 | { | 1065 | { |
1033 | ssize_t r; | 1066 | ssize_t r; |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 101f55d407d0..c9541fea9514 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
@@ -305,6 +305,27 @@ static int fd__is_64_bit(int fd) | |||
305 | return e_ident[EI_CLASS] == ELFCLASS64; | 305 | return e_ident[EI_CLASS] == ELFCLASS64; |
306 | } | 306 | } |
307 | 307 | ||
308 | enum dso_type dso__type_fd(int fd) | ||
309 | { | ||
310 | Elf64_Ehdr ehdr; | ||
311 | int ret; | ||
312 | |||
313 | ret = fd__is_64_bit(fd); | ||
314 | if (ret < 0) | ||
315 | return DSO__TYPE_UNKNOWN; | ||
316 | |||
317 | if (ret) | ||
318 | return DSO__TYPE_64BIT; | ||
319 | |||
320 | if (readn(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) | ||
321 | return DSO__TYPE_UNKNOWN; | ||
322 | |||
323 | if (ehdr.e_machine == EM_X86_64) | ||
324 | return DSO__TYPE_X32BIT; | ||
325 | |||
326 | return DSO__TYPE_32BIT; | ||
327 | } | ||
328 | |||
308 | int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, | 329 | int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, |
309 | struct symsrc *ss, | 330 | struct symsrc *ss, |
310 | struct symsrc *runtime_ss __maybe_unused, | 331 | struct symsrc *runtime_ss __maybe_unused, |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index ee2d3ccd3ad1..e7295e93cff9 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -243,6 +243,8 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, | |||
243 | struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); | 243 | struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); |
244 | struct symbol *dso__next_symbol(struct symbol *sym); | 244 | struct symbol *dso__next_symbol(struct symbol *sym); |
245 | 245 | ||
246 | enum dso_type dso__type_fd(int fd); | ||
247 | |||
246 | int filename__read_build_id(const char *filename, void *bf, size_t size); | 248 | int filename__read_build_id(const char *filename, void *bf, size_t size); |
247 | int sysfs__read_build_id(const char *filename, void *bf, size_t size); | 249 | int sysfs__read_build_id(const char *filename, void *bf, size_t size); |
248 | int modules__parse(const char *filename, void *arg, | 250 | int modules__parse(const char *filename, void *arg, |