1a45ae5f8SJohn Marino /* Virtual tail call frames unwinder for GDB.
2a45ae5f8SJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2010-2013 Free Software Foundation, Inc.
4a45ae5f8SJohn Marino
5a45ae5f8SJohn Marino This file is part of GDB.
6a45ae5f8SJohn Marino
7a45ae5f8SJohn Marino This program is free software; you can redistribute it and/or modify
8a45ae5f8SJohn Marino it under the terms of the GNU General Public License as published by
9a45ae5f8SJohn Marino the Free Software Foundation; either version 3 of the License, or
10a45ae5f8SJohn Marino (at your option) any later version.
11a45ae5f8SJohn Marino
12a45ae5f8SJohn Marino This program is distributed in the hope that it will be useful,
13a45ae5f8SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14a45ae5f8SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15a45ae5f8SJohn Marino GNU General Public License for more details.
16a45ae5f8SJohn Marino
17a45ae5f8SJohn Marino You should have received a copy of the GNU General Public License
18a45ae5f8SJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19a45ae5f8SJohn Marino
20a45ae5f8SJohn Marino #include "defs.h"
21a45ae5f8SJohn Marino #include "gdb_assert.h"
22a45ae5f8SJohn Marino #include "frame.h"
23a45ae5f8SJohn Marino #include "dwarf2-frame-tailcall.h"
24a45ae5f8SJohn Marino #include "dwarf2loc.h"
25a45ae5f8SJohn Marino #include "frame-unwind.h"
26a45ae5f8SJohn Marino #include "block.h"
27a45ae5f8SJohn Marino #include "hashtab.h"
28a45ae5f8SJohn Marino #include "exceptions.h"
29a45ae5f8SJohn Marino #include "gdbtypes.h"
30a45ae5f8SJohn Marino #include "regcache.h"
31a45ae5f8SJohn Marino #include "value.h"
32a45ae5f8SJohn Marino #include "dwarf2-frame.h"
33a45ae5f8SJohn Marino
34a45ae5f8SJohn Marino /* Contains struct tailcall_cache indexed by next_bottom_frame. */
35a45ae5f8SJohn Marino static htab_t cache_htab;
36a45ae5f8SJohn Marino
37a45ae5f8SJohn Marino /* Associate structure of the unwinder to call_site_chain. Lifetime of this
38a45ae5f8SJohn Marino structure is maintained by REFC decremented by dealloc_cache, all of them
39a45ae5f8SJohn Marino get deleted during reinit_frame_cache. */
40a45ae5f8SJohn Marino struct tailcall_cache
41a45ae5f8SJohn Marino {
42a45ae5f8SJohn Marino /* It must be the first one of this struct. It is the furthest callee. */
43a45ae5f8SJohn Marino struct frame_info *next_bottom_frame;
44a45ae5f8SJohn Marino
45a45ae5f8SJohn Marino /* Reference count. The whole chain of virtual tail call frames shares one
46a45ae5f8SJohn Marino tailcall_cache. */
47a45ae5f8SJohn Marino int refc;
48a45ae5f8SJohn Marino
49a45ae5f8SJohn Marino /* Associated found virtual taill call frames chain, it is never NULL. */
50a45ae5f8SJohn Marino struct call_site_chain *chain;
51a45ae5f8SJohn Marino
52a45ae5f8SJohn Marino /* Cached pretended_chain_levels result. */
53a45ae5f8SJohn Marino int chain_levels;
54a45ae5f8SJohn Marino
55a45ae5f8SJohn Marino /* Unwound PC from the top (caller) frame, as it is not contained
56a45ae5f8SJohn Marino in CHAIN. */
57a45ae5f8SJohn Marino CORE_ADDR prev_pc;
58a45ae5f8SJohn Marino
59a45ae5f8SJohn Marino /* Compensate SP in caller frames appropriately. prev_sp and
60a45ae5f8SJohn Marino entry_cfa_sp_offset are valid only if PREV_SP_P. PREV_SP is SP at the top
61a45ae5f8SJohn Marino (caller) frame. ENTRY_CFA_SP_OFFSET is shift of SP in tail call frames
62a45ae5f8SJohn Marino against next_bottom_frame SP. */
63a45ae5f8SJohn Marino unsigned prev_sp_p : 1;
64a45ae5f8SJohn Marino CORE_ADDR prev_sp;
65a45ae5f8SJohn Marino LONGEST entry_cfa_sp_offset;
66a45ae5f8SJohn Marino };
67a45ae5f8SJohn Marino
68a45ae5f8SJohn Marino /* hash_f for htab_create_alloc of cache_htab. */
69a45ae5f8SJohn Marino
70a45ae5f8SJohn Marino static hashval_t
cache_hash(const void * arg)71a45ae5f8SJohn Marino cache_hash (const void *arg)
72a45ae5f8SJohn Marino {
73a45ae5f8SJohn Marino const struct tailcall_cache *cache = arg;
74a45ae5f8SJohn Marino
75a45ae5f8SJohn Marino return htab_hash_pointer (cache->next_bottom_frame);
76a45ae5f8SJohn Marino }
77a45ae5f8SJohn Marino
78a45ae5f8SJohn Marino /* eq_f for htab_create_alloc of cache_htab. */
79a45ae5f8SJohn Marino
80a45ae5f8SJohn Marino static int
cache_eq(const void * arg1,const void * arg2)81a45ae5f8SJohn Marino cache_eq (const void *arg1, const void *arg2)
82a45ae5f8SJohn Marino {
83a45ae5f8SJohn Marino const struct tailcall_cache *cache1 = arg1;
84a45ae5f8SJohn Marino const struct tailcall_cache *cache2 = arg2;
85a45ae5f8SJohn Marino
86a45ae5f8SJohn Marino return cache1->next_bottom_frame == cache2->next_bottom_frame;
87a45ae5f8SJohn Marino }
88a45ae5f8SJohn Marino
89a45ae5f8SJohn Marino /* Create new tailcall_cache for NEXT_BOTTOM_FRAME, NEXT_BOTTOM_FRAME must not
90a45ae5f8SJohn Marino yet have been indexed by cache_htab. Caller holds one reference of the new
91a45ae5f8SJohn Marino tailcall_cache. */
92a45ae5f8SJohn Marino
93a45ae5f8SJohn Marino static struct tailcall_cache *
cache_new_ref1(struct frame_info * next_bottom_frame)94a45ae5f8SJohn Marino cache_new_ref1 (struct frame_info *next_bottom_frame)
95a45ae5f8SJohn Marino {
96a45ae5f8SJohn Marino struct tailcall_cache *cache;
97a45ae5f8SJohn Marino void **slot;
98a45ae5f8SJohn Marino
99a45ae5f8SJohn Marino cache = xzalloc (sizeof (*cache));
100a45ae5f8SJohn Marino
101a45ae5f8SJohn Marino cache->next_bottom_frame = next_bottom_frame;
102a45ae5f8SJohn Marino cache->refc = 1;
103a45ae5f8SJohn Marino
104a45ae5f8SJohn Marino slot = htab_find_slot (cache_htab, cache, INSERT);
105a45ae5f8SJohn Marino gdb_assert (*slot == NULL);
106a45ae5f8SJohn Marino *slot = cache;
107a45ae5f8SJohn Marino
108a45ae5f8SJohn Marino return cache;
109a45ae5f8SJohn Marino }
110a45ae5f8SJohn Marino
111a45ae5f8SJohn Marino /* Create new reference to CACHE. */
112a45ae5f8SJohn Marino
113a45ae5f8SJohn Marino static void
cache_ref(struct tailcall_cache * cache)114a45ae5f8SJohn Marino cache_ref (struct tailcall_cache *cache)
115a45ae5f8SJohn Marino {
116a45ae5f8SJohn Marino gdb_assert (cache->refc > 0);
117a45ae5f8SJohn Marino
118a45ae5f8SJohn Marino cache->refc++;
119a45ae5f8SJohn Marino }
120a45ae5f8SJohn Marino
121a45ae5f8SJohn Marino /* Drop reference to CACHE, possibly fully freeing it and unregistering it from
122a45ae5f8SJohn Marino cache_htab. */
123a45ae5f8SJohn Marino
124a45ae5f8SJohn Marino static void
cache_unref(struct tailcall_cache * cache)125a45ae5f8SJohn Marino cache_unref (struct tailcall_cache *cache)
126a45ae5f8SJohn Marino {
127a45ae5f8SJohn Marino gdb_assert (cache->refc > 0);
128a45ae5f8SJohn Marino
129a45ae5f8SJohn Marino if (!--cache->refc)
130a45ae5f8SJohn Marino {
131a45ae5f8SJohn Marino gdb_assert (htab_find_slot (cache_htab, cache, NO_INSERT) != NULL);
132a45ae5f8SJohn Marino htab_remove_elt (cache_htab, cache);
133a45ae5f8SJohn Marino
134a45ae5f8SJohn Marino xfree (cache->chain);
135a45ae5f8SJohn Marino xfree (cache);
136a45ae5f8SJohn Marino }
137a45ae5f8SJohn Marino }
138a45ae5f8SJohn Marino
139a45ae5f8SJohn Marino /* Return 1 if FI is a non-bottom (not the callee) tail call frame. Otherwise
140a45ae5f8SJohn Marino return 0. */
141a45ae5f8SJohn Marino
142a45ae5f8SJohn Marino static int
frame_is_tailcall(struct frame_info * fi)143a45ae5f8SJohn Marino frame_is_tailcall (struct frame_info *fi)
144a45ae5f8SJohn Marino {
145a45ae5f8SJohn Marino return frame_unwinder_is (fi, &dwarf2_tailcall_frame_unwind);
146a45ae5f8SJohn Marino }
147a45ae5f8SJohn Marino
148a45ae5f8SJohn Marino /* Try to find tailcall_cache in cache_htab if FI is a part of its virtual tail
149a45ae5f8SJohn Marino call chain. Otherwise return NULL. No new reference is created. */
150a45ae5f8SJohn Marino
151a45ae5f8SJohn Marino static struct tailcall_cache *
cache_find(struct frame_info * fi)152a45ae5f8SJohn Marino cache_find (struct frame_info *fi)
153a45ae5f8SJohn Marino {
154a45ae5f8SJohn Marino struct tailcall_cache *cache;
155a45ae5f8SJohn Marino void **slot;
156a45ae5f8SJohn Marino
157a45ae5f8SJohn Marino while (frame_is_tailcall (fi))
158a45ae5f8SJohn Marino {
159a45ae5f8SJohn Marino fi = get_next_frame (fi);
160a45ae5f8SJohn Marino gdb_assert (fi != NULL);
161a45ae5f8SJohn Marino }
162a45ae5f8SJohn Marino
163a45ae5f8SJohn Marino slot = htab_find_slot (cache_htab, &fi, NO_INSERT);
164a45ae5f8SJohn Marino if (slot == NULL)
165a45ae5f8SJohn Marino return NULL;
166a45ae5f8SJohn Marino
167a45ae5f8SJohn Marino cache = *slot;
168a45ae5f8SJohn Marino gdb_assert (cache != NULL);
169a45ae5f8SJohn Marino return cache;
170a45ae5f8SJohn Marino }
171a45ae5f8SJohn Marino
172a45ae5f8SJohn Marino /* Number of virtual frames between THIS_FRAME and CACHE->NEXT_BOTTOM_FRAME.
173a45ae5f8SJohn Marino If THIS_FRAME is CACHE-> NEXT_BOTTOM_FRAME return -1. */
174a45ae5f8SJohn Marino
175a45ae5f8SJohn Marino static int
existing_next_levels(struct frame_info * this_frame,struct tailcall_cache * cache)176a45ae5f8SJohn Marino existing_next_levels (struct frame_info *this_frame,
177a45ae5f8SJohn Marino struct tailcall_cache *cache)
178a45ae5f8SJohn Marino {
179a45ae5f8SJohn Marino int retval = (frame_relative_level (this_frame)
180a45ae5f8SJohn Marino - frame_relative_level (cache->next_bottom_frame) - 1);
181a45ae5f8SJohn Marino
182a45ae5f8SJohn Marino gdb_assert (retval >= -1);
183a45ae5f8SJohn Marino
184a45ae5f8SJohn Marino return retval;
185a45ae5f8SJohn Marino }
186a45ae5f8SJohn Marino
187a45ae5f8SJohn Marino /* The number of virtual tail call frames in CHAIN. With no virtual tail call
188a45ae5f8SJohn Marino frames the function would return 0 (but CHAIN does not exist in such
189a45ae5f8SJohn Marino case). */
190a45ae5f8SJohn Marino
191a45ae5f8SJohn Marino static int
pretended_chain_levels(struct call_site_chain * chain)192a45ae5f8SJohn Marino pretended_chain_levels (struct call_site_chain *chain)
193a45ae5f8SJohn Marino {
194a45ae5f8SJohn Marino int chain_levels;
195a45ae5f8SJohn Marino
196a45ae5f8SJohn Marino gdb_assert (chain != NULL);
197a45ae5f8SJohn Marino
198a45ae5f8SJohn Marino if (chain->callers == chain->length && chain->callees == chain->length)
199a45ae5f8SJohn Marino return chain->length;
200a45ae5f8SJohn Marino
201a45ae5f8SJohn Marino chain_levels = chain->callers + chain->callees;
202a45ae5f8SJohn Marino gdb_assert (chain_levels < chain->length);
203a45ae5f8SJohn Marino
204a45ae5f8SJohn Marino return chain_levels;
205a45ae5f8SJohn Marino }
206a45ae5f8SJohn Marino
207a45ae5f8SJohn Marino /* Implementation of frame_this_id_ftype. THIS_CACHE must be already
208a45ae5f8SJohn Marino initialized with tailcall_cache, THIS_FRAME must be a part of THIS_CACHE.
209a45ae5f8SJohn Marino
210a45ae5f8SJohn Marino Specific virtual tail call frames are tracked by INLINE_DEPTH. */
211a45ae5f8SJohn Marino
212a45ae5f8SJohn Marino static void
tailcall_frame_this_id(struct frame_info * this_frame,void ** this_cache,struct frame_id * this_id)213a45ae5f8SJohn Marino tailcall_frame_this_id (struct frame_info *this_frame, void **this_cache,
214a45ae5f8SJohn Marino struct frame_id *this_id)
215a45ae5f8SJohn Marino {
216a45ae5f8SJohn Marino struct tailcall_cache *cache = *this_cache;
217a45ae5f8SJohn Marino struct frame_info *next_frame;
218a45ae5f8SJohn Marino
219a45ae5f8SJohn Marino /* Tail call does not make sense for a sentinel frame. */
220a45ae5f8SJohn Marino next_frame = get_next_frame (this_frame);
221a45ae5f8SJohn Marino gdb_assert (next_frame != NULL);
222a45ae5f8SJohn Marino
223a45ae5f8SJohn Marino *this_id = get_frame_id (next_frame);
224a45ae5f8SJohn Marino (*this_id).code_addr = get_frame_pc (this_frame);
225a45ae5f8SJohn Marino (*this_id).code_addr_p = 1;
226*ef5ccd6cSJohn Marino (*this_id).artificial_depth = (cache->chain_levels
227a45ae5f8SJohn Marino - existing_next_levels (this_frame, cache));
228*ef5ccd6cSJohn Marino gdb_assert ((*this_id).artificial_depth > 0);
229a45ae5f8SJohn Marino }
230a45ae5f8SJohn Marino
231a45ae5f8SJohn Marino /* Find PC to be unwound from THIS_FRAME. THIS_FRAME must be a part of
232a45ae5f8SJohn Marino CACHE. */
233a45ae5f8SJohn Marino
234a45ae5f8SJohn Marino static CORE_ADDR
pretend_pc(struct frame_info * this_frame,struct tailcall_cache * cache)235a45ae5f8SJohn Marino pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache)
236a45ae5f8SJohn Marino {
237a45ae5f8SJohn Marino int next_levels = existing_next_levels (this_frame, cache);
238a45ae5f8SJohn Marino struct call_site_chain *chain = cache->chain;
239a45ae5f8SJohn Marino
240a45ae5f8SJohn Marino gdb_assert (chain != NULL);
241a45ae5f8SJohn Marino
242a45ae5f8SJohn Marino next_levels++;
243a45ae5f8SJohn Marino gdb_assert (next_levels >= 0);
244a45ae5f8SJohn Marino
245a45ae5f8SJohn Marino if (next_levels < chain->callees)
246a45ae5f8SJohn Marino return chain->call_site[chain->length - next_levels - 1]->pc;
247a45ae5f8SJohn Marino next_levels -= chain->callees;
248a45ae5f8SJohn Marino
249a45ae5f8SJohn Marino /* Otherwise CHAIN->CALLEES are already covered by CHAIN->CALLERS. */
250a45ae5f8SJohn Marino if (chain->callees != chain->length)
251a45ae5f8SJohn Marino {
252a45ae5f8SJohn Marino if (next_levels < chain->callers)
253a45ae5f8SJohn Marino return chain->call_site[chain->callers - next_levels - 1]->pc;
254a45ae5f8SJohn Marino next_levels -= chain->callers;
255a45ae5f8SJohn Marino }
256a45ae5f8SJohn Marino
257a45ae5f8SJohn Marino gdb_assert (next_levels == 0);
258a45ae5f8SJohn Marino return cache->prev_pc;
259a45ae5f8SJohn Marino }
260a45ae5f8SJohn Marino
261a45ae5f8SJohn Marino /* Implementation of frame_prev_register_ftype. If no specific register
262a45ae5f8SJohn Marino override is supplied NULL is returned (this is incompatible with
263a45ae5f8SJohn Marino frame_prev_register_ftype semantics). next_bottom_frame and tail call
264a45ae5f8SJohn Marino frames unwind the NULL case differently. */
265a45ae5f8SJohn Marino
266a45ae5f8SJohn Marino struct value *
dwarf2_tailcall_prev_register_first(struct frame_info * this_frame,void ** tailcall_cachep,int regnum)267a45ae5f8SJohn Marino dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
268a45ae5f8SJohn Marino void **tailcall_cachep, int regnum)
269a45ae5f8SJohn Marino {
270a45ae5f8SJohn Marino struct gdbarch *this_gdbarch = get_frame_arch (this_frame);
271a45ae5f8SJohn Marino struct tailcall_cache *cache = *tailcall_cachep;
272a45ae5f8SJohn Marino CORE_ADDR addr;
273a45ae5f8SJohn Marino
274a45ae5f8SJohn Marino if (regnum == gdbarch_pc_regnum (this_gdbarch))
275a45ae5f8SJohn Marino addr = pretend_pc (this_frame, cache);
276a45ae5f8SJohn Marino else if (cache->prev_sp_p && regnum == gdbarch_sp_regnum (this_gdbarch))
277a45ae5f8SJohn Marino {
278a45ae5f8SJohn Marino int next_levels = existing_next_levels (this_frame, cache);
279a45ae5f8SJohn Marino
280a45ae5f8SJohn Marino if (next_levels == cache->chain_levels - 1)
281a45ae5f8SJohn Marino addr = cache->prev_sp;
282a45ae5f8SJohn Marino else
283a45ae5f8SJohn Marino addr = dwarf2_frame_cfa (this_frame) - cache->entry_cfa_sp_offset;
284a45ae5f8SJohn Marino }
285a45ae5f8SJohn Marino else
286a45ae5f8SJohn Marino return NULL;
287a45ae5f8SJohn Marino
288a45ae5f8SJohn Marino return frame_unwind_got_address (this_frame, regnum, addr);
289a45ae5f8SJohn Marino }
290a45ae5f8SJohn Marino
291a45ae5f8SJohn Marino /* Implementation of frame_prev_register_ftype for tail call frames. Register
292a45ae5f8SJohn Marino set of virtual tail call frames is assumed to be the one of the top (caller)
293a45ae5f8SJohn Marino frame - assume unchanged register value for NULL from
294a45ae5f8SJohn Marino dwarf2_tailcall_prev_register_first. */
295a45ae5f8SJohn Marino
296a45ae5f8SJohn Marino static struct value *
tailcall_frame_prev_register(struct frame_info * this_frame,void ** this_cache,int regnum)297a45ae5f8SJohn Marino tailcall_frame_prev_register (struct frame_info *this_frame,
298a45ae5f8SJohn Marino void **this_cache, int regnum)
299a45ae5f8SJohn Marino {
300a45ae5f8SJohn Marino struct tailcall_cache *cache = *this_cache;
301a45ae5f8SJohn Marino struct value *val;
302a45ae5f8SJohn Marino
303a45ae5f8SJohn Marino gdb_assert (this_frame != cache->next_bottom_frame);
304a45ae5f8SJohn Marino
305a45ae5f8SJohn Marino val = dwarf2_tailcall_prev_register_first (this_frame, this_cache, regnum);
306a45ae5f8SJohn Marino if (val)
307a45ae5f8SJohn Marino return val;
308a45ae5f8SJohn Marino
309a45ae5f8SJohn Marino return frame_unwind_got_register (this_frame, regnum, regnum);
310a45ae5f8SJohn Marino }
311a45ae5f8SJohn Marino
312a45ae5f8SJohn Marino /* Implementation of frame_sniffer_ftype. It will never find a new chain, use
313a45ae5f8SJohn Marino dwarf2_tailcall_sniffer_first for the bottom (callee) frame. It will find
314a45ae5f8SJohn Marino all the predecessing virtual tail call frames, it will return false when
315a45ae5f8SJohn Marino there exist no more tail call frames in this chain. */
316a45ae5f8SJohn Marino
317a45ae5f8SJohn Marino static int
tailcall_frame_sniffer(const struct frame_unwind * self,struct frame_info * this_frame,void ** this_cache)318a45ae5f8SJohn Marino tailcall_frame_sniffer (const struct frame_unwind *self,
319a45ae5f8SJohn Marino struct frame_info *this_frame, void **this_cache)
320a45ae5f8SJohn Marino {
321a45ae5f8SJohn Marino struct frame_info *next_frame;
322a45ae5f8SJohn Marino int next_levels;
323a45ae5f8SJohn Marino struct tailcall_cache *cache;
324a45ae5f8SJohn Marino
325a45ae5f8SJohn Marino /* Inner tail call element does not make sense for a sentinel frame. */
326a45ae5f8SJohn Marino next_frame = get_next_frame (this_frame);
327a45ae5f8SJohn Marino if (next_frame == NULL)
328a45ae5f8SJohn Marino return 0;
329a45ae5f8SJohn Marino
330a45ae5f8SJohn Marino cache = cache_find (next_frame);
331a45ae5f8SJohn Marino if (cache == NULL)
332a45ae5f8SJohn Marino return 0;
333a45ae5f8SJohn Marino
334a45ae5f8SJohn Marino cache_ref (cache);
335a45ae5f8SJohn Marino
336a45ae5f8SJohn Marino next_levels = existing_next_levels (this_frame, cache);
337a45ae5f8SJohn Marino
338a45ae5f8SJohn Marino /* NEXT_LEVELS is -1 only in dwarf2_tailcall_sniffer_first. */
339a45ae5f8SJohn Marino gdb_assert (next_levels >= 0);
340a45ae5f8SJohn Marino gdb_assert (next_levels <= cache->chain_levels);
341a45ae5f8SJohn Marino
342a45ae5f8SJohn Marino if (next_levels == cache->chain_levels)
343a45ae5f8SJohn Marino {
344a45ae5f8SJohn Marino cache_unref (cache);
345a45ae5f8SJohn Marino return 0;
346a45ae5f8SJohn Marino }
347a45ae5f8SJohn Marino
348a45ae5f8SJohn Marino *this_cache = cache;
349a45ae5f8SJohn Marino return 1;
350a45ae5f8SJohn Marino }
351a45ae5f8SJohn Marino
352a45ae5f8SJohn Marino /* The initial "sniffer" whether THIS_FRAME is a bottom (callee) frame of a new
353a45ae5f8SJohn Marino chain to create. Keep TAILCALL_CACHEP NULL if it did not find any chain,
354a45ae5f8SJohn Marino initialize it otherwise. No tail call chain is created if there are no
355a45ae5f8SJohn Marino unambiguous virtual tail call frames to report.
356a45ae5f8SJohn Marino
357a45ae5f8SJohn Marino ENTRY_CFA_SP_OFFSETP is NULL if no special SP handling is possible,
358a45ae5f8SJohn Marino otherwise *ENTRY_CFA_SP_OFFSETP is the number of bytes to subtract from tail
359a45ae5f8SJohn Marino call frames frame base to get the SP value there - to simulate return
360a45ae5f8SJohn Marino address pushed on the stack. */
361a45ae5f8SJohn Marino
362a45ae5f8SJohn Marino void
dwarf2_tailcall_sniffer_first(struct frame_info * this_frame,void ** tailcall_cachep,const LONGEST * entry_cfa_sp_offsetp)363a45ae5f8SJohn Marino dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
364a45ae5f8SJohn Marino void **tailcall_cachep,
365a45ae5f8SJohn Marino const LONGEST *entry_cfa_sp_offsetp)
366a45ae5f8SJohn Marino {
367a45ae5f8SJohn Marino CORE_ADDR prev_pc = 0, prev_sp = 0; /* GCC warning. */
368a45ae5f8SJohn Marino int prev_sp_p = 0;
369*ef5ccd6cSJohn Marino CORE_ADDR this_pc;
370a45ae5f8SJohn Marino struct gdbarch *prev_gdbarch;
371a45ae5f8SJohn Marino struct call_site_chain *chain = NULL;
372a45ae5f8SJohn Marino struct tailcall_cache *cache;
373a45ae5f8SJohn Marino volatile struct gdb_exception except;
374a45ae5f8SJohn Marino
375a45ae5f8SJohn Marino gdb_assert (*tailcall_cachep == NULL);
376a45ae5f8SJohn Marino
377*ef5ccd6cSJohn Marino /* PC may be after the function if THIS_FRAME calls noreturn function,
378*ef5ccd6cSJohn Marino get_frame_address_in_block will decrease it by 1 in such case. */
379*ef5ccd6cSJohn Marino this_pc = get_frame_address_in_block (this_frame);
380a45ae5f8SJohn Marino
381a45ae5f8SJohn Marino /* Catch any unwinding errors. */
382a45ae5f8SJohn Marino TRY_CATCH (except, RETURN_MASK_ERROR)
383a45ae5f8SJohn Marino {
384a45ae5f8SJohn Marino int sp_regnum;
385a45ae5f8SJohn Marino
386a45ae5f8SJohn Marino prev_gdbarch = frame_unwind_arch (this_frame);
387a45ae5f8SJohn Marino
388a45ae5f8SJohn Marino /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p. */
389a45ae5f8SJohn Marino prev_pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
390a45ae5f8SJohn Marino
391a45ae5f8SJohn Marino /* call_site_find_chain can throw an exception. */
392a45ae5f8SJohn Marino chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);
393a45ae5f8SJohn Marino
394a45ae5f8SJohn Marino if (entry_cfa_sp_offsetp == NULL)
395a45ae5f8SJohn Marino break;
396a45ae5f8SJohn Marino sp_regnum = gdbarch_sp_regnum (prev_gdbarch);
397a45ae5f8SJohn Marino if (sp_regnum == -1)
398a45ae5f8SJohn Marino break;
399a45ae5f8SJohn Marino prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum);
400a45ae5f8SJohn Marino prev_sp_p = 1;
401a45ae5f8SJohn Marino }
402a45ae5f8SJohn Marino if (except.reason < 0)
403a45ae5f8SJohn Marino {
404a45ae5f8SJohn Marino if (entry_values_debug)
405a45ae5f8SJohn Marino exception_print (gdb_stdout, except);
406a45ae5f8SJohn Marino return;
407a45ae5f8SJohn Marino }
408a45ae5f8SJohn Marino
409a45ae5f8SJohn Marino /* Ambiguous unwind or unambiguous unwind verified as matching. */
410a45ae5f8SJohn Marino if (chain == NULL || chain->length == 0)
411a45ae5f8SJohn Marino {
412a45ae5f8SJohn Marino xfree (chain);
413a45ae5f8SJohn Marino return;
414a45ae5f8SJohn Marino }
415a45ae5f8SJohn Marino
416a45ae5f8SJohn Marino cache = cache_new_ref1 (this_frame);
417a45ae5f8SJohn Marino *tailcall_cachep = cache;
418a45ae5f8SJohn Marino cache->chain = chain;
419a45ae5f8SJohn Marino cache->prev_pc = prev_pc;
420a45ae5f8SJohn Marino cache->chain_levels = pretended_chain_levels (chain);
421a45ae5f8SJohn Marino cache->prev_sp_p = prev_sp_p;
422a45ae5f8SJohn Marino if (cache->prev_sp_p)
423a45ae5f8SJohn Marino {
424a45ae5f8SJohn Marino cache->prev_sp = prev_sp;
425a45ae5f8SJohn Marino cache->entry_cfa_sp_offset = *entry_cfa_sp_offsetp;
426a45ae5f8SJohn Marino }
427a45ae5f8SJohn Marino gdb_assert (cache->chain_levels > 0);
428a45ae5f8SJohn Marino }
429a45ae5f8SJohn Marino
430a45ae5f8SJohn Marino /* Implementation of frame_dealloc_cache_ftype. It can be called even for the
431a45ae5f8SJohn Marino bottom chain frame from dwarf2_frame_dealloc_cache which is not a real
432a45ae5f8SJohn Marino TAILCALL_FRAME. */
433a45ae5f8SJohn Marino
434a45ae5f8SJohn Marino static void
tailcall_frame_dealloc_cache(struct frame_info * self,void * this_cache)435a45ae5f8SJohn Marino tailcall_frame_dealloc_cache (struct frame_info *self, void *this_cache)
436a45ae5f8SJohn Marino {
437a45ae5f8SJohn Marino struct tailcall_cache *cache = this_cache;
438a45ae5f8SJohn Marino
439a45ae5f8SJohn Marino cache_unref (cache);
440a45ae5f8SJohn Marino }
441a45ae5f8SJohn Marino
442a45ae5f8SJohn Marino /* Implementation of frame_prev_arch_ftype. We assume all the virtual tail
443a45ae5f8SJohn Marino call frames have gdbarch of the bottom (callee) frame. */
444a45ae5f8SJohn Marino
445a45ae5f8SJohn Marino static struct gdbarch *
tailcall_frame_prev_arch(struct frame_info * this_frame,void ** this_prologue_cache)446a45ae5f8SJohn Marino tailcall_frame_prev_arch (struct frame_info *this_frame,
447a45ae5f8SJohn Marino void **this_prologue_cache)
448a45ae5f8SJohn Marino {
449a45ae5f8SJohn Marino struct tailcall_cache *cache = *this_prologue_cache;
450a45ae5f8SJohn Marino
451a45ae5f8SJohn Marino return get_frame_arch (cache->next_bottom_frame);
452a45ae5f8SJohn Marino }
453a45ae5f8SJohn Marino
454a45ae5f8SJohn Marino /* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds
455a45ae5f8SJohn Marino a chain to create. */
456a45ae5f8SJohn Marino
457a45ae5f8SJohn Marino const struct frame_unwind dwarf2_tailcall_frame_unwind =
458a45ae5f8SJohn Marino {
459a45ae5f8SJohn Marino TAILCALL_FRAME,
460a45ae5f8SJohn Marino default_frame_unwind_stop_reason,
461a45ae5f8SJohn Marino tailcall_frame_this_id,
462a45ae5f8SJohn Marino tailcall_frame_prev_register,
463a45ae5f8SJohn Marino NULL,
464a45ae5f8SJohn Marino tailcall_frame_sniffer,
465a45ae5f8SJohn Marino tailcall_frame_dealloc_cache,
466a45ae5f8SJohn Marino tailcall_frame_prev_arch
467a45ae5f8SJohn Marino };
468a45ae5f8SJohn Marino
469a45ae5f8SJohn Marino /* Provide a prototype to silence -Wmissing-prototypes. */
470a45ae5f8SJohn Marino extern initialize_file_ftype _initialize_tailcall_frame;
471a45ae5f8SJohn Marino
472a45ae5f8SJohn Marino void
_initialize_tailcall_frame(void)473a45ae5f8SJohn Marino _initialize_tailcall_frame (void)
474a45ae5f8SJohn Marino {
475a45ae5f8SJohn Marino cache_htab = htab_create_alloc (50, cache_hash, cache_eq, NULL, xcalloc,
476a45ae5f8SJohn Marino xfree);
477a45ae5f8SJohn Marino }
478