libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH 6/6] Add .debug_frame based remote unwinding su


From: anderson . lizardo
Subject: [Libunwind-devel] [PATCH 6/6] Add .debug_frame based remote unwinding support
Date: Thu, 17 Jul 2008 10:23:28 -0300
User-agent: quilt/0.46-1

Add support for .debug_frame based unwinding in _UPTi_find_unwind_table().
Tested on ARM and x86 only. IA64 is not supported.

Signed-off-by: Anderson Lizardo <address@hidden>
Signed-off-by: Bruna Moreira <address@hidden>
---
 include/libunwind-common.h.in    |    2 ++
 src/dwarf/Gfind_proc_info-lsb.c  |   13 ++++++-------
 src/dwarf/Gparser.c              |    8 ++++++++
 src/ptrace/_UPT_find_proc_info.c |   26 +++++++++++++++++++++++++-
 4 files changed, 41 insertions(+), 8 deletions(-)

Index: libunwind-0.99+git20080710/src/dwarf/Gparser.c
===================================================================
--- libunwind-0.99+git20080710.orig/src/dwarf/Gparser.c
+++ libunwind-0.99+git20080710/src/dwarf/Gparser.c
@@ -73,6 +73,14 @@
 
   as = c->as;
   arg = c->as_arg;
+#ifndef UNW_TARGET_IA64
+  if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME)
+    {
+      /* .debug_frame CFI is stored in local address space.  */
+      as = unw_local_addr_space;
+      arg = NULL;
+    }
+#endif
   a = unw_get_accessors (as);
   curr_ip = c->pi.start_ip;
 
Index: libunwind-0.99+git20080710/src/ptrace/_UPT_find_proc_info.c
===================================================================
--- libunwind-0.99+git20080710.orig/src/ptrace/_UPT_find_proc_info.c
+++ libunwind-0.99+git20080710/src/ptrace/_UPT_find_proc_info.c
@@ -207,7 +207,31 @@
        }
     }
   if (!ptxt || !peh_hdr)
-    return NULL;
+    {
+      /* No .eh_frame found, try .debug_frame. */
+      struct dl_phdr_info info;
+
+      info.dlpi_name = path;
+      info.dlpi_phdr = phdr;
+      info.dlpi_phnum = ehdr->e_phnum;
+
+      /* Fixup segbase to match correct base address. */
+      for (i = 0; i < info.dlpi_phnum; i++)
+       {
+         if (info.dlpi_phdr[i].p_type == PT_LOAD &&
+           info.dlpi_phdr[i].p_offset == 0)
+           {
+             segbase -= info.dlpi_phdr[i].p_vaddr;
+             break;
+           }
+       }
+      info.dlpi_addr = segbase;
+
+      if (dwarf_find_debug_frame (0, &ui->di_cache, &info, ip))
+       return &ui->di_cache;
+      else
+       return NULL;
+    }
 
   if (pdyn)
     {
Index: libunwind-0.99+git20080710/include/libunwind-common.h.in
===================================================================
--- libunwind-0.99+git20080710.orig/include/libunwind-common.h.in
+++ libunwind-0.99+git20080710/include/libunwind-common.h.in
@@ -119,6 +119,8 @@
 /* Each target may define it's own set of flags, but bits 0-15 are
    reserved for general libunwind-use.  */
 #define UNW_PI_FLAG_FIRST_TDEP_BIT     16
+/* The information comes from a .debug_frame section.  */
+#define UNW_PI_FLAG_DEBUG_FRAME                32
 
 typedef struct unw_proc_info
   {
Index: libunwind-0.99+git20080710/src/dwarf/Gfind_proc_info-lsb.c
===================================================================
--- libunwind-0.99+git20080710.orig/src/dwarf/Gfind_proc_info-lsb.c
+++ libunwind-0.99+git20080710/src/dwarf/Gfind_proc_info-lsb.c
@@ -877,13 +877,11 @@
 #ifndef UNW_REMOTE_ONLY
       struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data;
 
-      /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is currently only
-        supported for the local address space.  Both the index and
-        the unwind tables live in local memory, but the address space
-        to check for properties like the address size and endianness
-        is the target one.  When the ptrace code adds support for
-        .debug_frame something will have to change.  */
-      assert (as == unw_local_addr_space);
+      /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address
+         space.  Both the index and the unwind tables live in local memory, but
+         the address space to check for properties like the address size and
+         endianness is the target one.  */
+      as = unw_local_addr_space;
       table = fdesc->index;
       table_len = fdesc->index_size * sizeof (struct table_entry);
       debug_frame_base = (uintptr_t) fdesc->debug_frame;
@@ -940,6 +938,7 @@
     {
       pi->start_ip += segbase;
       pi->end_ip += segbase;
+      pi->flags = UNW_PI_FLAG_DEBUG_FRAME;
     }
 
   if (ip < pi->start_ip || ip >= pi->end_ip)

-- 
Anderson Lizardo
Instituto Nokia de Tecnologia (INdT)
Manaus - Brazil




reply via email to

[Prev in Thread] Current Thread [Next in Thread]