17d62b00eSchristos /* Virtual tail call frames unwinder for GDB. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 2010-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #include "defs.h" 217d62b00eSchristos #include "frame.h" 227d62b00eSchristos #include "dwarf2/frame-tailcall.h" 237d62b00eSchristos #include "dwarf2/loc.h" 247d62b00eSchristos #include "frame-unwind.h" 257d62b00eSchristos #include "block.h" 267d62b00eSchristos #include "hashtab.h" 277d62b00eSchristos #include "gdbtypes.h" 287d62b00eSchristos #include "regcache.h" 297d62b00eSchristos #include "value.h" 307d62b00eSchristos #include "dwarf2/frame.h" 317d62b00eSchristos #include "gdbarch.h" 327d62b00eSchristos 337d62b00eSchristos /* Contains struct tailcall_cache indexed by next_bottom_frame. */ 347d62b00eSchristos static htab_t cache_htab; 357d62b00eSchristos 367d62b00eSchristos /* Associate structure of the unwinder to call_site_chain. Lifetime of this 377d62b00eSchristos structure is maintained by REFC decremented by dealloc_cache, all of them 387d62b00eSchristos get deleted during reinit_frame_cache. */ 397d62b00eSchristos struct tailcall_cache 407d62b00eSchristos { 417d62b00eSchristos /* It must be the first one of this struct. It is the furthest callee. */ 42*6881a400Schristos frame_info *next_bottom_frame; 437d62b00eSchristos 447d62b00eSchristos /* Reference count. The whole chain of virtual tail call frames shares one 457d62b00eSchristos tailcall_cache. */ 467d62b00eSchristos int refc; 477d62b00eSchristos 487d62b00eSchristos /* Associated found virtual tail call frames chain, it is never NULL. */ 497d62b00eSchristos struct call_site_chain *chain; 507d62b00eSchristos 517d62b00eSchristos /* Cached pretended_chain_levels result. */ 527d62b00eSchristos int chain_levels; 537d62b00eSchristos 547d62b00eSchristos /* Unwound PC from the top (caller) frame, as it is not contained 557d62b00eSchristos in CHAIN. */ 567d62b00eSchristos CORE_ADDR prev_pc; 577d62b00eSchristos 587d62b00eSchristos /* Compensate SP in caller frames appropriately. prev_sp and 597d62b00eSchristos entry_cfa_sp_offset are valid only if PREV_SP_P. PREV_SP is SP at the top 607d62b00eSchristos (caller) frame. ENTRY_CFA_SP_OFFSET is shift of SP in tail call frames 617d62b00eSchristos against next_bottom_frame SP. */ 627d62b00eSchristos unsigned prev_sp_p : 1; 637d62b00eSchristos CORE_ADDR prev_sp; 647d62b00eSchristos LONGEST entry_cfa_sp_offset; 657d62b00eSchristos }; 667d62b00eSchristos 677d62b00eSchristos /* hash_f for htab_create_alloc of cache_htab. */ 687d62b00eSchristos 697d62b00eSchristos static hashval_t 707d62b00eSchristos cache_hash (const void *arg) 717d62b00eSchristos { 727d62b00eSchristos const struct tailcall_cache *cache = (const struct tailcall_cache *) arg; 737d62b00eSchristos 747d62b00eSchristos return htab_hash_pointer (cache->next_bottom_frame); 757d62b00eSchristos } 767d62b00eSchristos 777d62b00eSchristos /* eq_f for htab_create_alloc of cache_htab. */ 787d62b00eSchristos 797d62b00eSchristos static int 807d62b00eSchristos cache_eq (const void *arg1, const void *arg2) 817d62b00eSchristos { 827d62b00eSchristos const struct tailcall_cache *cache1 = (const struct tailcall_cache *) arg1; 837d62b00eSchristos const struct tailcall_cache *cache2 = (const struct tailcall_cache *) arg2; 847d62b00eSchristos 857d62b00eSchristos return cache1->next_bottom_frame == cache2->next_bottom_frame; 867d62b00eSchristos } 877d62b00eSchristos 887d62b00eSchristos /* Create new tailcall_cache for NEXT_BOTTOM_FRAME, NEXT_BOTTOM_FRAME must not 897d62b00eSchristos yet have been indexed by cache_htab. Caller holds one reference of the new 907d62b00eSchristos tailcall_cache. */ 917d62b00eSchristos 927d62b00eSchristos static struct tailcall_cache * 93*6881a400Schristos cache_new_ref1 (frame_info_ptr next_bottom_frame) 947d62b00eSchristos { 957d62b00eSchristos struct tailcall_cache *cache = XCNEW (struct tailcall_cache); 967d62b00eSchristos void **slot; 977d62b00eSchristos 98*6881a400Schristos cache->next_bottom_frame = next_bottom_frame.get (); 997d62b00eSchristos cache->refc = 1; 1007d62b00eSchristos 1017d62b00eSchristos slot = htab_find_slot (cache_htab, cache, INSERT); 1027d62b00eSchristos gdb_assert (*slot == NULL); 1037d62b00eSchristos *slot = cache; 1047d62b00eSchristos 1057d62b00eSchristos return cache; 1067d62b00eSchristos } 1077d62b00eSchristos 1087d62b00eSchristos /* Create new reference to CACHE. */ 1097d62b00eSchristos 1107d62b00eSchristos static void 1117d62b00eSchristos cache_ref (struct tailcall_cache *cache) 1127d62b00eSchristos { 1137d62b00eSchristos gdb_assert (cache->refc > 0); 1147d62b00eSchristos 1157d62b00eSchristos cache->refc++; 1167d62b00eSchristos } 1177d62b00eSchristos 1187d62b00eSchristos /* Drop reference to CACHE, possibly fully freeing it and unregistering it from 1197d62b00eSchristos cache_htab. */ 1207d62b00eSchristos 1217d62b00eSchristos static void 1227d62b00eSchristos cache_unref (struct tailcall_cache *cache) 1237d62b00eSchristos { 1247d62b00eSchristos gdb_assert (cache->refc > 0); 1257d62b00eSchristos 1267d62b00eSchristos if (!--cache->refc) 1277d62b00eSchristos { 1287d62b00eSchristos gdb_assert (htab_find_slot (cache_htab, cache, NO_INSERT) != NULL); 1297d62b00eSchristos htab_remove_elt (cache_htab, cache); 1307d62b00eSchristos 1317d62b00eSchristos xfree (cache->chain); 1327d62b00eSchristos xfree (cache); 1337d62b00eSchristos } 1347d62b00eSchristos } 1357d62b00eSchristos 1367d62b00eSchristos /* Return 1 if FI is a non-bottom (not the callee) tail call frame. Otherwise 1377d62b00eSchristos return 0. */ 1387d62b00eSchristos 1397d62b00eSchristos static int 140*6881a400Schristos frame_is_tailcall (frame_info_ptr fi) 1417d62b00eSchristos { 1427d62b00eSchristos return frame_unwinder_is (fi, &dwarf2_tailcall_frame_unwind); 1437d62b00eSchristos } 1447d62b00eSchristos 1457d62b00eSchristos /* Try to find tailcall_cache in cache_htab if FI is a part of its virtual tail 1467d62b00eSchristos call chain. Otherwise return NULL. No new reference is created. */ 1477d62b00eSchristos 1487d62b00eSchristos static struct tailcall_cache * 149*6881a400Schristos cache_find (frame_info_ptr fi) 1507d62b00eSchristos { 1517d62b00eSchristos struct tailcall_cache *cache; 152*6881a400Schristos struct tailcall_cache search; 1537d62b00eSchristos void **slot; 1547d62b00eSchristos 1557d62b00eSchristos while (frame_is_tailcall (fi)) 1567d62b00eSchristos { 1577d62b00eSchristos fi = get_next_frame (fi); 1587d62b00eSchristos gdb_assert (fi != NULL); 1597d62b00eSchristos } 1607d62b00eSchristos 161*6881a400Schristos search.next_bottom_frame = fi.get(); 162*6881a400Schristos search.refc = 1; 163*6881a400Schristos slot = htab_find_slot (cache_htab, &search, NO_INSERT); 1647d62b00eSchristos if (slot == NULL) 1657d62b00eSchristos return NULL; 1667d62b00eSchristos 1677d62b00eSchristos cache = (struct tailcall_cache *) *slot; 1687d62b00eSchristos gdb_assert (cache != NULL); 1697d62b00eSchristos return cache; 1707d62b00eSchristos } 1717d62b00eSchristos 1727d62b00eSchristos /* Number of virtual frames between THIS_FRAME and CACHE->NEXT_BOTTOM_FRAME. 1737d62b00eSchristos If THIS_FRAME is CACHE-> NEXT_BOTTOM_FRAME return -1. */ 1747d62b00eSchristos 1757d62b00eSchristos static int 176*6881a400Schristos existing_next_levels (frame_info_ptr this_frame, 1777d62b00eSchristos struct tailcall_cache *cache) 1787d62b00eSchristos { 1797d62b00eSchristos int retval = (frame_relative_level (this_frame) 180*6881a400Schristos - frame_relative_level (frame_info_ptr (cache->next_bottom_frame)) - 1); 1817d62b00eSchristos 1827d62b00eSchristos gdb_assert (retval >= -1); 1837d62b00eSchristos 1847d62b00eSchristos return retval; 1857d62b00eSchristos } 1867d62b00eSchristos 1877d62b00eSchristos /* The number of virtual tail call frames in CHAIN. With no virtual tail call 1887d62b00eSchristos frames the function would return 0 (but CHAIN does not exist in such 1897d62b00eSchristos case). */ 1907d62b00eSchristos 1917d62b00eSchristos static int 1927d62b00eSchristos pretended_chain_levels (struct call_site_chain *chain) 1937d62b00eSchristos { 1947d62b00eSchristos int chain_levels; 1957d62b00eSchristos 1967d62b00eSchristos gdb_assert (chain != NULL); 1977d62b00eSchristos 1987d62b00eSchristos if (chain->callers == chain->length && chain->callees == chain->length) 1997d62b00eSchristos return chain->length; 2007d62b00eSchristos 2017d62b00eSchristos chain_levels = chain->callers + chain->callees; 2027d62b00eSchristos gdb_assert (chain_levels <= chain->length); 2037d62b00eSchristos 2047d62b00eSchristos return chain_levels; 2057d62b00eSchristos } 2067d62b00eSchristos 2077d62b00eSchristos /* Implementation of frame_this_id_ftype. THIS_CACHE must be already 2087d62b00eSchristos initialized with tailcall_cache, THIS_FRAME must be a part of THIS_CACHE. 2097d62b00eSchristos 2107d62b00eSchristos Specific virtual tail call frames are tracked by INLINE_DEPTH. */ 2117d62b00eSchristos 2127d62b00eSchristos static void 213*6881a400Schristos tailcall_frame_this_id (frame_info_ptr this_frame, void **this_cache, 2147d62b00eSchristos struct frame_id *this_id) 2157d62b00eSchristos { 2167d62b00eSchristos struct tailcall_cache *cache = (struct tailcall_cache *) *this_cache; 217*6881a400Schristos frame_info_ptr next_frame; 2187d62b00eSchristos 2197d62b00eSchristos /* Tail call does not make sense for a sentinel frame. */ 2207d62b00eSchristos next_frame = get_next_frame (this_frame); 2217d62b00eSchristos gdb_assert (next_frame != NULL); 2227d62b00eSchristos 2237d62b00eSchristos *this_id = get_frame_id (next_frame); 2247d62b00eSchristos (*this_id).code_addr = get_frame_pc (this_frame); 2257d62b00eSchristos (*this_id).code_addr_p = true; 2267d62b00eSchristos (*this_id).artificial_depth = (cache->chain_levels 2277d62b00eSchristos - existing_next_levels (this_frame, cache)); 2287d62b00eSchristos gdb_assert ((*this_id).artificial_depth > 0); 2297d62b00eSchristos } 2307d62b00eSchristos 2317d62b00eSchristos /* Find PC to be unwound from THIS_FRAME. THIS_FRAME must be a part of 2327d62b00eSchristos CACHE. */ 2337d62b00eSchristos 2347d62b00eSchristos static CORE_ADDR 235*6881a400Schristos pretend_pc (frame_info_ptr this_frame, struct tailcall_cache *cache) 2367d62b00eSchristos { 2377d62b00eSchristos int next_levels = existing_next_levels (this_frame, cache); 2387d62b00eSchristos struct call_site_chain *chain = cache->chain; 2397d62b00eSchristos 2407d62b00eSchristos gdb_assert (chain != NULL); 2417d62b00eSchristos 2427d62b00eSchristos next_levels++; 2437d62b00eSchristos gdb_assert (next_levels >= 0); 2447d62b00eSchristos 2457d62b00eSchristos if (next_levels < chain->callees) 246*6881a400Schristos return chain->call_site[chain->length - next_levels - 1]->pc (); 2477d62b00eSchristos next_levels -= chain->callees; 2487d62b00eSchristos 2497d62b00eSchristos /* Otherwise CHAIN->CALLEES are already covered by CHAIN->CALLERS. */ 2507d62b00eSchristos if (chain->callees != chain->length) 2517d62b00eSchristos { 2527d62b00eSchristos if (next_levels < chain->callers) 253*6881a400Schristos return chain->call_site[chain->callers - next_levels - 1]->pc (); 2547d62b00eSchristos next_levels -= chain->callers; 2557d62b00eSchristos } 2567d62b00eSchristos 2577d62b00eSchristos gdb_assert (next_levels == 0); 2587d62b00eSchristos return cache->prev_pc; 2597d62b00eSchristos } 2607d62b00eSchristos 2617d62b00eSchristos /* Implementation of frame_prev_register_ftype. If no specific register 2627d62b00eSchristos override is supplied NULL is returned (this is incompatible with 2637d62b00eSchristos frame_prev_register_ftype semantics). next_bottom_frame and tail call 2647d62b00eSchristos frames unwind the NULL case differently. */ 2657d62b00eSchristos 2667d62b00eSchristos struct value * 267*6881a400Schristos dwarf2_tailcall_prev_register_first (frame_info_ptr this_frame, 2687d62b00eSchristos void **tailcall_cachep, int regnum) 2697d62b00eSchristos { 2707d62b00eSchristos struct gdbarch *this_gdbarch = get_frame_arch (this_frame); 2717d62b00eSchristos struct tailcall_cache *cache = (struct tailcall_cache *) *tailcall_cachep; 2727d62b00eSchristos CORE_ADDR addr; 2737d62b00eSchristos 2747d62b00eSchristos if (regnum == gdbarch_pc_regnum (this_gdbarch)) 2757d62b00eSchristos addr = pretend_pc (this_frame, cache); 2767d62b00eSchristos else if (cache->prev_sp_p && regnum == gdbarch_sp_regnum (this_gdbarch)) 2777d62b00eSchristos { 2787d62b00eSchristos int next_levels = existing_next_levels (this_frame, cache); 2797d62b00eSchristos 2807d62b00eSchristos if (next_levels == cache->chain_levels - 1) 2817d62b00eSchristos addr = cache->prev_sp; 2827d62b00eSchristos else 2837d62b00eSchristos addr = dwarf2_frame_cfa (this_frame) - cache->entry_cfa_sp_offset; 2847d62b00eSchristos } 2857d62b00eSchristos else 2867d62b00eSchristos return NULL; 2877d62b00eSchristos 2887d62b00eSchristos return frame_unwind_got_address (this_frame, regnum, addr); 2897d62b00eSchristos } 2907d62b00eSchristos 2917d62b00eSchristos /* Implementation of frame_prev_register_ftype for tail call frames. Register 2927d62b00eSchristos set of virtual tail call frames is assumed to be the one of the top (caller) 2937d62b00eSchristos frame - assume unchanged register value for NULL from 2947d62b00eSchristos dwarf2_tailcall_prev_register_first. */ 2957d62b00eSchristos 2967d62b00eSchristos static struct value * 297*6881a400Schristos tailcall_frame_prev_register (frame_info_ptr this_frame, 2987d62b00eSchristos void **this_cache, int regnum) 2997d62b00eSchristos { 3007d62b00eSchristos struct tailcall_cache *cache = (struct tailcall_cache *) *this_cache; 3017d62b00eSchristos struct value *val; 3027d62b00eSchristos 3037d62b00eSchristos gdb_assert (this_frame != cache->next_bottom_frame); 3047d62b00eSchristos 3057d62b00eSchristos val = dwarf2_tailcall_prev_register_first (this_frame, this_cache, regnum); 3067d62b00eSchristos if (val) 3077d62b00eSchristos return val; 3087d62b00eSchristos 3097d62b00eSchristos return frame_unwind_got_register (this_frame, regnum, regnum); 3107d62b00eSchristos } 3117d62b00eSchristos 3127d62b00eSchristos /* Implementation of frame_sniffer_ftype. It will never find a new chain, use 3137d62b00eSchristos dwarf2_tailcall_sniffer_first for the bottom (callee) frame. It will find 3147d62b00eSchristos all the predecessing virtual tail call frames, it will return false when 3157d62b00eSchristos there exist no more tail call frames in this chain. */ 3167d62b00eSchristos 3177d62b00eSchristos static int 3187d62b00eSchristos tailcall_frame_sniffer (const struct frame_unwind *self, 319*6881a400Schristos frame_info_ptr this_frame, void **this_cache) 3207d62b00eSchristos { 321*6881a400Schristos frame_info_ptr next_frame; 3227d62b00eSchristos int next_levels; 3237d62b00eSchristos struct tailcall_cache *cache; 3247d62b00eSchristos 3257d62b00eSchristos if (!dwarf2_frame_unwinders_enabled_p) 3267d62b00eSchristos return 0; 3277d62b00eSchristos 3287d62b00eSchristos /* Inner tail call element does not make sense for a sentinel frame. */ 3297d62b00eSchristos next_frame = get_next_frame (this_frame); 3307d62b00eSchristos if (next_frame == NULL) 3317d62b00eSchristos return 0; 3327d62b00eSchristos 3337d62b00eSchristos cache = cache_find (next_frame); 3347d62b00eSchristos if (cache == NULL) 3357d62b00eSchristos return 0; 3367d62b00eSchristos 3377d62b00eSchristos cache_ref (cache); 3387d62b00eSchristos 3397d62b00eSchristos next_levels = existing_next_levels (this_frame, cache); 3407d62b00eSchristos 3417d62b00eSchristos /* NEXT_LEVELS is -1 only in dwarf2_tailcall_sniffer_first. */ 3427d62b00eSchristos gdb_assert (next_levels >= 0); 3437d62b00eSchristos gdb_assert (next_levels <= cache->chain_levels); 3447d62b00eSchristos 3457d62b00eSchristos if (next_levels == cache->chain_levels) 3467d62b00eSchristos { 3477d62b00eSchristos cache_unref (cache); 3487d62b00eSchristos return 0; 3497d62b00eSchristos } 3507d62b00eSchristos 3517d62b00eSchristos *this_cache = cache; 3527d62b00eSchristos return 1; 3537d62b00eSchristos } 3547d62b00eSchristos 3557d62b00eSchristos /* The initial "sniffer" whether THIS_FRAME is a bottom (callee) frame of a new 3567d62b00eSchristos chain to create. Keep TAILCALL_CACHEP NULL if it did not find any chain, 3577d62b00eSchristos initialize it otherwise. No tail call chain is created if there are no 3587d62b00eSchristos unambiguous virtual tail call frames to report. 3597d62b00eSchristos 3607d62b00eSchristos ENTRY_CFA_SP_OFFSETP is NULL if no special SP handling is possible, 3617d62b00eSchristos otherwise *ENTRY_CFA_SP_OFFSETP is the number of bytes to subtract from tail 3627d62b00eSchristos call frames frame base to get the SP value there - to simulate return 3637d62b00eSchristos address pushed on the stack. */ 3647d62b00eSchristos 3657d62b00eSchristos void 366*6881a400Schristos dwarf2_tailcall_sniffer_first (frame_info_ptr this_frame, 3677d62b00eSchristos void **tailcall_cachep, 3687d62b00eSchristos const LONGEST *entry_cfa_sp_offsetp) 3697d62b00eSchristos { 3707d62b00eSchristos CORE_ADDR prev_pc = 0, prev_sp = 0; /* GCC warning. */ 3717d62b00eSchristos int prev_sp_p = 0; 3727d62b00eSchristos CORE_ADDR this_pc; 3737d62b00eSchristos struct gdbarch *prev_gdbarch; 3747d62b00eSchristos gdb::unique_xmalloc_ptr<call_site_chain> chain; 3757d62b00eSchristos struct tailcall_cache *cache; 3767d62b00eSchristos 3777d62b00eSchristos gdb_assert (*tailcall_cachep == NULL); 3787d62b00eSchristos 3797d62b00eSchristos /* PC may be after the function if THIS_FRAME calls noreturn function, 3807d62b00eSchristos get_frame_address_in_block will decrease it by 1 in such case. */ 3817d62b00eSchristos this_pc = get_frame_address_in_block (this_frame); 3827d62b00eSchristos 3837d62b00eSchristos try 3847d62b00eSchristos { 3857d62b00eSchristos int sp_regnum; 3867d62b00eSchristos 3877d62b00eSchristos prev_gdbarch = frame_unwind_arch (this_frame); 3887d62b00eSchristos 3897d62b00eSchristos /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p. */ 3907d62b00eSchristos prev_pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); 3917d62b00eSchristos 3927d62b00eSchristos /* call_site_find_chain can throw an exception. */ 3937d62b00eSchristos chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc); 3947d62b00eSchristos 3957d62b00eSchristos if (entry_cfa_sp_offsetp != NULL) 3967d62b00eSchristos { 3977d62b00eSchristos sp_regnum = gdbarch_sp_regnum (prev_gdbarch); 3987d62b00eSchristos if (sp_regnum != -1) 3997d62b00eSchristos { 4007d62b00eSchristos prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum); 4017d62b00eSchristos prev_sp_p = 1; 4027d62b00eSchristos } 4037d62b00eSchristos } 4047d62b00eSchristos } 4057d62b00eSchristos catch (const gdb_exception_error &except) 4067d62b00eSchristos { 4077d62b00eSchristos if (entry_values_debug) 4087d62b00eSchristos exception_print (gdb_stdout, except); 4097d62b00eSchristos 4107d62b00eSchristos switch (except.error) 4117d62b00eSchristos { 4127d62b00eSchristos case NO_ENTRY_VALUE_ERROR: 4137d62b00eSchristos /* Thrown by call_site_find_chain. */ 4147d62b00eSchristos case MEMORY_ERROR: 4157d62b00eSchristos case OPTIMIZED_OUT_ERROR: 4167d62b00eSchristos case NOT_AVAILABLE_ERROR: 4177d62b00eSchristos /* These can normally happen when we try to access an 4187d62b00eSchristos optimized out or unavailable register, either in a 4197d62b00eSchristos physical register or spilled to memory. */ 4207d62b00eSchristos return; 4217d62b00eSchristos } 4227d62b00eSchristos 4237d62b00eSchristos /* Let unexpected errors propagate. */ 4247d62b00eSchristos throw; 4257d62b00eSchristos } 4267d62b00eSchristos 4277d62b00eSchristos /* Ambiguous unwind or unambiguous unwind verified as matching. */ 4287d62b00eSchristos if (chain == NULL || chain->length == 0) 4297d62b00eSchristos return; 4307d62b00eSchristos 4317d62b00eSchristos cache = cache_new_ref1 (this_frame); 4327d62b00eSchristos *tailcall_cachep = cache; 4337d62b00eSchristos cache->chain = chain.release (); 4347d62b00eSchristos cache->prev_pc = prev_pc; 4357d62b00eSchristos cache->chain_levels = pretended_chain_levels (cache->chain); 4367d62b00eSchristos cache->prev_sp_p = prev_sp_p; 4377d62b00eSchristos if (cache->prev_sp_p) 4387d62b00eSchristos { 4397d62b00eSchristos cache->prev_sp = prev_sp; 4407d62b00eSchristos cache->entry_cfa_sp_offset = *entry_cfa_sp_offsetp; 4417d62b00eSchristos } 4427d62b00eSchristos gdb_assert (cache->chain_levels > 0); 4437d62b00eSchristos } 4447d62b00eSchristos 4457d62b00eSchristos /* Implementation of frame_dealloc_cache_ftype. It can be called even for the 4467d62b00eSchristos bottom chain frame from dwarf2_frame_dealloc_cache which is not a real 4477d62b00eSchristos TAILCALL_FRAME. */ 4487d62b00eSchristos 4497d62b00eSchristos static void 450*6881a400Schristos tailcall_frame_dealloc_cache (frame_info *self, void *this_cache) 4517d62b00eSchristos { 4527d62b00eSchristos struct tailcall_cache *cache = (struct tailcall_cache *) this_cache; 4537d62b00eSchristos 4547d62b00eSchristos cache_unref (cache); 4557d62b00eSchristos } 4567d62b00eSchristos 4577d62b00eSchristos /* Implementation of frame_prev_arch_ftype. We assume all the virtual tail 4587d62b00eSchristos call frames have gdbarch of the bottom (callee) frame. */ 4597d62b00eSchristos 4607d62b00eSchristos static struct gdbarch * 461*6881a400Schristos tailcall_frame_prev_arch (frame_info_ptr this_frame, 4627d62b00eSchristos void **this_prologue_cache) 4637d62b00eSchristos { 4647d62b00eSchristos struct tailcall_cache *cache = (struct tailcall_cache *) *this_prologue_cache; 4657d62b00eSchristos 466*6881a400Schristos return get_frame_arch (frame_info_ptr (cache->next_bottom_frame)); 4677d62b00eSchristos } 4687d62b00eSchristos 4697d62b00eSchristos /* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds 4707d62b00eSchristos a chain to create. */ 4717d62b00eSchristos 4727d62b00eSchristos const struct frame_unwind dwarf2_tailcall_frame_unwind = 4737d62b00eSchristos { 474*6881a400Schristos "dwarf2 tailcall", 4757d62b00eSchristos TAILCALL_FRAME, 4767d62b00eSchristos default_frame_unwind_stop_reason, 4777d62b00eSchristos tailcall_frame_this_id, 4787d62b00eSchristos tailcall_frame_prev_register, 4797d62b00eSchristos NULL, 4807d62b00eSchristos tailcall_frame_sniffer, 4817d62b00eSchristos tailcall_frame_dealloc_cache, 4827d62b00eSchristos tailcall_frame_prev_arch 4837d62b00eSchristos }; 4847d62b00eSchristos 4857d62b00eSchristos void _initialize_tailcall_frame (); 4867d62b00eSchristos void 4877d62b00eSchristos _initialize_tailcall_frame () 4887d62b00eSchristos { 4897d62b00eSchristos cache_htab = htab_create_alloc (50, cache_hash, cache_eq, NULL, xcalloc, 4907d62b00eSchristos xfree); 4917d62b00eSchristos } 492