static struct value * tailcall_frame_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct tailcall_cache *cache = *this_cache; struct value *val; gdb_assert (this_frame != cache->next_bottom_frame); val = dwarf2_tailcall_prev_register_first (this_frame, this_cache, regnum); if (val) return val; return frame_unwind_got_register (this_frame, regnum, regnum); }
static struct value * amd64_windows_frame_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct amd64_windows_frame_cache *cache = amd64_windows_frame_cache (this_frame, this_cache); struct value *val; CORE_ADDR prev; if (frame_debug) fprintf_unfiltered (gdb_stdlog, "amd64_windows_frame_prev_register %s for sp=%s\n", gdbarch_register_name (gdbarch, regnum), paddress (gdbarch, cache->prev_sp)); if (regnum >= AMD64_XMM0_REGNUM && regnum <= AMD64_XMM0_REGNUM + 15) prev = cache->prev_xmm_addr[regnum - AMD64_XMM0_REGNUM]; else if (regnum == AMD64_RSP_REGNUM) { prev = cache->prev_rsp_addr; if (prev == 0) return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp); } else if (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_R15_REGNUM) prev = cache->prev_reg_addr[regnum - AMD64_RAX_REGNUM]; else if (regnum == AMD64_RIP_REGNUM) prev = cache->prev_rip_addr; else prev = 0; if (prev && frame_debug) fprintf_unfiltered (gdb_stdlog, " -> at %s\n", paddress (gdbarch, prev)); if (prev) { /* Register was saved. */ return frame_unwind_got_memory (this_frame, regnum, prev); } else { /* Register is either volatile or not modified. */ return frame_unwind_got_register (this_frame, regnum, regnum); } }
static struct value * moxie_frame_prev_register (struct frame_info *this_frame, void **this_prologue_cache, int regnum) { struct moxie_frame_cache *cache = moxie_frame_cache (this_frame, this_prologue_cache); gdb_assert (regnum >= 0); if (regnum == MOXIE_SP_REGNUM && cache->saved_sp) return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL) return frame_unwind_got_memory (this_frame, regnum, cache->saved_regs[regnum]); return frame_unwind_got_register (this_frame, regnum, regnum); }
struct value * libunwind_frame_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct libunwind_frame_cache *cache = libunwind_frame_cache (this_frame, this_cache); struct gdbarch *gdbarch = get_frame_arch (this_frame); void *ptr; unw_cursor_t *c; unw_save_loc_t sl; int i, ret; unw_word_t intval; unw_fpreg_t fpval; unw_regnum_t uw_regnum; struct libunwind_descr *descr; struct value *val = NULL; if (cache == NULL) return frame_unwind_got_constant (this_frame, regnum, 0); /* Convert from gdb register number to libunwind register number. */ descr = libunwind_descr (get_frame_arch (this_frame)); uw_regnum = descr->gdb2uw (regnum); gdb_assert (regnum >= 0); if (!target_has_registers) error (_("No registers.")); if (uw_regnum < 0) return frame_unwind_got_constant (this_frame, regnum, 0); if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0) return frame_unwind_got_constant (this_frame, regnum, 0); switch (sl.type) { case UNW_SLT_MEMORY: val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr); break; case UNW_SLT_REG: val = frame_unwind_got_register (this_frame, regnum, descr->uw2gdb (sl.u.regnum)); break; case UNW_SLT_NONE: { /* The register is not stored at a specific memory address nor inside another register. So use libunwind to fetch the register value for us, and create a constant value with the result. */ if (descr->is_fpreg (uw_regnum)) { ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval); if (ret < 0) return frame_unwind_got_constant (this_frame, regnum, 0); val = frame_unwind_got_bytes (this_frame, regnum, (gdb_byte *) &fpval); } else { ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval); if (ret < 0) return frame_unwind_got_constant (this_frame, regnum, 0); val = frame_unwind_got_constant (this_frame, regnum, intval); } break; } } return val; }