void dwarf2_tailcall_sniffer_first (struct frame_info *this_frame, void **tailcall_cachep, const LONGEST *entry_cfa_sp_offsetp) { CORE_ADDR prev_pc = 0, prev_sp = 0; /* GCC warning. */ int prev_sp_p = 0; CORE_ADDR this_pc; struct gdbarch *prev_gdbarch; struct call_site_chain *chain = NULL; struct tailcall_cache *cache; volatile struct gdb_exception except; gdb_assert (*tailcall_cachep == NULL); /* PC may be after the function if THIS_FRAME calls noreturn function, get_frame_address_in_block will decrease it by 1 in such case. */ this_pc = get_frame_address_in_block (this_frame); /* Catch any unwinding errors. */ TRY_CATCH (except, RETURN_MASK_ERROR) { int sp_regnum; prev_gdbarch = frame_unwind_arch (this_frame); /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p. */ prev_pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); /* call_site_find_chain can throw an exception. */ chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc); if (entry_cfa_sp_offsetp == NULL) break; sp_regnum = gdbarch_sp_regnum (prev_gdbarch); if (sp_regnum == -1) break; prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum); prev_sp_p = 1; }
void dwarf2_tailcall_sniffer_first (struct frame_info *this_frame, void **tailcall_cachep, const LONGEST *entry_cfa_sp_offsetp) { CORE_ADDR prev_pc = 0, prev_sp = 0; /* GCC warning. */ int prev_sp_p = 0; CORE_ADDR this_pc; struct gdbarch *prev_gdbarch; struct call_site_chain *chain = NULL; struct tailcall_cache *cache; gdb_assert (*tailcall_cachep == NULL); /* PC may be after the function if THIS_FRAME calls noreturn function, get_frame_address_in_block will decrease it by 1 in such case. */ this_pc = get_frame_address_in_block (this_frame); /* Catch any unwinding errors. */ TRY { int sp_regnum; prev_gdbarch = frame_unwind_arch (this_frame); /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p. */ prev_pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); /* call_site_find_chain can throw an exception. */ chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc); if (entry_cfa_sp_offsetp == NULL) break; sp_regnum = gdbarch_sp_regnum (prev_gdbarch); if (sp_regnum == -1) break; prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum); prev_sp_p = 1; } CATCH (except, RETURN_MASK_ERROR) { if (entry_values_debug) exception_print (gdb_stdout, except); return; } END_CATCH /* Ambiguous unwind or unambiguous unwind verified as matching. */ if (chain == NULL || chain->length == 0) { xfree (chain); return; } cache = cache_new_ref1 (this_frame); *tailcall_cachep = cache; cache->chain = chain; cache->prev_pc = prev_pc; cache->chain_levels = pretended_chain_levels (chain); cache->prev_sp_p = prev_sp_p; if (cache->prev_sp_p) { cache->prev_sp = prev_sp; cache->entry_cfa_sp_offset = *entry_cfa_sp_offsetp; } gdb_assert (cache->chain_levels > 0); }