xref: /dflybsd-src/contrib/gdb-7/gdb/dwarf2-frame-tailcall.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
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