1 2005-09-27 Jeff Johnston <jjohnstn@redhat.com>
3 * libunwind-frame.c (libunwind_frame_cache): Save the current
4 stack pointer in the cache.
5 (libunwind_sigtramp_frame_this_id): New function.
6 (libunwind_sigtramp_frame_unwind): New unwinder.
7 (libunwind_sigtramp_frame_sniffer): Return
8 libunwind_sigtramp_frame_unwind address.
9 * libunwind-frame.h (libunwind_sigtramp_frame_this_id): New
11 * ia64-tdep.c (ia64_libunwind_sigtramp_frame_this_id): Calculate
12 the base address using the current stack pointer plus a fixed
15 2007-10-14 Jan Kratochvil <jan.kratochvil@redhat.com>
19 2008-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>
23 2008-04-16 Yi Zhan <yi.zhan@intel.com>
25 Fix a compilation error on a typo.
27 Index: gdb-6.8.50.20081128/gdb/libunwind-frame.c
28 ===================================================================
29 --- gdb-6.8.50.20081128.orig/gdb/libunwind-frame.c 2008-05-06 20:37:46.000000000 +0200
30 +++ gdb-6.8.50.20081128/gdb/libunwind-frame.c 2008-12-02 19:46:26.000000000 +0100
31 @@ -61,6 +61,7 @@ static unw_word_t (*unw_find_dyn_list_p)
32 struct libunwind_frame_cache
39 @@ -133,6 +134,7 @@ libunwind_frame_cache (struct frame_info
44 unw_regnum_t uw_sp_regnum;
45 struct libunwind_frame_cache *cache;
46 struct libunwind_descr *descr;
47 @@ -174,14 +176,30 @@ libunwind_frame_cache (struct frame_info
50 unw_init_remote_p (&cache->cursor, as, this_frame);
52 + /* For the base address, we have a small problem. The majority
53 + of the time, we can get the stack pointer of the previous
54 + frame to use as a frame pointer. In the case where we have
55 + a signal trampoline, the stack may change due to a sigaltstack
56 + being set up. In that case, the normal mechanism will give us
57 + an address in the regular stack which is not at the end of the
58 + sigaltstack as we want. To handle this, we record the stack
59 + address so the caller may calculate a more correct base address
61 + uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
62 + ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &sp);
65 + unw_destroy_addr_space_p (as);
66 + error (_("Can't get libunwind sp register."));
69 if (unw_step_p (&cache->cursor) < 0)
71 unw_destroy_addr_space_p (as);
75 - /* To get base address, get sp from previous frame. */
76 - uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
77 ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
80 @@ -189,6 +207,7 @@ libunwind_frame_cache (struct frame_info
81 error (_("Can't get libunwind sp register."));
84 + cache->sp = (CORE_ADDR)sp;
85 cache->base = (CORE_ADDR)fp;
88 @@ -376,6 +395,31 @@ libunwind_search_unwind_table (void *as,
89 di, pi, need_unwind_info, args);
93 +libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
95 + struct frame_id *this_id)
97 + struct libunwind_frame_cache *cache =
98 + libunwind_frame_cache (this_frame, this_cache);
100 + /* Unlike a regular frame, we can't use the normal frame pointer
101 + mechanism because a sigaltstack may have been used. Instead,
102 + we return the current stack pointer for the caller to use
103 + to calculate the base address. */
105 + (*this_id) = frame_id_build (cache->sp, cache->func_addr);
107 + (*this_id) = null_frame_id;
110 +static const struct frame_unwind libunwind_sigtramp_frame_unwind =
113 + libunwind_sigtramp_frame_this_id,
114 + libunwind_frame_prev_register
117 /* Verify if we are in a sigtramp frame and we can use libunwind to unwind. */
119 libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
120 Index: gdb-6.8.50.20081128/gdb/libunwind-frame.h
121 ===================================================================
122 --- gdb-6.8.50.20081128.orig/gdb/libunwind-frame.h 2008-05-06 20:37:46.000000000 +0200
123 +++ gdb-6.8.50.20081128/gdb/libunwind-frame.h 2008-12-02 19:38:55.000000000 +0100
124 @@ -52,6 +52,9 @@ void libunwind_frame_set_descr (struct g
126 void libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
127 struct frame_id *this_id);
128 +void libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
130 + struct frame_id *this_id);
131 struct value *libunwind_frame_prev_register (struct frame_info *this_frame,
132 void **this_cache, int regnum);
133 void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
134 Index: gdb-6.8.50.20081128/gdb/ia64-tdep.c
135 ===================================================================
136 --- gdb-6.8.50.20081128.orig/gdb/ia64-tdep.c 2008-12-02 19:04:32.000000000 +0100
137 +++ gdb-6.8.50.20081128/gdb/ia64-tdep.c 2008-12-02 21:09:46.000000000 +0100
138 @@ -2964,7 +2964,7 @@ ia64_libunwind_sigtramp_frame_this_id (s
142 - libunwind_frame_this_id (this_frame, this_cache, &id);
143 + libunwind_sigtramp_frame_this_id (this_frame, this_cache, &id);
144 if (frame_id_eq (id, null_frame_id))
146 (*this_id) = null_frame_id;
147 @@ -2976,8 +2976,14 @@ ia64_libunwind_sigtramp_frame_this_id (s
148 get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
149 bsp = extract_unsigned_integer (buf, 8);
151 - /* For a sigtramp frame, we don't make the check for previous ip being 0. */
152 - (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
153 + /* For a sigtramp frame, we don't make the check for previous ip being 0.
154 + We also must calculate the frame pointer because libunwind will give
155 + us back the current stack pointer instead of the frame pointer since
156 + it cannot figure this out when in a sigaltstack. We make a basic
157 + assumption of 16 (default size) + 8 bytes for sigcontext address.
158 + FIXME: if libunwind were to export the frame pointer address, we
159 + could eliminate the assumption and get the actual value. */
160 + (*this_id) = frame_id_build_special (id.stack_addr + 24, id.code_addr, bsp);
162 if (gdbarch_debug >= 1)
163 fprintf_unfiltered (gdb_stdlog,