gdb/gdb-6.3-ia64-sigtramp-fp-20050926.patch
Jan Kratochvil e5611bfae3 - Upgrade to the FSF GDB gdb-6.8.50 snapshot: 6.8.50.20090803
- archer-jankratochvil-fedora12 commit:
    0222cb1f4ddd1eda32965e464cb60b1e44e110b2
2009-08-04 05:37:29 +00:00

164 lines
6.3 KiB
Diff

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