]>
Commit | Line | Data |
---|---|---|
edb3359d DJ |
1 | /* Inline frame unwinder for GDB. |
2 | ||
3 | Copyright (C) 2008 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "addrmap.h" | |
22 | #include "block.h" | |
23 | #include "frame-unwind.h" | |
24 | #include "inferior.h" | |
25 | #include "symtab.h" | |
26 | #include "vec.h" | |
27 | ||
28 | #include "gdb_assert.h" | |
29 | ||
30 | /* We need to save a few variables for every thread stopped at the | |
31 | virtual call site of an inlined function. If there was always a | |
32 | "struct thread_info", we could hang it off that; in the mean time, | |
33 | keep our own list. */ | |
34 | struct inline_state | |
35 | { | |
36 | /* The thread this data relates to. It should be a currently | |
37 | stopped thread; we assume thread IDs never change while the | |
38 | thread is stopped. */ | |
39 | ptid_t ptid; | |
40 | ||
41 | /* The number of inlined functions we are skipping. Each of these | |
42 | functions can be stepped in to. */ | |
43 | int skipped_frames; | |
44 | ||
45 | /* Only valid if SKIPPED_FRAMES is non-zero. This is the PC used | |
46 | when calculating SKIPPED_FRAMES; used to check whether we have | |
47 | moved to a new location by user request. If so, we invalidate | |
48 | any skipped frames. */ | |
49 | CORE_ADDR saved_pc; | |
50 | ||
51 | /* Only valid if SKIPPED_FRAMES is non-zero. This is the symbol | |
52 | of the outermost skipped inline function. It's used to find the | |
53 | call site of the current frame. */ | |
54 | struct symbol *skipped_symbol; | |
55 | }; | |
56 | ||
57 | typedef struct inline_state inline_state_s; | |
58 | DEF_VEC_O(inline_state_s); | |
59 | ||
60 | static VEC(inline_state_s) *inline_states; | |
61 | ||
62 | /* Locate saved inlined frame state for PTID, if it exists. */ | |
63 | ||
64 | static struct inline_state * | |
65 | find_inline_frame_state (ptid_t ptid) | |
66 | { | |
67 | struct inline_state *state; | |
68 | int ix; | |
69 | ||
70 | for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++) | |
71 | { | |
72 | if (ptid_equal (state->ptid, ptid)) | |
73 | return state; | |
74 | } | |
75 | ||
76 | return NULL; | |
77 | } | |
78 | ||
79 | /* Allocate saved inlined frame state for PTID. */ | |
80 | ||
81 | static struct inline_state * | |
82 | allocate_inline_frame_state (ptid_t ptid) | |
83 | { | |
84 | struct inline_state *state; | |
85 | ||
86 | state = VEC_safe_push (inline_state_s, inline_states, NULL); | |
87 | memset (state, 0, sizeof (*state)); | |
88 | state->ptid = ptid; | |
89 | ||
90 | return state; | |
91 | } | |
92 | ||
93 | /* Forget about any hidden inlined functions in PTID, which is new or | |
94 | about to be resumed. PTID may be minus_one_ptid (all processes) | |
95 | or a PID (all threads in this process). */ | |
96 | ||
97 | void | |
98 | clear_inline_frame_state (ptid_t ptid) | |
99 | { | |
100 | struct inline_state *state; | |
101 | int ix; | |
102 | ||
103 | if (ptid_equal (ptid, minus_one_ptid)) | |
104 | { | |
105 | VEC_free (inline_state_s, inline_states); | |
106 | return; | |
107 | } | |
108 | ||
109 | if (ptid_is_pid (ptid)) | |
110 | { | |
111 | VEC (inline_state_s) *new_states = NULL; | |
112 | int pid = ptid_get_pid (ptid); | |
113 | for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++) | |
114 | if (pid != ptid_get_pid (state->ptid)) | |
115 | VEC_safe_push (inline_state_s, new_states, state); | |
116 | VEC_free (inline_state_s, inline_states); | |
117 | inline_states = new_states; | |
118 | return; | |
119 | } | |
120 | ||
121 | for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++) | |
122 | if (ptid_equal (state->ptid, ptid)) | |
123 | { | |
124 | VEC_unordered_remove (inline_state_s, inline_states, ix); | |
125 | return; | |
126 | } | |
127 | } | |
128 | ||
129 | static void | |
130 | inline_frame_this_id (struct frame_info *this_frame, | |
131 | void **this_cache, | |
132 | struct frame_id *this_id) | |
133 | { | |
134 | struct symbol *func; | |
135 | ||
136 | /* In order to have a stable frame ID for a given inline function, | |
137 | we must get the stack / special addresses from the underlying | |
138 | real frame's this_id method. So we must call get_prev_frame. | |
139 | Because we are inlined into some function, there must be previous | |
140 | frames, so this is safe - as long as we're careful not to | |
141 | create any cycles. */ | |
142 | *this_id = get_frame_id (get_prev_frame (this_frame)); | |
143 | ||
144 | /* We need a valid frame ID, so we need to be based on a valid | |
145 | frame. FSF submission NOTE: this would be a good assertion to | |
146 | apply to all frames, all the time. That would fix the ambiguity | |
147 | of null_frame_id (between "no/any frame" and "the outermost | |
148 | frame"). This will take work. */ | |
149 | gdb_assert (frame_id_p (*this_id)); | |
150 | ||
151 | /* Future work NOTE: Alexandre Oliva applied a patch to GCC 4.3 | |
152 | which generates DW_AT_entry_pc for inlined functions when | |
153 | possible. If this attribute is available, we should use it | |
154 | in the frame ID (and eventually, to set breakpoints). */ | |
155 | func = get_frame_function (this_frame); | |
156 | gdb_assert (func != NULL); | |
157 | (*this_id).code_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (func)); | |
158 | (*this_id).inline_depth++; | |
159 | } | |
160 | ||
161 | static struct value * | |
162 | inline_frame_prev_register (struct frame_info *this_frame, void **this_cache, | |
163 | int regnum) | |
164 | { | |
165 | /* Use get_frame_register_value instead of | |
166 | frame_unwind_got_register, to avoid requiring this frame's ID. | |
167 | This frame's ID depends on the previous frame's ID (unusual), and | |
168 | the previous frame's ID depends on this frame's unwound | |
169 | registers. If unwinding registers from this frame called | |
170 | get_frame_id, there would be a loop. | |
171 | ||
172 | Do not copy this code into any other unwinder! Inlined functions | |
173 | are special; other unwinders must not have a dependency on the | |
174 | previous frame's ID, and therefore can and should use | |
175 | frame_unwind_got_register instead. */ | |
176 | return get_frame_register_value (this_frame, regnum); | |
177 | } | |
178 | ||
179 | /* Check whether we are at an inlining site that does not already | |
180 | have an associated frame. */ | |
181 | ||
182 | static int | |
183 | inline_frame_sniffer (const struct frame_unwind *self, | |
184 | struct frame_info *this_frame, | |
185 | void **this_cache) | |
186 | { | |
187 | CORE_ADDR this_pc; | |
188 | struct block *frame_block, *cur_block; | |
189 | int depth; | |
190 | struct frame_info *next_frame; | |
191 | struct inline_state *state = find_inline_frame_state (inferior_ptid); | |
192 | ||
193 | this_pc = get_frame_address_in_block (this_frame); | |
194 | frame_block = block_for_pc (this_pc); | |
195 | if (frame_block == NULL) | |
196 | return 0; | |
197 | ||
198 | /* Calculate DEPTH, the number of inlined functions at this | |
199 | location. */ | |
200 | depth = 0; | |
201 | cur_block = frame_block; | |
202 | while (BLOCK_SUPERBLOCK (cur_block)) | |
203 | { | |
204 | if (block_inlined_p (cur_block)) | |
205 | depth++; | |
206 | ||
207 | cur_block = BLOCK_SUPERBLOCK (cur_block); | |
208 | } | |
209 | ||
210 | /* Check how many inlined functions already have frames. */ | |
211 | for (next_frame = get_next_frame (this_frame); | |
212 | next_frame && get_frame_type (next_frame) == INLINE_FRAME; | |
213 | next_frame = get_next_frame (next_frame)) | |
214 | { | |
215 | gdb_assert (depth > 0); | |
216 | depth--; | |
217 | } | |
218 | ||
219 | /* If this is the topmost frame, or all frames above us are inlined, | |
220 | then check whether we were requested to skip some frames (so they | |
221 | can be stepped into later). */ | |
222 | if (state != NULL && state->skipped_frames > 0 && next_frame == NULL) | |
223 | { | |
224 | if (this_pc != state->saved_pc) | |
225 | state->skipped_frames = 0; | |
226 | else | |
227 | { | |
228 | gdb_assert (depth >= state->skipped_frames); | |
229 | depth -= state->skipped_frames; | |
230 | } | |
231 | } | |
232 | ||
233 | /* If all the inlined functions here already have frames, then pass | |
234 | to the normal unwinder for this PC. */ | |
235 | if (depth == 0) | |
236 | return 0; | |
237 | ||
238 | /* If the next frame is an inlined function, but not the outermost, then | |
239 | we are the next outer. If it is not an inlined function, then we | |
240 | are the innermost inlined function of a different real frame. */ | |
241 | return 1; | |
242 | } | |
243 | ||
244 | const struct frame_unwind inline_frame_unwinder = { | |
245 | INLINE_FRAME, | |
246 | inline_frame_this_id, | |
247 | inline_frame_prev_register, | |
248 | NULL, | |
249 | inline_frame_sniffer | |
250 | }; | |
251 | ||
252 | const struct frame_unwind *const inline_frame_unwind = &inline_frame_unwinder; | |
253 | ||
254 | /* Return non-zero if BLOCK, an inlined function block containing PC, | |
255 | has a group of contiguous instructions starting at PC (but not | |
256 | before it). */ | |
257 | ||
258 | static int | |
259 | block_starting_point_at (CORE_ADDR pc, struct block *block) | |
260 | { | |
261 | struct blockvector *bv; | |
262 | struct block *new_block; | |
263 | ||
264 | bv = blockvector_for_pc (pc, NULL); | |
265 | if (BLOCKVECTOR_MAP (bv) == NULL) | |
266 | return 0; | |
267 | ||
268 | new_block = addrmap_find (BLOCKVECTOR_MAP (bv), pc - 1); | |
269 | if (new_block == NULL) | |
270 | return 1; | |
271 | ||
272 | if (new_block == block || contained_in (new_block, block)) | |
273 | return 0; | |
274 | ||
275 | /* The immediately preceeding address belongs to a different block, | |
276 | which is not a child of this one. Treat this as an entrance into | |
277 | BLOCK. */ | |
278 | return 1; | |
279 | } | |
280 | ||
281 | /* Skip all inlined functions whose call sites are at the current PC. | |
282 | Frames for the hidden functions will not appear in the backtrace until the | |
283 | user steps into them. */ | |
284 | ||
285 | void | |
286 | skip_inline_frames (ptid_t ptid) | |
287 | { | |
288 | CORE_ADDR this_pc; | |
289 | struct block *frame_block, *cur_block; | |
290 | struct symbol *last_sym = NULL; | |
291 | int skip_count = 0; | |
292 | struct inline_state *state; | |
293 | ||
294 | /* This function is called right after reinitializing the frame | |
295 | cache. We try not to do more unwinding than absolutely | |
296 | necessary, for performance. */ | |
297 | this_pc = get_frame_pc (get_current_frame ()); | |
298 | frame_block = block_for_pc (this_pc); | |
299 | ||
300 | if (frame_block != NULL) | |
301 | { | |
302 | cur_block = frame_block; | |
303 | while (BLOCK_SUPERBLOCK (cur_block)) | |
304 | { | |
305 | if (block_inlined_p (cur_block)) | |
306 | { | |
307 | /* See comments in inline_frame_this_id about this use | |
308 | of BLOCK_START. */ | |
309 | if (BLOCK_START (cur_block) == this_pc | |
310 | || block_starting_point_at (this_pc, cur_block)) | |
311 | { | |
312 | skip_count++; | |
313 | last_sym = BLOCK_FUNCTION (cur_block); | |
314 | } | |
315 | else | |
316 | break; | |
317 | } | |
318 | cur_block = BLOCK_SUPERBLOCK (cur_block); | |
319 | } | |
320 | } | |
321 | ||
322 | gdb_assert (find_inline_frame_state (ptid) == NULL); | |
323 | state = allocate_inline_frame_state (ptid); | |
324 | state->skipped_frames = skip_count; | |
325 | state->saved_pc = this_pc; | |
326 | state->skipped_symbol = last_sym; | |
327 | ||
328 | if (skip_count != 0) | |
329 | reinit_frame_cache (); | |
330 | } | |
331 | ||
332 | /* Step into an inlined function by unhiding it. */ | |
333 | ||
334 | void | |
335 | step_into_inline_frame (ptid_t ptid) | |
336 | { | |
337 | struct inline_state *state = find_inline_frame_state (ptid); | |
338 | ||
339 | gdb_assert (state != NULL && state->skipped_frames > 0); | |
340 | state->skipped_frames--; | |
341 | reinit_frame_cache (); | |
342 | } | |
343 | ||
344 | /* Return the number of hidden functions inlined into the current | |
345 | frame. */ | |
346 | ||
347 | int | |
348 | inline_skipped_frames (ptid_t ptid) | |
349 | { | |
350 | struct inline_state *state = find_inline_frame_state (ptid); | |
351 | ||
352 | if (state == NULL) | |
353 | return 0; | |
354 | else | |
355 | return state->skipped_frames; | |
356 | } | |
357 | ||
358 | /* If one or more inlined functions are hidden, return the symbol for | |
359 | the function inlined into the current frame. */ | |
360 | ||
361 | struct symbol * | |
362 | inline_skipped_symbol (ptid_t ptid) | |
363 | { | |
364 | struct inline_state *state = find_inline_frame_state (ptid); | |
365 | ||
366 | gdb_assert (state != NULL); | |
367 | return state->skipped_symbol; | |
368 | } | |
369 | ||
370 | /* Return the number of functions inlined into THIS_FRAME. Some of | |
371 | the callees may not have associated frames (see | |
372 | skip_inline_frames). */ | |
373 | ||
374 | int | |
375 | frame_inlined_callees (struct frame_info *this_frame) | |
376 | { | |
377 | struct frame_info *next_frame; | |
378 | int inline_count = 0; | |
379 | ||
380 | /* First count how many inlined functions at this PC have frames | |
381 | above FRAME (are inlined into FRAME). */ | |
382 | for (next_frame = get_next_frame (this_frame); | |
383 | next_frame && get_frame_type (next_frame) == INLINE_FRAME; | |
384 | next_frame = get_next_frame (next_frame)) | |
385 | inline_count++; | |
386 | ||
387 | /* Simulate some most-inner inlined frames which were suppressed, so | |
388 | they can be stepped into later. If we are unwinding already | |
389 | outer frames from some non-inlined frame this does not apply. */ | |
390 | if (next_frame == NULL) | |
391 | inline_count += inline_skipped_frames (inferior_ptid); | |
392 | ||
393 | return inline_count; | |
394 | } |