078093a
2005-09-27  Jeff Johnston  <jjohnstn@redhat.com>
078093a
078093a
	* libunwind-frame.c (libunwind_frame_cache): Save the current
078093a
	stack pointer in the cache.
078093a
	(libunwind_sigtramp_frame_this_id): New function.
078093a
	(libunwind_sigtramp_frame_unwind): New unwinder.
078093a
	(libunwind_sigtramp_frame_sniffer): Return 
078093a
	libunwind_sigtramp_frame_unwind address.
078093a
	* libunwind-frame.h (libunwind_sigtramp_frame_this_id): New
078093a
	prototype.
078093a
	* ia64-tdep.c (ia64_libunwind_sigtramp_frame_this_id): Calculate
078093a
	the base address using the current stack pointer plus a fixed
078093a
	offset.
eb9d945
eb9d945
2007-10-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
eb9d945
eb9d945
	Port to GDB-6.7.
eb9d945
25ff8a1
2008-02-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
25ff8a1
25ff8a1
	Port to GDB-6.8pre.
25ff8a1
7db944e
2008-04-16  Yi Zhan  <yi.zhan@intel.com>
7db944e
7db944e
	Fix a compilation error on a typo.
7db944e
e5611bf
Index: gdb-6.8.50.20090803/gdb/libunwind-frame.c
9231e41
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/libunwind-frame.c	2009-01-03 06:57:52.000000000 +0100
e5611bf
+++ gdb-6.8.50.20090803/gdb/libunwind-frame.c	2009-08-04 06:31:34.000000000 +0200
e5611bf
@@ -62,6 +62,7 @@ static unw_word_t (*unw_find_dyn_list_p)
078093a
 struct libunwind_frame_cache
