libunwind-devel
[Top][All Lists]
Advanced

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

[Libunwind-devel] [PATCH 5/6] Factor out and export dwarf_find_debug_fra


From: anderson . lizardo
Subject: [Libunwind-devel] [PATCH 5/6] Factor out and export dwarf_find_debug_frame() function
Date: Thu, 17 Jul 2008 10:23:27 -0300
User-agent: quilt/0.46-1

Much of the .debug_frame processing work can be shared between local/remote
backtracing. This patch factors out the common functionality into a new
dwarf_find_debug_frame() that is called from _UPTi_find_unwind_table().

Signed-off-by: Anderson Lizardo <address@hidden>
Signed-off-by: Bruna Moreira <address@hidden>
---
 include/dwarf.h                 |    4 
 src/dwarf/Gfind_proc_info-lsb.c |  280 +++++++++++++++++++++-------------------
 2 files changed, 151 insertions(+), 133 deletions(-)

Index: libunwind-indt-split-v2/include/dwarf.h
===================================================================
--- libunwind-indt-split-v2.orig/include/dwarf.h
+++ libunwind-indt-split-v2/include/dwarf.h
@@ -39,6 +39,7 @@
 struct dwarf_cursor;   /* forward-declaration */
 
 #include "dwarf-config.h"
+#include <link.h>
 
 /* DWARF expression opcodes.  */
 
@@ -349,6 +350,7 @@
 /* Convenience macros: */
 #define dwarf_init                     UNW_ARCH_OBJ (dwarf_init)
 #define dwarf_find_proc_info           UNW_OBJ (dwarf_find_proc_info)
+#define dwarf_find_debug_frame         UNW_OBJ (dwarf_find_debug_frame)
 #define dwarf_search_unwind_table      UNW_OBJ (dwarf_search_unwind_table)
 #define dwarf_put_unwind_info          UNW_OBJ (dwarf_put_unwind_info)
 #define dwarf_put_unwind_info          UNW_OBJ (dwarf_put_unwind_info)
@@ -365,6 +367,8 @@
 extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
                                 unw_proc_info_t *pi,
                                 int need_unwind_info, void *arg);
+extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
+                               struct dl_phdr_info *info, unw_word_t ip);
 extern int dwarf_search_unwind_table (unw_addr_space_t as,
                                      unw_word_t ip,
                                      unw_dyn_info_t *di,
Index: libunwind-indt-split-v2/src/dwarf/Gfind_proc_info-lsb.c
===================================================================
--- libunwind-indt-split-v2.orig/src/dwarf/Gfind_proc_info-lsb.c
+++ libunwind-indt-split-v2/src/dwarf/Gfind_proc_info-lsb.c
@@ -407,6 +407,152 @@
     return 0;
 }
 
