/* 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; }
struct m88k_frame_cache * m88k_frame_cache (struct frame_info *next_frame, void **this_cache) { struct m88k_frame_cache *cache; CORE_ADDR frame_sp; if (*this_cache) return *this_cache; cache = FRAME_OBSTACK_ZALLOC (struct m88k_frame_cache); cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); cache->fp_offset = -1; cache->pc = frame_func_unwind (next_frame); if (cache->pc != 0) { CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame); m88k_analyze_prologue (cache->pc, addr_in_block, cache); } /* Calculate the stack pointer used in the prologue. */ if (cache->fp_offset != -1) { CORE_ADDR fp; fp = frame_unwind_register_unsigned (next_frame, M88K_R30_REGNUM); frame_sp = fp - cache->fp_offset; } else { /* If we know where the return address is saved, we can take a solid guess at what the frame pointer should be. */ if (cache->saved_regs[M88K_R1_REGNUM].addr != -1) cache->fp_offset = cache->saved_regs[M88K_R1_REGNUM].addr - 4; frame_sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM); } /* Now that we know the stack pointer, adjust the location of the saved registers. */ { int regnum; for (regnum = M88K_R0_REGNUM; regnum < M88K_R31_REGNUM; regnum ++) if (cache->saved_regs[regnum].addr != -1) cache->saved_regs[regnum].addr += frame_sp; } /* Calculate the frame's base. */ cache->base = frame_sp - cache->sp_offset; trad_frame_set_value (cache->saved_regs, M88K_R31_REGNUM, cache->base); /* Identify SXIP with the return address in R1. */ cache->saved_regs[M88K_SXIP_REGNUM] = cache->saved_regs[M88K_R1_REGNUM]; *this_cache = cache; return cache; }
static struct libunwind_frame_cache * libunwind_frame_cache (struct frame_info *next_frame, void **this_cache) { unw_accessors_t *acc; unw_addr_space_t as; unw_word_t fp; unw_regnum_t uw_sp_regnum; struct libunwind_frame_cache *cache; struct libunwind_descr *descr; int i, ret; if (*this_cache) return *this_cache; /* Allocate a new cache. */ cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache); cache->func_addr = frame_func_unwind (next_frame); /* Get a libunwind cursor to the previous frame. We do this by initializing a cursor. Libunwind treats a new cursor as the top of stack and will get the current register set via the libunwind register accessor. Now, we provide the platform-specific accessors and we set up the register accessor to use the frame register unwinding interfaces so that we properly get the registers for the current frame rather than the top. We then use the unw_step function to move the libunwind cursor back one frame. We can later use this cursor to find previous registers via the unw_get_reg interface which will invoke libunwind's special logic. */ descr = libunwind_descr (get_frame_arch (next_frame)); acc = descr->accessors; as = unw_create_addr_space_p (acc, TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? __BIG_ENDIAN : __LITTLE_ENDIAN); unw_init_remote_p (&cache->cursor, as, next_frame); unw_step_p (&cache->cursor); /* To get base address, get sp from previous frame. */ uw_sp_regnum = descr->gdb2uw (SP_REGNUM); ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp); if (ret < 0) error ("Can't get libunwind sp register."); cache->base = (CORE_ADDR)fp; *this_cache = cache; return cache; }
static struct trad_frame_cache * amd64obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs; char *name; int i; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (next_frame); *this_cache = cache; /* NORMAL_FRAME matches the type in amd64obsd_trapframe_unwind, but SIGTRAMP_FRAME might be more appropriate. */ func = frame_func_unwind (next_frame, NORMAL_FRAME); sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && strncmp (name, "Xintr", 5) == 0) addr = sp + 8; /* It's an interrupt frame. */ else addr = sp; for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++) if (amd64obsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 8); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, null_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 16, func)); } return cache; }
struct sparc_frame_cache * sparc_frame_cache (struct frame_info *next_frame, void **this_cache) { struct sparc_frame_cache *cache; if (*this_cache) return *this_cache; cache = sparc_alloc_frame_cache (); *this_cache = cache; cache->pc = frame_func_unwind (next_frame); if (cache->pc != 0) { CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame); sparc_analyze_prologue (cache->pc, addr_in_block, cache); } if (cache->frameless_p) { /* This function is frameless, so %fp (%i6) holds the frame pointer for our calling frame. Use %sp (%o6) as this frame's base address. */ cache->base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); } else { /* For normal frames, %fp (%i6) holds the frame pointer, the base address for the current stack frame. */ cache->base = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); } if (cache->base & 1) cache->base += BIAS; return cache; }