/* 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; }
static struct trad_frame_cache * vaxobsd_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR addr, base, func; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (next_frame); *this_cache = cache; func = frame_pc_unwind (next_frame); func &= ~(vaxobsd_page_size - 1); base = frame_unwind_register_unsigned (next_frame, VAX_SP_REGNUM); addr = get_frame_memory_unsigned (next_frame, base - 4, 4); trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8); trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12); trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16); trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20); trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24); /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); return cache; }
static struct trad_frame_cache * aix_sighandle_frame_cache (struct frame_info *this_frame, void **this_cache) { LONGEST backchain; CORE_ADDR base, base_orig, func; struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *this_trad_cache; if ((*this_cache) != NULL) return (struct trad_frame_cache *) (*this_cache); this_trad_cache = trad_frame_cache_zalloc (this_frame); (*this_cache) = this_trad_cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); base_orig = base; if (tdep->wordsize == 4) { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_PC_OFFSET + 8, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET + 8, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } else { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_LR_OFFSET64, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET64, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } trad_frame_set_reg_value (this_trad_cache, gdbarch_pc_regnum (gdbarch), func); trad_frame_set_reg_value (this_trad_cache, gdbarch_sp_regnum (gdbarch), base); if (tdep->wordsize == 4) trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x38 + 52 + 8); else trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x70 + 320); trad_frame_set_id (this_trad_cache, frame_id_build (base, func)); trad_frame_set_this_base (this_trad_cache, base); return this_trad_cache; }
static struct trad_frame_cache * ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, base, func; gdb_byte buf[PPC_INSN_SIZE]; unsigned long insn, sigcontext_offset; int i; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_pc (this_frame); func &= ~(ppcobsd_page_size - 1); if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf)) return cache; /* Calculate the offset where we can find `struct sigcontext'. We base our calculation on the amount of stack space reserved by the first instruction of the signal trampoline. */ insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order); sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); addr = base + sigcontext_offset + 2 * tdep->wordsize; for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (cache, regnum, addr); } trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr); /* SRR0? */ addr += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); return cache; }
static struct trad_frame_cache * amd64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, pc, sp; const char *name; int i; if (*this_cache != NULL) return (*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so %rsp in the pcb points to the trapframe. GDB has auto-adjusted %rsp for this frame to account for the "call" into fork_trampoline, so "undo" the adjustment. */ sp += 8; } for (i = 0; i < ARRAY_SIZE (amd64fbsd_trapframe_offset); i++) if (amd64fbsd_trapframe_offset[i] != -1) trad_frame_set_reg_addr (cache, i, sp + amd64fbsd_trapframe_offset[i]); /* Read %rip from trap frame. */ addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM]; pc = read_memory_unsigned_integer (addr, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func)); } return cache; }
static int arm_android_sigreturn_frame_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache) { CORE_ADDR pc = get_frame_pc (this_frame); struct trad_frame_cache *trad_cache; if (pc != 0xffff0500) return 0; trad_cache = trad_frame_cache_zalloc (this_frame); arm_android_sigreturn_init (this_frame, trad_cache, pc); (*this_cache) = trad_cache; return 1; }
static struct trad_frame_cache * tramp_frame_cache (struct frame_info *this_frame, void **this_cache) { CORE_ADDR pc = get_frame_pc (this_frame); struct tramp_frame_cache *tramp_cache = (*this_cache); if (tramp_cache->trad_cache == NULL) { tramp_cache->trad_cache = trad_frame_cache_zalloc (this_frame); tramp_cache->tramp_frame->init (tramp_cache->tramp_frame, this_frame, tramp_cache->trad_cache, tramp_cache->func); } return tramp_cache->trad_cache; }
static struct trad_frame_cache * amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs; const char *name; int i; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && startswith (name, "Xintr")) 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, byte_order); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 16, func)); } return cache; }
static struct trad_frame_cache * ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, base, func; gdb_byte buf[PPC_INSN_SIZE]; int i; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_pc (this_frame); func &= ~(ppcfbsd_page_size - 1); if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf)) return cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); addr = base + 0x10 + 2 * tdep->wordsize; for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (cache, regnum, addr); } trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr); /* SRR0? */ addr += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); 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; }
static struct trad_frame_cache * ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR base; int i, regnum; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); if (tdep->wordsize == 8) base += 48; else base += 8; for (i = 0; i < ppc_num_gprs; i++) trad_frame_set_reg_addr (cache, tdep->ppc_gp0_regnum + i, base + (OFF_FIXREG + i) * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, base + OFF_LR * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, base + OFF_CR * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, base + OFF_XER * tdep->wordsize); trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base + OFF_CTR * tdep->wordsize); /* SRR0? */ trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base + OFF_SRR0 * tdep->wordsize); /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame))); return cache; }
static struct trad_frame_cache * frv_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr; gdb_byte buf[4]; int regnum; CORE_ADDR sc_addr_cache_val = 0; struct frame_id this_id; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); /* FIXME: cagney/2004-05-01: This is is long standing broken code. The frame ID's code address should be the start-address of the signal trampoline and not the current PC within that trampoline. */ get_frame_register (this_frame, sp_regnum, buf); addr = extract_unsigned_integer (buf, sizeof buf, byte_order); this_id = frame_id_build (addr, get_frame_pc (this_frame)); trad_frame_set_id (cache, this_id); for (regnum = 0; regnum < frv_num_regs; regnum++) { LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum, &sc_addr_cache_val); if (reg_addr != -1) trad_frame_set_reg_addr (cache, regnum, reg_addr); } *this_cache = cache; return cache; }
static struct trad_frame_cache * frv_linux_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) { struct trad_frame_cache *cache; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[4]; int regnum; CORE_ADDR sc_addr_cache_val = 0; struct frame_id this_id; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (next_frame); /* FIXME: cagney/2004-05-01: This is is long standing broken code. The frame ID's code address should be the start-address of the signal trampoline and not the current PC within that trampoline. */ frame_unwind_register (next_frame, sp_regnum, buf); this_id = frame_id_build (extract_unsigned_integer (buf, sizeof buf), frame_pc_unwind (next_frame)); trad_frame_set_id (cache, this_id); for (regnum = 0; regnum < frv_num_regs; regnum++) { LONGEST reg_addr = frv_linux_sigcontext_reg_addr (next_frame, regnum, &sc_addr_cache_val); if (reg_addr != -1) trad_frame_set_reg_addr (cache, regnum, reg_addr); } *this_cache = cache; return cache; }
static struct trad_frame_cache * mips_sde_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); const struct mips_regnum *regs = mips_regnum (gdbarch); const int sizeof_reg_t = mips_abi_regsize (gdbarch); enum mips_abi abi = mips_abi (gdbarch); struct trad_frame_cache *cache; CORE_ADDR xcpt_frame; CORE_ADDR start_addr; CORE_ADDR stack_addr; CORE_ADDR pc; int i; if (*this_cache != NULL) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; /* The previous registers are held in struct xcptcontext which is at $sp+offs struct xcptcontext { reg_t sr; CP0 Status reg_t cr; CP0 Cause reg_t epc; CP0 EPC reg_t vaddr; CP0 BadVAddr reg_t regs[32]; General registers reg_t mdlo; LO reg_t mdhi; HI reg_t mdex; ACX ... }; */ stack_addr = get_frame_register_signed (this_frame, gdbarch_sp_regnum (gdbarch)); switch (abi) { case MIPS_ABI_O32: /* 40: XCPTCONTEXT 24: xcpt_gen() argspace (16 bytes) 16: _xcptcall() saved ra, rounded up ( 8 bytes) 00: _xcptcall() argspace (16 bytes) */ xcpt_frame = stack_addr + 40; break; case MIPS_ABI_N32: case MIPS_ABI_N64: default: /* Wild guess. */ /* 16: XCPTCONTEXT 16: xcpt_gen() argspace ( 0 bytes) 00: _xcptcall() saved ra, rounded up (16 bytes) */ xcpt_frame = stack_addr + 16; break; } trad_frame_set_reg_addr (cache, MIPS_PS_REGNUM + gdbarch_num_regs (gdbarch), xcpt_frame + 0 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->cause + gdbarch_num_regs (gdbarch), xcpt_frame + 1 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->pc + gdbarch_num_regs (gdbarch), xcpt_frame + 2 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->badvaddr + gdbarch_num_regs (gdbarch), xcpt_frame + 3 * sizeof_reg_t); for (i = 0; i < MIPS_NUMREGS; i++) trad_frame_set_reg_addr (cache, i + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch), xcpt_frame + (4 + i) * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->lo + gdbarch_num_regs (gdbarch), xcpt_frame + 36 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->hi + gdbarch_num_regs (gdbarch), xcpt_frame + 37 * sizeof_reg_t); pc = get_frame_pc (this_frame); find_pc_partial_function (pc, NULL, &start_addr, NULL); trad_frame_set_id (cache, frame_id_build (start_addr, stack_addr)); return cache; }
static struct trad_frame_cache * amd64nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs = 0, rip = 0; const char *name; int i; struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); /* There is an extra 'call' in the interrupt sequence - ignore the extra * return address */ if (name && strncmp (name, "Xintr", 5) == 0) addr = sp + 8; /* It's an interrupt frame. */ else addr = sp; for (i = 0; i < ARRAY_SIZE (amd64nbsd_tf_reg_offset); i++) if (amd64nbsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + amd64nbsd_tf_reg_offset[i]); /* Read %cs and %rip when we have the addresses to hand */ cs = read_memory_unsigned_integer (addr + amd64nbsd_tf_reg_offset[AMD64_CS_REGNUM], 8, byte_order); rip = read_memory_unsigned_integer (addr + amd64nbsd_tf_reg_offset[AMD64_RIP_REGNUM], 8, byte_order); /* The trap frame layout was changed lf the %rip value is less than 2^16 it * is almost certainly the %ss of the old format. */ if (rip < (1 << 16)) { for (i = 0; i < ARRAY_SIZE (amd64nbsd_tf_reg_offset); i++) { if (amd64nbsd_tf_reg_offset[i] == -1) continue; trad_frame_set_reg_addr (cache, i, addr + amd64nbsd_r_reg_offset[i]); /* Read %cs when we have the address to hand */ if (i == AMD64_CS_REGNUM) cs = read_memory_unsigned_integer (addr + amd64nbsd_r_reg_offset[i], 8, byte_order); } } if ((cs & I386_SEL_RPL) == I386_SEL_UPL || (name && strncmp(name, "Xsoft", 5) == 0)) { /* Trap from user space or soft interrupt; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 16, func)); } return cache; }
static struct trad_frame_cache * i386nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR func, sp, addr, tmp; ULONGEST cs; const char *name; int i; struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); if (*this_cache) return (struct trad_frame_cache *)*this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && strncmp (name, "Xintr", 5) == 0) { /* It's an interrupt frame. */ tmp = read_memory_unsigned_integer (sp + 4, 4, byte_order); if (tmp < 15) { /* Reasonable value for 'ppl': already on interrupt stack. */ addr = sp + 8; } else { /* Switch to previous stack. */ addr = tmp + 4; } } else { /* It's a trap frame. */ addr = sp + 4; } for (i = 0; i < ARRAY_SIZE (i386nbsd_tf_reg_offset); i++) if (i386nbsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + i386nbsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ addr += i386nbsd_tf_reg_offset[I386_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 4, byte_order); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 8, func)); } return cache; }