Commit | Line | Data |
---|---|---|
edb3359d DJ |
1 | /* Inline frame unwinder for GDB. |
2 | ||
e2882c85 | 3 | Copyright (C) 2008-2018 Free Software Foundation, Inc. |
edb3359d DJ |
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" | |
ddfe970e | 21 | #include "breakpoint.h" |
e451c4a1 | 22 | #include "inline-frame.h" |
edb3359d DJ |
23 | #include "addrmap.h" |
24 | #include "block.h" | |
25 | #include "frame-unwind.h" | |
26 | #include "inferior.h" | |
4e485129 | 27 | #include "regcache.h" |
edb3359d DJ |
28 | #include "symtab.h" |
29 | #include "vec.h" | |
51d48146 | 30 | #include "frame.h" |
b24531ed | 31 | #include <algorithm> |
edb3359d | 32 | |
edb3359d DJ |
33 | /* We need to save a few variables for every thread stopped at the |
34 | virtual call site of an inlined function. If there was always a | |
35 | "struct thread_info", we could hang it off that; in the mean time, | |
36 | keep our own list. */ | |
37 | struct inline_state | |
38 | { | |
b24531ed SM |
39 | inline_state (ptid_t ptid_, int skipped_frames_, CORE_ADDR saved_pc_, |
40 | symbol *skipped_symbol_) | |
41 | : ptid (ptid_), skipped_frames (skipped_frames_), saved_pc (saved_pc_), | |
42 | skipped_symbol (skipped_symbol_) | |
43 | {} | |
44 | ||
edb3359d DJ |
45 | /* The thread this data relates to. It should be a currently |
46 | stopped thread; we assume thread IDs never change while the | |
47 | thread is stopped. */ | |
48 | ptid_t ptid; | |
49 | ||
50 | /* The number of inlined functions we are skipping. Each of these | |
51 | functions can be stepped in to. */ | |
52 | int skipped_frames; | |
53 | ||
54 | /* Only valid if SKIPPED_FRAMES is non-zero. This is the PC used | |
55 | when calculating SKIPPED_FRAMES; used to check whether we have | |
56 | moved to a new location by user request. If so, we invalidate | |
57 | any skipped frames. */ | |
58 | CORE_ADDR saved_pc; | |
59 | ||
60 | /* Only valid if SKIPPED_FRAMES is non-zero. This is the symbol | |
61 | of the outermost skipped inline function. It's used to find the | |
62 | call site of the current frame. */ | |
63 | struct symbol *skipped_symbol; | |
64 | }; | |
65 | ||
b24531ed | 66 | static std::vector<inline_state> inline_states; |
edb3359d | 67 | |
4e485129 DJ |
68 | /* Locate saved inlined frame state for PTID, if it exists |
69 | and is valid. */ | |
edb3359d DJ |
70 | |
71 | static struct inline_state * | |
72 | find_inline_frame_state (ptid_t ptid) | |
73 | { | |
b24531ed SM |
74 | auto state_it = std::find_if (inline_states.begin (), inline_states.end (), |
75 | [&ptid] (const inline_state &state) | |
76 | { | |
77 | return ptid == state.ptid; | |
78 | }); | |
edb3359d | 79 | |
b24531ed SM |
80 | if (state_it == inline_states.end ()) |
81 | return nullptr; | |
edb3359d | 82 | |
b24531ed SM |
83 | inline_state &state = *state_it; |
84 | struct regcache *regcache = get_thread_regcache (ptid); | |
85 | CORE_ADDR current_pc = regcache_read_pc (regcache); | |
edb3359d | 86 | |
b24531ed SM |
87 | if (current_pc != state.saved_pc) |
88 | { | |
89 | /* PC has changed - this context is invalid. Use the | |
90 | default behavior. */ | |
edb3359d | 91 | |
b24531ed SM |
92 | unordered_remove (inline_states, state_it); |
93 | return nullptr; | |
94 | } | |
edb3359d | 95 | |
b24531ed | 96 | return &state; |
edb3359d DJ |
97 | } |
98 | ||
99 | /* Forget about any hidden inlined functions in PTID, which is new or | |
100 | about to be resumed. PTID may be minus_one_ptid (all processes) | |
101 | or a PID (all threads in this process). */ | |
102 | ||
103 | void | |
104 | clear_inline_frame_state (ptid_t ptid) | |
105 | { | |
b24531ed | 106 | if (ptid == minus_one_ptid) |
edb3359d | 107 | { |
b24531ed | 108 | inline_states.clear (); |
edb3359d DJ |
109 | return; |
110 | } | |
111 | ||
b24531ed | 112 | if (ptid.is_pid ()) |
edb3359d | 113 | { |
b24531ed SM |
114 | int pid = ptid.pid (); |
115 | auto it = std::remove_if (inline_states.begin (), inline_states.end (), | |
116 | [pid] (const inline_state &state) | |
117 | { | |
118 | return pid == state.ptid.pid (); | |
119 | }); | |
120 | ||
121 | inline_states.erase (it, inline_states.end ()); | |
122 | ||
edb3359d DJ |
123 | return; |
124 | } | |
125 | ||
b24531ed SM |
126 | auto it = std::find_if (inline_states.begin (), inline_states.end (), |
127 | [&ptid] (const inline_state &state) | |
128 | { | |
129 | return ptid == state.ptid; | |
130 | }); | |
131 | ||
132 | if (it != inline_states.end ()) | |
133 | unordered_remove (inline_states, it); | |
edb3359d DJ |
134 | } |
135 | ||
136 | static void | |
137 | inline_frame_this_id (struct frame_info *this_frame, | |
138 | void **this_cache, | |
139 | struct frame_id *this_id) | |
140 | { | |
141 | struct symbol *func; | |
142 | ||
143 | /* In order to have a stable frame ID for a given inline function, | |
144 | we must get the stack / special addresses from the underlying | |
51d48146 PA |
145 | real frame's this_id method. So we must call |
146 | get_prev_frame_always. Because we are inlined into some | |
147 | function, there must be previous frames, so this is safe - as | |
148 | long as we're careful not to create any cycles. */ | |
149 | *this_id = get_frame_id (get_prev_frame_always (this_frame)); | |
edb3359d DJ |
150 | |
151 | /* We need a valid frame ID, so we need to be based on a valid | |
152 | frame. FSF submission NOTE: this would be a good assertion to | |
153 | apply to all frames, all the time. That would fix the ambiguity | |
154 | of null_frame_id (between "no/any frame" and "the outermost | |
155 | frame"). This will take work. */ | |
156 | gdb_assert (frame_id_p (*this_id)); | |
157 | ||
005ca36a JB |
158 | /* For now, require we don't match outer_frame_id either (see |
159 | comment above). */ | |
160 | gdb_assert (!frame_id_eq (*this_id, outer_frame_id)); | |
161 | ||
edb3359d DJ |
162 | /* Future work NOTE: Alexandre Oliva applied a patch to GCC 4.3 |
163 | which generates DW_AT_entry_pc for inlined functions when | |
164 | possible. If this attribute is available, we should use it | |
165 | in the frame ID (and eventually, to set breakpoints). */ | |
166 | func = get_frame_function (this_frame); | |
167 | gdb_assert (func != NULL); | |
168 | (*this_id).code_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (func)); | |
193facb3 | 169 | (*this_id).artificial_depth++; |
edb3359d DJ |
170 | } |
171 | ||
172 | static struct value * | |
173 | inline_frame_prev_register (struct frame_info *this_frame, void **this_cache, | |
174 | int regnum) | |
175 | { | |
176 | /* Use get_frame_register_value instead of | |
177 | frame_unwind_got_register, to avoid requiring this frame's ID. | |
178 | This frame's ID depends on the previous frame's ID (unusual), and | |
179 | the previous frame's ID depends on this frame's unwound | |
180 | registers. If unwinding registers from this frame called | |
181 | get_frame_id, there would be a loop. | |
182 | ||
183 | Do not copy this code into any other unwinder! Inlined functions | |
184 | are special; other unwinders must not have a dependency on the | |
185 | previous frame's ID, and therefore can and should use | |
186 | frame_unwind_got_register instead. */ | |
187 | return get_frame_register_value (this_frame, regnum); | |
188 | } | |
189 | ||
190 | /* Check whether we are at an inlining site that does not already | |
191 | have an associated frame. */ | |
192 | ||
193 | static int | |
194 | inline_frame_sniffer (const struct frame_unwind *self, | |
195 | struct frame_info *this_frame, | |
196 | void **this_cache) | |
197 | { | |
198 | CORE_ADDR this_pc; | |
3977b71f | 199 | const struct block *frame_block, *cur_block; |
edb3359d DJ |
200 | int depth; |
201 | struct frame_info *next_frame; | |
202 | struct inline_state *state = find_inline_frame_state (inferior_ptid); | |
203 | ||
204 | this_pc = get_frame_address_in_block (this_frame); | |
205 | frame_block = block_for_pc (this_pc); | |
206 | if (frame_block == NULL) | |
207 | return 0; | |
208 | ||
209 | /* Calculate DEPTH, the number of inlined functions at this | |
210 | location. */ | |
211 | depth = 0; | |
212 | cur_block = frame_block; | |
213 | while (BLOCK_SUPERBLOCK (cur_block)) | |
214 | { | |
215 | if (block_inlined_p (cur_block)) | |
216 | depth++; | |
0fa7fe50 JB |
217 | else if (BLOCK_FUNCTION (cur_block) != NULL) |
218 | break; | |
edb3359d DJ |
219 | |
220 | cur_block = BLOCK_SUPERBLOCK (cur_block); | |
221 | } | |
222 | ||
223 | /* Check how many inlined functions already have frames. */ | |
224 | for (next_frame = get_next_frame (this_frame); | |
225 | next_frame && get_frame_type (next_frame) == INLINE_FRAME; | |
226 | next_frame = get_next_frame (next_frame)) | |
227 | { | |
228 | gdb_assert (depth > 0); | |
229 | depth--; | |
230 | } | |
231 | ||
232 | /* If this is the topmost frame, or all frames above us are inlined, | |
233 | then check whether we were requested to skip some frames (so they | |
234 | can be stepped into later). */ | |
235 | if (state != NULL && state->skipped_frames > 0 && next_frame == NULL) | |
236 | { | |
4e485129 DJ |
237 | gdb_assert (depth >= state->skipped_frames); |
238 | depth -= state->skipped_frames; | |
edb3359d DJ |
239 | } |
240 | ||
241 | /* If all the inlined functions here already have frames, then pass | |
242 | to the normal unwinder for this PC. */ | |
243 | if (depth == 0) | |
244 | return 0; | |
245 | ||
246 | /* If the next frame is an inlined function, but not the outermost, then | |
247 | we are the next outer. If it is not an inlined function, then we | |
248 | are the innermost inlined function of a different real frame. */ | |
249 | return 1; | |
250 | } | |
251 | ||
39d7b0e2 | 252 | const struct frame_unwind inline_frame_unwind = { |
edb3359d | 253 | INLINE_FRAME, |
8fbca658 | 254 | default_frame_unwind_stop_reason, |
edb3359d DJ |
255 | inline_frame_this_id, |
256 | inline_frame_prev_register, | |
257 | NULL, | |
258 | inline_frame_sniffer | |
259 | }; | |
260 | ||
edb3359d DJ |
261 | /* Return non-zero if BLOCK, an inlined function block containing PC, |
262 | has a group of contiguous instructions starting at PC (but not | |
263 | before it). */ | |
264 | ||
265 | static int | |
3977b71f | 266 | block_starting_point_at (CORE_ADDR pc, const struct block *block) |
edb3359d | 267 | { |
346d1dfe | 268 | const struct blockvector *bv; |
edb3359d DJ |
269 | struct block *new_block; |
270 | ||
271 | bv = blockvector_for_pc (pc, NULL); | |
272 | if (BLOCKVECTOR_MAP (bv) == NULL) | |
273 | return 0; | |
274 | ||
9a3c8263 | 275 | new_block = (struct block *) addrmap_find (BLOCKVECTOR_MAP (bv), pc - 1); |
edb3359d DJ |
276 | if (new_block == NULL) |
277 | return 1; | |
278 | ||
279 | if (new_block == block || contained_in (new_block, block)) | |
280 | return 0; | |
281 | ||
177b42fe | 282 | /* The immediately preceding address belongs to a different block, |
edb3359d DJ |
283 | which is not a child of this one. Treat this as an entrance into |
284 | BLOCK. */ | |
285 | return 1; | |
286 | } | |
287 | ||
ddfe970e KS |
288 | /* Loop over the stop chain and determine if execution stopped in an |
289 | inlined frame because of a user breakpoint. THIS_PC is the current | |
290 | frame's PC. */ | |
291 | ||
292 | static bool | |
293 | stopped_by_user_bp_inline_frame (CORE_ADDR this_pc, bpstat stop_chain) | |
294 | { | |
295 | for (bpstat s = stop_chain; s != NULL; s = s->next) | |
296 | { | |
297 | struct breakpoint *bpt = s->breakpoint_at; | |
298 | ||
299 | if (bpt != NULL && user_breakpoint_p (bpt)) | |
300 | { | |
301 | bp_location *loc = s->bp_location_at; | |
302 | enum bp_loc_type t = loc->loc_type; | |
303 | ||
304 | if (loc->address == this_pc | |
305 | && (t == bp_loc_software_breakpoint | |
306 | || t == bp_loc_hardware_breakpoint)) | |
307 | return true; | |
308 | } | |
309 | } | |
310 | ||
311 | return false; | |
312 | } | |
313 | ||
314 | /* See inline-frame.h. */ | |
edb3359d DJ |
315 | |
316 | void | |
ddfe970e | 317 | skip_inline_frames (ptid_t ptid, bpstat stop_chain) |
edb3359d | 318 | { |
3977b71f | 319 | const struct block *frame_block, *cur_block; |
edb3359d DJ |
320 | struct symbol *last_sym = NULL; |
321 | int skip_count = 0; | |
edb3359d DJ |
322 | |
323 | /* This function is called right after reinitializing the frame | |
324 | cache. We try not to do more unwinding than absolutely | |
325 | necessary, for performance. */ | |
b24531ed | 326 | CORE_ADDR this_pc = get_frame_pc (get_current_frame ()); |
edb3359d DJ |
327 | frame_block = block_for_pc (this_pc); |
328 | ||
329 | if (frame_block != NULL) | |
330 | { | |
331 | cur_block = frame_block; | |
332 | while (BLOCK_SUPERBLOCK (cur_block)) | |
333 | { | |
334 | if (block_inlined_p (cur_block)) | |
335 | { | |
336 | /* See comments in inline_frame_this_id about this use | |
337 | of BLOCK_START. */ | |
338 | if (BLOCK_START (cur_block) == this_pc | |
339 | || block_starting_point_at (this_pc, cur_block)) | |
340 | { | |
ddfe970e KS |
341 | /* Do not skip the inlined frame if execution |
342 | stopped in an inlined frame because of a user | |
343 | breakpoint. */ | |
344 | if (!stopped_by_user_bp_inline_frame (this_pc, stop_chain)) | |
345 | { | |
346 | skip_count++; | |
347 | last_sym = BLOCK_FUNCTION (cur_block); | |
348 | } | |
edb3359d DJ |
349 | } |
350 | else | |
351 | break; | |
352 | } | |
0fa7fe50 JB |
353 | else if (BLOCK_FUNCTION (cur_block) != NULL) |
354 | break; | |
355 | ||
edb3359d DJ |
356 | cur_block = BLOCK_SUPERBLOCK (cur_block); |
357 | } | |
358 | } | |
359 | ||
360 | gdb_assert (find_inline_frame_state (ptid) == NULL); | |
b24531ed | 361 | inline_states.emplace_back (ptid, skip_count, this_pc, last_sym); |
edb3359d DJ |
362 | |
363 | if (skip_count != 0) | |
364 | reinit_frame_cache (); | |
365 | } | |
366 | ||
367 | /* Step into an inlined function by unhiding it. */ | |
368 | ||
369 | void | |
370 | step_into_inline_frame (ptid_t ptid) | |
371 | { | |
372 | struct inline_state *state = find_inline_frame_state (ptid); | |
373 | ||
374 | gdb_assert (state != NULL && state->skipped_frames > 0); | |
375 | state->skipped_frames--; | |
376 | reinit_frame_cache (); | |
377 | } | |
378 | ||
379 | /* Return the number of hidden functions inlined into the current | |
380 | frame. */ | |
381 | ||
382 | int | |
383 | inline_skipped_frames (ptid_t ptid) | |
384 | { | |
385 | struct inline_state *state = find_inline_frame_state (ptid); | |
386 | ||
387 | if (state == NULL) | |
388 | return 0; | |
389 | else | |
390 | return state->skipped_frames; | |
391 | } | |
392 | ||
393 | /* If one or more inlined functions are hidden, return the symbol for | |
394 | the function inlined into the current frame. */ | |
395 | ||
396 | struct symbol * | |
397 | inline_skipped_symbol (ptid_t ptid) | |
398 | { | |
399 | struct inline_state *state = find_inline_frame_state (ptid); | |
400 | ||
401 | gdb_assert (state != NULL); | |
402 | return state->skipped_symbol; | |
403 | } | |
404 | ||
405 | /* Return the number of functions inlined into THIS_FRAME. Some of | |
406 | the callees may not have associated frames (see | |
407 | skip_inline_frames). */ | |
408 | ||
409 | int | |
410 | frame_inlined_callees (struct frame_info *this_frame) | |
411 | { | |
412 | struct frame_info *next_frame; | |
413 | int inline_count = 0; | |
414 | ||
415 | /* First count how many inlined functions at this PC have frames | |
416 | above FRAME (are inlined into FRAME). */ | |
417 | for (next_frame = get_next_frame (this_frame); | |
418 | next_frame && get_frame_type (next_frame) == INLINE_FRAME; | |
419 | next_frame = get_next_frame (next_frame)) | |
420 | inline_count++; | |
421 | ||
422 | /* Simulate some most-inner inlined frames which were suppressed, so | |
423 | they can be stepped into later. If we are unwinding already | |
424 | outer frames from some non-inlined frame this does not apply. */ | |
425 | if (next_frame == NULL) | |
426 | inline_count += inline_skipped_frames (inferior_ptid); | |
427 | ||
428 | return inline_count; | |
429 | } |