From 8e0cf965f95edd41df11cca50b92b4cb6ea8d80a Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 7 Aug 2013 14:38:51 +0300 Subject: perf symbols: Add support for reading from /proc/kcore In the absence of vmlinux, perf tools uses kallsyms for symbols. If the user has access, now also map to /proc/kcore. The dso data_type is now set to either DSO_BINARY_TYPE__KCORE or DSO_BINARY_TYPE__GUEST_KCORE as approprite. This patch breaks the "vmlinux symtab matches kallsyms" test. That is fixed in a following patch. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375875537-4509-8-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'tools/perf/util/symbol-elf.c') diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 3eaa7b486e2e..a7b9ab557380 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -951,6 +951,57 @@ out_elf_end: return err; } +static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data) +{ + GElf_Phdr phdr; + size_t i, phdrnum; + int err; + u64 sz; + + if (elf_getphdrnum(elf, &phdrnum)) + return -1; + + for (i = 0; i < phdrnum; i++) { + if (gelf_getphdr(elf, i, &phdr) == NULL) + return -1; + if (phdr.p_type != PT_LOAD) + continue; + if (exe) { + if (!(phdr.p_flags & PF_X)) + continue; + } else { + if (!(phdr.p_flags & PF_R)) + continue; + } + sz = min(phdr.p_memsz, phdr.p_filesz); + if (!sz) + continue; + err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data); + if (err) + return err; + } + return 0; +} + +int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, + bool *is_64_bit) +{ + int err; + Elf *elf; + + elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + if (elf == NULL) + return -1; + + if (is_64_bit) + *is_64_bit = (gelf_getclass(elf) == ELFCLASS64); + + err = elf_read_maps(elf, exe, mapfn, data); + + elf_end(elf); + return err; +} + void symbol__elf_init(void) { elf_version(EV_CURRENT); -- cgit v1.2.3