+PROTECTED int
+dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
+                       struct dl_phdr_info *info, unw_word_t ip)
+{
+  unw_dyn_info_t *di;
+  struct unw_debug_frame_list *fdesc = 0;
+  unw_accessors_t *a;
+  unw_word_t addr;
+
+  Debug (15, "Trying to find .debug_frame info->dlpi_name=%s\n",
+        info->dlpi_name);
+  di = di_debug;
+
+  fdesc = locate_debug_info (unw_local_addr_space, info, ip, info->dlpi_name);
+
+  if (!fdesc)
+    {
+      Debug (15, "couldn't load .debug_frame\n");
+      return found;
+    }
+  else
+    {
+      char *buf;
+      size_t bufsize;
+      unw_word_t item_start, item_end = 0;
+      uint32_t u32val = 0;
+      uint64_t cie_id = 0;
+      struct debug_frame_tab *tab;
+
+      Debug (15, "loaded .debug_frame\n");
+
+      buf = fdesc->debug_frame;
+      bufsize = fdesc->debug_frame_size;
+
+      if (bufsize == 0)
+       {
+         Debug (15, "zero-length .debug_frame\n");
+         return found;
+       }
+
+      /* Now create a binary-search table, if it does not already exist.  */
+      if (!fdesc->index)
+       {
+         addr = (unw_word_t) (uintptr_t) buf;
+
+         a = unw_get_accessors (unw_local_addr_space);
+
+         /* Find all FDE entries in debug_frame, and make into a sorted
+            index.  */
+
+         tab = debug_frame_tab_new (16);
+
+         while (addr < (unw_word_t) (uintptr_t) (buf + bufsize))
+           {
+             uint64_t id_for_cie;
+             item_start = addr;
+
+             dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL);
+
+             if (u32val == 0)
+               break;
+             else if (u32val != 0xffffffff)
+               {
+                 uint32_t cie_id32 = 0;
+                 item_end = addr + u32val;
+                 dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32,
+                                NULL);
+                 cie_id = cie_id32;
+                 id_for_cie = 0xffffffff;
+               }
+             else
+               {
+                 uint64_t u64val = 0;
+                 /* Extended length.  */
+                 dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL);
+                 item_end = addr + u64val;
+
+                 dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL);
+                 id_for_cie = 0xffffffffffffffffull;
+               }
+
+             /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/
+
+             if (cie_id == id_for_cie)
+               ;
+             /*Debug (1, "Found CIE at %.8x.\n", item_start);*/
+             else
+               {
+                 unw_word_t fde_addr = item_start;
+                 unw_proc_info_t this_pi;
+                 int err;
+
+                 /*Debug (1, "Found FDE at %.8x\n", item_start);*/
+
+                 err = dwarf_extract_proc_info_from_fde (unw_local_addr_space,
+                                                         a, &fde_addr,
+                                                         &this_pi, 0,
+                                                         (uintptr_t) buf,
+                                                         NULL);
+                 if (err == 0)
+                   {
+                     Debug (15, "start_ip = %x, end_ip = %x\n",
+                            (int) this_pi.start_ip, (int) this_pi.end_ip);
+                     debug_frame_tab_append (tab,
+                                             item_start - (unw_word_t) 
(uintptr_t) buf,
+                                             this_pi.start_ip);
+                   }
+                 /*else
+                   Debug (1, "FDE parse failed\n");*/
+               }
+
+             addr = item_end;
+           }
+
+         debug_frame_tab_shrink (tab);
+         qsort (tab->tab, tab->length, sizeof (struct table_entry),
+                debug_frame_tab_compare);
+         /* for (i = 0; i < tab->length; i++)
+            {
+            fprintf (stderr, "ip %x, fde offset %x\n",
+            (int) tab->tab[i].start_ip_offset,
+            (int) tab->tab[i].fde_offset);
+            }*/
+         fdesc->index = tab->tab;
+         fdesc->index_size = tab->length;
+         free (tab);
+       }
+
+      di->format = UNW_INFO_FORMAT_TABLE;
+      di->start_ip = fdesc->start;
+      di->end_ip = fdesc->end;
+      di->u.ti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name;
+      di->u.ti.table_data = (unw_word_t *) fdesc;
+      di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t);
+      di->u.ti.segbase = (unw_word_t) (uintptr_t) info->dlpi_addr;
+
+      found = 1;
+      Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, "
+            "gp=0x%lx, table_data=0x%lx\n",
+            (char *) (uintptr_t) di->u.ti.name_ptr,
+            (long) di->u.ti.segbase, (long) di->u.ti.table_len,
+            (long) di->gp, (long) di->u.ti.table_data);
+    }
+  return found;
+}
+
 /* ptr is a pointer to a callback_data structure and, on entry,
    member ip contains the instruction-pointer we're looking
    for.  */
@@ -423,7 +569,6 @@
   struct dwarf_eh_frame_hdr *hdr;
   unw_accessors_t *a;
   long n;
-  struct unw_debug_frame_list *fdesc = 0;
   int found = 0;
 
   ip = cb_data->ip;
@@ -582,138 +727,7 @@
        }
     }
 
