/* Simple frame_unwind_cache. This finds the "extra info" for the frame. */ struct trad_frame_cache * mn10300_frame_unwind_cache (struct frame_info *next_frame, void **this_prologue_cache) { struct trad_frame_cache *cache; CORE_ADDR pc, start, end; if (*this_prologue_cache) return (*this_prologue_cache); cache = trad_frame_cache_zalloc (next_frame); pc = gdbarch_unwind_pc (current_gdbarch, next_frame); mn10300_analyze_prologue (next_frame, (void **) &cache, pc); if (find_pc_partial_function (pc, NULL, &start, &end)) trad_frame_set_id (cache, frame_id_build (trad_frame_get_this_base (cache), start)); else trad_frame_set_id (cache, frame_id_build (trad_frame_get_this_base (cache), frame_func_unwind (next_frame))); (*this_prologue_cache) = cache; return cache; }
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); }