aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/unwind-libunwind.c
diff options
context:
space:
mode:
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)
185 return offset; 185 return offset;
186} 186}
187 187
188#ifndef NO_LIBUNWIND_DEBUG_FRAME
189static int elf_is_exec(int fd, const char *name)
190{
191 Elf *elf;
192 GElf_Ehdr ehdr;
193 int retval = 0;
194
195 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
196 if (elf == NULL)
197 return 0;
198 if (gelf_getehdr(elf, &ehdr) == NULL)
199 goto out;
200
201 retval = (ehdr.e_type == ET_EXEC);
202
203out:
204 elf_end(elf);
205 pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
206 return retval;
207}
208#endif
209
188struct table_entry { 210struct table_entry {
189 u32 start_ip_offset; 211 u32 start_ip_offset;
190 u32 fde_offset; 212 u32 fde_offset;
@@ -322,8 +344,12 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
322#ifndef NO_LIBUNWIND_DEBUG_FRAME 344#ifndef NO_LIBUNWIND_DEBUG_FRAME
323 /* Check the .debug_frame section for unwinding info */ 345 /* Check the .debug_frame section for unwinding info */
324 if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { 346 if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
347 int fd = dso__data_fd(map->dso, ui->machine);
348 int is_exec = elf_is_exec(fd, map->dso->name);
349 unw_word_t base = is_exec ? 0 : map->start;
350
325 memset(&di, 0, sizeof(di)); 351 memset(&di, 0, sizeof(di));
326 if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, 352 if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name,
327 map->start, map->end)) 353 map->start, map->end))
328 return dwarf_search_unwind_table(as, ip, &di, pi, 354 return dwarf_search_unwind_table(as, ip, &di, pi,
329 need_unwind_info, arg); 355 need_unwind_info, arg);