This is the mail archive of the frysk@sourceware.org mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Use only eh_frame data for libunwind get_unwind_table


Hi,

We used to have a somewhat awkward get_unwind_table interface where we
passed both the (fake) address space of the unwind table as the original
vaddr of the table. This was necessary because eh_frames contain
pc-relative addresses, so libunwind wanted to get the original address.
This patch makes it so that the address space we pass to libunwind has
the correct relative addresses, so no extra arguments are necessary for
libunwind to adjust anything.

There is one local libunwind patch necessary for now to make this work.
That is to not directly read the the personality routine address from
the CIE since it can be stored anywhere and currently we are just
feeding it the unwind table data. We still need to read the encoded
pointer to get past it. This can be restored when frysk feeds the
eh_frame through its main address space. We never use the personality
routine inside Frysk at the moment.

frysk-imports/libunwind/ChangeLog
2007-12-22  Mark Wielaard  <mwielaard@redhat.com>
    
       * include/libunwind-common.h.in (unw_get_unwind_table):
       Remove as, arg and peh_vaddr arguments.
       * src/mi/Gget_unwind_table.c (unw_get_unwind_table): Likewise.
       Create address space from eh_frame_accessors. Set rti.table_data
       and rti.segbase from eh_frame_hdr_address. Pass eh_frame_arg
       to tdep_search_unwind_table.
       * src/dwarf/Gfde.c (parse_cie): Add FRYSK LOCAL hack to not
       read personality routine address.
    
frysk-sys/lib/unwind/ChangeLog
2007-12-22  Mark Wielaard  <mwielaard@redhat.com>
    
       * cni/UnwindH.hxx (get_eh_frame_hdr_addr): Return char*.
       (createProcInfoFromElfImage): Calculate virtual and adjusted
       addresses from eh_table_hdr and peh_vaddr.

Tested on x86 and x86_64.

Committed,

Mark
--- a/frysk-imports/libunwind/include/libunwind-common.h.in
+++ b/frysk-imports/libunwind/include/libunwind-common.h.in
@@ -250,12 +250,10 @@ extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
 extern int unw_is_signal_frame (unw_cursor_t *);
 extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
 extern const char *unw_strerror (int);
-extern int unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, 
+extern int unw_get_unwind_table(unw_word_t ip, 
 				unw_proc_info_t *pi, int need_unwind_info,
-				void *arg,
 				unw_accessors_t *eh_frame_accessors,
 				unw_word_t eh_frame_hdr_address,
-				void *eh_frame_arg,
-				unw_word_t peh_vaddr);
+				void *eh_frame_arg);
 
 extern unw_addr_space_t unw_local_addr_space;
diff --git a/frysk-imports/libunwind/src/dwarf/Gfde.c b/frysk-imports/libunwind/src/dwarf/Gfde.c
index d6b4987..11a6433 100644
--- a/frysk-imports/libunwind/src/dwarf/Gfde.c
+++ b/frysk-imports/libunwind/src/dwarf/Gfde.c
@@ -173,6 +173,15 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
 	/* read the personality-routine pointer-encoding format.  */
 	if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0)
 	  return ret;
+	// FRYSK LOCAL
+	// We never want to actually read the personality routine address
+	// since it can be stored anywhere and currently we are just
+	// feeding it the unwind table data. We still need to read the
+	// encoded pointer to get past it.
+	// Can be restored when frysk feeds the eh_frame through its
+	// main address space.
+	handler_encoding &= ~DW_EH_PE_indirect;
+	// END FRYSK LOCAL
 	if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding,
 					       pi, &dci->handler, arg)) < 0)
 	  return ret;
diff --git a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
index 1d905b6..fc46269 100644
--- a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
+++ b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
@@ -26,14 +26,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #include "dwarf-eh.h"
 
 int
-unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip,
-		     unw_proc_info_t *pi, int need_unwind_info, void *arg,
+unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
 		     unw_accessors_t *eh_frame_accessors,
 		     unw_word_t eh_frame_hdr_address,
-		     void *eh_frame_arg,
-		     unw_word_t peh_vaddr)
+		     void *eh_frame_arg)
 {
   int ret;
+  unw_addr_space_t as = unw_create_addr_space (eh_frame_accessors, 0);
   unw_word_t start = eh_frame_hdr_address;
 
   // Version
@@ -83,11 +82,12 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip,
   di.u.rti.name_ptr = 0;
   /* two 32-bit values (ip_offset/fde_offset) per table-entry:
      For the binary-search table in the eh_frame_hdr, data-relative
-     means relative to the start of that section...
-     So for now we pass in peh_vaddr and use the main as for access. */
+     means relative to the start of that section... */
   di.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);
-  di.u.rti.table_data = peh_vaddr + 12;
-  di.u.rti.segbase = peh_vaddr;
+  di.u.rti.table_data = eh_frame_hdr_address + 12;
+  di.u.rti.segbase = eh_frame_hdr_address;
 
-  return tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info, arg);
+  ret = tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info,
+				  eh_frame_arg);
+  return ret;
 }
diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx
index 7dbcf7b..e69e031 100644
--- a/frysk-sys/lib/unwind/cni/UnwindH.hxx
+++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx
@@ -446,7 +446,7 @@ lib::unwind::TARGET::getProcInfo(gnu::gcj::RawDataManaged* cursor)
 // Also fills in ip->start_ip, ip->end_ip and ip->gp.
 // peh_vaddr will point to the address of the eh_frame_hdr in the main
 // address space of the inferior.
-static void *
+static char *
 get_eh_frame_hdr_addr(unw_proc_info_t *pi, char *image, size_t size,
 		      unsigned long segbase, unw_word_t *peh_vaddr)
 {
@@ -582,12 +582,10 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre
   unw_proc_info_t *procInfo
     = (::unw_proc_info_t *) JvAllocBytes(sizeof (::unw_proc_info_t));
 
-  unw_addr_space_t as = (unw_addr_space_t) addressSpace->addressSpace;
-
   logFine(this, logger, "Pre unw_get_unwind_table");
   
   unw_word_t peh_vaddr = 0;
-  void *eh_table_hdr = get_eh_frame_hdr_addr(procInfo,
+  char *eh_table_hdr = get_eh_frame_hdr_addr(procInfo,
 					     (char *) elfImage->elfImage,
 					     elfImage->size,
 					     elfImage->segbase,
@@ -602,16 +600,14 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre
   if (eh_table_hdr == NULL)
     return new lib::unwind::ProcInfo(-UNW_ENOINFO);
 
-  int ret = unw_get_unwind_table(as,
-				 (unw_word_t) ip,
+  int ret = unw_get_unwind_table((unw_word_t) ip,
 				 procInfo,
 				 (int) needUnwindInfo,
-				 (void *) addressSpace,
 				 &local_accessors,
-				 0,
-				 eh_table_hdr,
-				 peh_vaddr);
-    
+				 // virtual address
+				 peh_vaddr,
+				 // address adjustment
+				 eh_table_hdr - peh_vaddr);
   
   logFine(this, logger, "Post unw_get_unwind_table");
   lib::unwind::ProcInfo *myInfo;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]