-  Debug (15, "Trying to find .debug_frame\n");
-  di = &cb_data->di_debug;
-  fdesc = locate_debug_info (unw_local_addr_space, info, ip, info->dlpi_name);
-
-  if (!fdesc)
-    {
-      Debug (15, "couldn't load .debug_frame\n");
-      return found;
-    }
-  else
-    {
-      char *buf;
-      size_t bufsize;
-      unw_word_t item_start, item_end = 0;
-      uint32_t u32val = 0;
-      uint64_t cie_id = 0;
-      struct debug_frame_tab *tab;
-
-      Debug (15, "loaded .debug_frame\n");
-
-      buf = fdesc->debug_frame;
-      bufsize = fdesc->debug_frame_size;
-
-      if (bufsize == 0)
-       {
-         Debug (15, "zero-length .debug_frame\n");
-         return found;
-       }
-
-      /* Now create a binary-search table, if it does not already exist.  */
-      if (!fdesc->index)
-       {
-         addr = (unw_word_t) (uintptr_t) buf;
-
-         a = unw_get_accessors (unw_local_addr_space);
-
-         /* Find all FDE entries in debug_frame, and make into a sorted
-            index.  */
-
-         tab = debug_frame_tab_new (16);
-
-         while (addr < (unw_word_t) (uintptr_t) (buf + bufsize))
-           {
-             uint64_t id_for_cie;
-             item_start = addr;
-
-             dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL);
-
-             if (u32val == 0)
-               break;
-             else if (u32val != 0xffffffff)
-               {
-                 uint32_t cie_id32 = 0;
-                 item_end = addr + u32val;
-                 dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32,
-                                NULL);
-                 cie_id = cie_id32;
-                 id_for_cie = 0xffffffff;
-               }
-             else
-               {
-                 uint64_t u64val = 0;
-                 /* Extended length.  */
-                 dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL);
-                 item_end = addr + u64val;
-
-                 dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL);
-                 id_for_cie = 0xffffffffffffffffull;
-               }
-
-             /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/
-
-             if (cie_id == id_for_cie)
-               ;
-             /*Debug (1, "Found CIE at %.8x.\n", item_start);*/
-             else
-               {
-                 unw_word_t fde_addr = item_start;
-                 unw_proc_info_t this_pi;
-                 int err;
-
-                 /*Debug (1, "Found FDE at %.8x\n", item_start);*/
-
-                 err = dwarf_extract_proc_info_from_fde (unw_local_addr_space,
-                                                         a, &fde_addr,
-                                                         &this_pi, 0,
-                                                         (uintptr_t) buf,
-                                                         NULL);
-                 if (err == 0)
-                   {
-                     Debug (15, "start_ip = %x, end_ip = %x\n",
-                            (int) this_pi.start_ip, (int) this_pi.end_ip);
-                     debug_frame_tab_append (tab,
-                                             item_start - (unw_word_t) 
(uintptr_t) buf,
-                                             this_pi.start_ip);
-                   }
-                 /*else
-                   Debug (1, "FDE parse failed\n");*/
-               }
-
-             addr = item_end;
-           }
-
-         debug_frame_tab_shrink (tab);
-         qsort (tab->tab, tab->length, sizeof (struct table_entry),
-                debug_frame_tab_compare);
-         /* for (i = 0; i < tab->length; i++)
-            {
-            fprintf (stderr, "ip %x, fde offset %x\n",
-            (int) tab->tab[i].start_ip_offset,
-            (int) tab->tab[i].fde_offset);
-            }*/
-         fdesc->index = tab->tab;
-         fdesc->index_size = tab->length;
-         free (tab);
-       }
-
-      di->format = UNW_INFO_FORMAT_TABLE;
-      di->start_ip = fdesc->start;
-      di->end_ip = fdesc->end;
-      di->u.ti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name;
-      di->u.ti.table_data = (unw_word_t *) fdesc;
-      di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t);
-      di->u.ti.segbase = (unw_word_t) (uintptr_t) info->dlpi_addr;
-
-      found = 1;
-      Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, "
-            "gp=0x%lx, table_data=0x%lx\n",
-            (char *) (uintptr_t) di->u.ti.name_ptr,
-            (long) di->u.ti.segbase, (long) di->u.ti.table_len,
-            (long) di->gp, (long) di->u.ti.table_data);
-    }
+  found = dwarf_find_debug_frame (found, &cb_data->di_debug, info, ip);
 
   return found;
 }

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




reply via email to

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