aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/unwind-libunwind.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-01-28 15:30:32 +0100
committerIngo Molnar <mingo@kernel.org>2015-01-28 15:30:32 +0100
commit41ca5d4e9be11ea6ae040b51d9628a189fd82896 (patch)
treef9c35cc37b9622f6cccd91b94548f44b9a534029 /tools/perf/util/unwind-libunwind.c
parentx86_64 entry: Fix RCX for ptraced syscalls (diff)
parentx86, tls: Interpret an all-zero struct user_desc as "no segment" (diff)
downloadlinux-dev-41ca5d4e9be11ea6ae040b51d9628a189fd82896.tar.xz
linux-dev-41ca5d4e9be11ea6ae040b51d9628a189fd82896.zip
Merge commit 3669ef9fa7d3 ("x86, tls: Interpret an all-zero struct user_desc as 'no segment'") into x86/asm
Pick up the latestest asm fixes before advancing it any further. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/unwind-libunwind.c')
-rw-r--r--tools/perf/util/unwind-libunwind.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 371219a6daf1..6edf535f65c2 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -185,6 +185,28 @@ static u64 elf_section_offset(int fd, const char *name)
return offset;
}
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+static int elf_is_exec(int fd, const char *name)
+{
+ Elf *elf;
+ GElf_Ehdr ehdr;
+ int retval = 0;
+
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+ if (elf == NULL)
+ return 0;
+ if (gelf_getehdr(elf, &ehdr) == NULL)
+ goto out;
+
+ retval = (ehdr.e_type == ET_EXEC);
+
+out:
+ elf_end(elf);
+ pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
+ return retval;
+}
+#endif
+
struct table_entry {
u32 start_ip_offset;
u32 fde_offset;
@@ -322,8 +344,12 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
#ifndef NO_LIBUNWIND_DEBUG_FRAME
/* Check the .debug_frame section for unwinding info */
if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+ int fd = dso__data_fd(map->dso, ui->machine);
+ int is_exec = elf_is_exec(fd, map->dso->name);
+ unw_word_t base = is_exec ? 0 : map->start;
+
memset(&di, 0, sizeof(di));
- if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
+ if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name,
map->start, map->end))
return dwarf_search_unwind_table(as, ip, &di, pi,
need_unwind_info, arg);