perf tools: Add dso__type()
authorAdrian Hunter <adrian.hunter@intel.com>
Tue, 22 Jul 2014 13:17:59 +0000 (16:17 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 23 Jul 2014 20:36:36 +0000 (17:36 -0300)
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>
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/symbol-elf.c
tools/perf/util/symbol-minimal.c
tools/perf/util/symbol.h

index e657d86..90d02c6 100644 (file)
@@ -940,3 +940,14 @@ size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
 
        return ret;
 }
+
+enum dso_type dso__type(struct dso *dso, struct machine *machine)
+{
+       int fd;
+
+       fd = dso__data_fd(dso, machine);
+       if (fd < 0)
+               return DSO__TYPE_UNKNOWN;
+
+       return dso__type_fd(fd);
+}
index af1c256..5e463c0 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/rbtree.h>
 #include <stdbool.h>
 #include <linux/types.h>
+#include <linux/bitops.h>
 #include "map.h"
 #include "build-id.h"
 
@@ -50,6 +51,13 @@ enum dso_data_status_seen {
        DSO_DATA_STATUS_SEEN_ITRACE,
 };
 
+enum dso_type {
+       DSO__TYPE_UNKNOWN,
+       DSO__TYPE_64BIT,
+       DSO__TYPE_32BIT,
+       DSO__TYPE_X32BIT,
+};
+
 #define DSO__SWAP(dso, type, val)                      \
 ({                                                     \
        type ____r = val;                               \
@@ -245,4 +253,6 @@ static inline bool dso__is_kcore(struct dso *dso)
 
 void dso__free_a2l(struct dso *dso);
 
+enum dso_type dso__type(struct dso *dso, struct machine *machine);
+
 #endif /* __PERF_DSO */
index 61b9cd4..d753499 100644 (file)
@@ -1028,6 +1028,39 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
        return err;
 }
 
+enum dso_type dso__type_fd(int fd)
+{
+       enum dso_type dso_type = DSO__TYPE_UNKNOWN;
+       GElf_Ehdr ehdr;
+       Elf_Kind ek;
+       Elf *elf;
+
+       elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+       if (elf == NULL)
+               goto out;
+
+       ek = elf_kind(elf);
+       if (ek != ELF_K_ELF)
+               goto out_end;
+
+       if (gelf_getclass(elf) == ELFCLASS64) {
+               dso_type = DSO__TYPE_64BIT;
+               goto out_end;
+       }
+
+       if (gelf_getehdr(elf, &ehdr) == NULL)
+               goto out_end;
+
+       if (ehdr.e_machine == EM_X86_64)
+               dso_type = DSO__TYPE_X32BIT;
+       else
+               dso_type = DSO__TYPE_32BIT;
+out_end:
+       elf_end(elf);
+out:
+       return dso_type;
+}
+
 static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)
 {
        ssize_t r;
index 101f55d..c9541fe 100644 (file)
@@ -305,6 +305,27 @@ static int fd__is_64_bit(int fd)
        return e_ident[EI_CLASS] == ELFCLASS64;
 }
 
+enum dso_type dso__type_fd(int fd)
+{
+       Elf64_Ehdr ehdr;
+       int ret;
+
+       ret = fd__is_64_bit(fd);
+       if (ret < 0)
+               return DSO__TYPE_UNKNOWN;
+
+       if (ret)
+               return DSO__TYPE_64BIT;
+
+       if (readn(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
+               return DSO__TYPE_UNKNOWN;
+
+       if (ehdr.e_machine == EM_X86_64)
+               return DSO__TYPE_X32BIT;
+
+       return DSO__TYPE_32BIT;
+}
+
 int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
                  struct symsrc *ss,
                  struct symsrc *runtime_ss __maybe_unused,
index ee2d3cc..e7295e9 100644 (file)
@@ -243,6 +243,8 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
 struct symbol *dso__next_symbol(struct symbol *sym);
 
+enum dso_type dso__type_fd(int fd);
+
 int filename__read_build_id(const char *filename, void *bf, size_t size);
 int sysfs__read_build_id(const char *filename, void *bf, size_t size);
 int modules__parse(const char *filename, void *arg,