078093a
 {
078093a
   CORE_ADDR base;
078093a
+  CORE_ADDR sp;
078093a
   CORE_ADDR func_addr;
078093a
   unw_cursor_t cursor;
eb9d945
   unw_addr_space_t as;
e5611bf
@@ -134,6 +135,7 @@ libunwind_frame_cache (struct frame_info
078093a
   unw_accessors_t *acc;
078093a
   unw_addr_space_t as;
25ff8a1
   unw_word_t fp;
7db944e
+  unw_word_t sp;
078093a
   unw_regnum_t uw_sp_regnum;
078093a
   struct libunwind_frame_cache *cache;
078093a
   struct libunwind_descr *descr;
e5611bf
@@ -175,14 +177,30 @@ libunwind_frame_cache (struct frame_info
25ff8a1
 				 : __LITTLE_ENDIAN);
078093a
 
407ebe9
   unw_init_remote_p (&cache->cursor, as, this_frame);
25ff8a1
+
078093a
+  /* For the base address, we have a small problem.  The majority
078093a
+     of the time, we can get the stack pointer of the previous
078093a
+     frame to use as a frame pointer.  In the case where we have
078093a
+     a signal trampoline, the stack may change due to a sigaltstack
078093a
+     being set up.  In that case, the normal mechanism will give us
078093a
+     an address in the regular stack which is not at the end of the
078093a
+     sigaltstack as we want.  To handle this, we record the stack
078093a
+     address so the caller may calculate a more correct base address
078093a
+     to use.  */
25ff8a1
+  uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
078093a
+  ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &sp);
078093a
+  if (ret < 0)
eb9d945
+    {
eb9d945
+      unw_destroy_addr_space_p (as);
eb9d945
+      error (_("Can't get libunwind sp register."));
eb9d945
+    }
078093a
+
078093a
   if (unw_step_p (&cache->cursor) < 0)
eb9d945
     {
eb9d945
       unw_destroy_addr_space_p (as);
eb9d945
       return NULL;
eb9d945
     }
078093a
 
078093a
-  /* To get base address, get sp from previous frame.  */
25ff8a1
-  uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
078093a
   ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
078093a
   if (ret < 0)
eb9d945
     {
e5611bf
@@ -190,6 +208,7 @@ libunwind_frame_cache (struct frame_info
eb9d945
       error (_("Can't get libunwind sp register."));
eb9d945
     }
078093a
 
078093a
+  cache->sp = (CORE_ADDR)sp;
078093a
   cache->base = (CORE_ADDR)fp;
eb9d945
   cache->as = as;
078093a
 
e5611bf
@@ -377,6 +396,31 @@ libunwind_search_unwind_table (void *as,
078093a
 				    di, pi, need_unwind_info, args);
078093a
 }
078093a
 
078093a
+void
407ebe9
+libunwind_sigtramp_frame_this_id (struct frame_info *this_frame, 
078093a
+				  void **this_cache,
078093a
+		      		  struct frame_id *this_id)
078093a
+{
078093a
+  struct libunwind_frame_cache *cache =
407ebe9
+    libunwind_frame_cache (this_frame, this_cache);
078093a
+
078093a
+  /* Unlike a regular frame, we can't use the normal frame pointer
078093a
+     mechanism because a sigaltstack may have been used.  Instead,
078093a
+     we return the current stack pointer for the caller to use
078093a
+     to calculate the base address.  */
078093a
+  if (cache != NULL)
078093a
+    (*this_id) = frame_id_build (cache->sp, cache->func_addr);
078093a
+  else
078093a
+    (*this_id) = null_frame_id;
078093a
+}
078093a
+
078093a
+static const struct frame_unwind libunwind_sigtramp_frame_unwind =
078093a
+{
078093a
+  SIGTRAMP_FRAME,
078093a
+  libunwind_sigtramp_frame_this_id,
078093a
+  libunwind_frame_prev_register
078093a
+};
078093a
+
078093a
 /* Verify if we are in a sigtramp frame and we can use libunwind to unwind.  */
407ebe9
 int
407ebe9
 libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
e5611bf
Index: gdb-6.8.50.20090803/gdb/libunwind-frame.h
9231e41
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/libunwind-frame.h	2009-01-03 06:57:52.000000000 +0100
e5611bf
+++ gdb-6.8.50.20090803/gdb/libunwind-frame.h	2009-08-04 06:31:34.000000000 +0200
407ebe9
@@ -52,6 +52,9 @@ void libunwind_frame_set_descr (struct g
078093a
 
407ebe9
 void libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
078093a
 			      struct frame_id *this_id);
407ebe9
+void libunwind_sigtramp_frame_this_id (struct frame_info *this_frame, 
078093a
+				       void **this_cache,
078093a
+			      	       struct frame_id *this_id);
407ebe9
 struct value *libunwind_frame_prev_register (struct frame_info *this_frame,
407ebe9
                                              void **this_cache, int regnum);
407ebe9
 void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
e5611bf
Index: gdb-6.8.50.20090803/gdb/ia64-tdep.c
9231e41
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/ia64-tdep.c	2009-08-04 06:30:45.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/ia64-tdep.c	2009-08-04 06:31:34.000000000 +0200
e5611bf
@@ -3023,7 +3023,7 @@ ia64_libunwind_sigtramp_frame_this_id (s
078093a
   struct frame_id id;
078093a
   CORE_ADDR prev_ip;
078093a
 
407ebe9
-  libunwind_frame_this_id (this_frame, this_cache, &id;;
407ebe9
+  libunwind_sigtramp_frame_this_id (this_frame, this_cache, &id;;
078093a
   if (frame_id_eq (id, null_frame_id))
078093a
     {
078093a
       (*this_id) = null_frame_id;
e5611bf
@@ -3035,8 +3035,14 @@ ia64_libunwind_sigtramp_frame_this_id (s
407ebe9
   get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
e5611bf
   bsp = extract_unsigned_integer (buf, 8, byte_order);
078093a
 
078093a
-  /* For a sigtramp frame, we don't make the check for previous ip being 0.  */
078093a
-  (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
078093a
+  /* For a sigtramp frame, we don't make the check for previous ip being 0.  
078093a
+     We also must calculate the frame pointer because libunwind will give
078093a
+     us back the current stack pointer instead of the frame pointer since
078093a
+     it cannot figure this out when in a sigaltstack.  We make a basic
078093a
+     assumption of 16 (default size) + 8 bytes for sigcontext address.
078093a
+     FIXME: if libunwind were to export the frame pointer address, we
078093a
+            could eliminate the assumption and get the actual value.  */
078093a
+  (*this_id) = frame_id_build_special (id.stack_addr + 24, id.code_addr, bsp);
078093a
 
078093a
   if (gdbarch_debug >= 1)
078093a
     fprintf_unfiltered (gdb_stdlog,