]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | 2005-09-27 Jeff Johnston <jjohnstn@redhat.com> |
2 | ||
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 | |
10 | prototype. | |
11 | * ia64-tdep.c (ia64_libunwind_sigtramp_frame_this_id): Calculate | |
12 | the base address using the current stack pointer plus a fixed | |
13 | offset. | |
14 | ||
15 | 2007-10-14 Jan Kratochvil <jan.kratochvil@redhat.com> | |
16 | ||
17 | Port to GDB-6.7. | |
18 | ||
19 | 2008-02-24 Jan Kratochvil <jan.kratochvil@redhat.com> | |
20 | ||
21 | Port to GDB-6.8pre. | |
22 | ||
23 | 2008-04-16 Yi Zhan <yi.zhan@intel.com> | |
24 | ||
25 | Fix a compilation error on a typo. | |
26 | ||
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 | |
33 | { | |
34 | CORE_ADDR base; | |
35 | + CORE_ADDR sp; | |
36 | CORE_ADDR func_addr; | |
37 | unw_cursor_t cursor; | |
38 | unw_addr_space_t as; | |
39 | @@ -133,6 +134,7 @@ libunwind_frame_cache (struct frame_info | |
40 | unw_accessors_t *acc; | |
41 | unw_addr_space_t as; | |
42 | unw_word_t fp; | |
43 | + unw_word_t sp; | |
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 | |
48 | : __LITTLE_ENDIAN); | |
49 | ||
50 | unw_init_remote_p (&cache->cursor, as, this_frame); | |
51 | + | |
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 | |
60 | + to use. */ | |
61 | + uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch)); | |
62 | + ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &sp); | |
63 | + if (ret < 0) | |
64 | + { | |
65 | + unw_destroy_addr_space_p (as); | |
66 | + error (_("Can't get libunwind sp register.")); | |
67 | + } | |
68 | + | |
69 | if (unw_step_p (&cache->cursor) < 0) | |
70 | { | |
71 | unw_destroy_addr_space_p (as); | |
72 | return NULL; | |
73 | } | |
74 | ||
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); | |
78 | if (ret < 0) | |
79 | { | |
80 | @@ -189,6 +207,7 @@ libunwind_frame_cache (struct frame_info | |
81 | error (_("Can't get libunwind sp register.")); | |
82 | } | |
83 | ||
84 | + cache->sp = (CORE_ADDR)sp; | |
85 | cache->base = (CORE_ADDR)fp; | |
86 | cache->as = as; | |
87 | ||
88 | @@ -376,6 +395,31 @@ libunwind_search_unwind_table (void *as, | |
89 | di, pi, need_unwind_info, args); | |
90 | } | |
91 | ||
92 | +void | |
93 | +libunwind_sigtramp_frame_this_id (struct frame_info *this_frame, | |
94 | + void **this_cache, | |
95 | + struct frame_id *this_id) | |
96 | +{ | |
97 | + struct libunwind_frame_cache *cache = | |
98 | + libunwind_frame_cache (this_frame, this_cache); | |
99 | + | |
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. */ | |
104 | + if (cache != NULL) | |
105 | + (*this_id) = frame_id_build (cache->sp, cache->func_addr); | |
106 | + else | |
107 | + (*this_id) = null_frame_id; | |
108 | +} | |
109 | + | |
110 | +static const struct frame_unwind libunwind_sigtramp_frame_unwind = | |
111 | +{ | |
112 | + SIGTRAMP_FRAME, | |
113 | + libunwind_sigtramp_frame_this_id, | |
114 | + libunwind_frame_prev_register | |
115 | +}; | |
116 | + | |
117 | /* Verify if we are in a sigtramp frame and we can use libunwind to unwind. */ | |
118 | int | |
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 | |
125 | ||
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, | |
129 | + void **this_cache, | |
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 | |
139 | struct frame_id id; | |
140 | CORE_ADDR prev_ip; | |
141 | ||
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)) | |
145 | { | |
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); | |
150 | ||
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); | |
161 | ||
162 | if (gdbarch_debug >= 1) | |
163 | fprintf_unfiltered (gdb_stdlog, |