static void stack_capture(struct stack *st, struct frame *frame) { struct frame *fp; vm_offset_t callpc; stack_zero(st); fp = frame; for (;;) { if (!INKERNEL((vm_offset_t)fp) || !ALIGNED_POINTER(fp, uint64_t)) break; callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; /* Don't bother traversing trap frames. */ if ((callpc > (uint64_t)tl_trap_begin && callpc < (uint64_t)tl_trap_end) || (callpc > (uint64_t)tl_text_begin && callpc < (uint64_t)tl_text_end)) break; if (stack_put(st, callpc) == -1) break; if (v9next_frame(fp) <= fp || v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) break; fp = v9next_frame(fp); } }
int md_getframe(struct pstate *ps, int frame, struct md_frame *fram) { struct frame64 fr; struct reg r; reg fp, pc; reg *outs; int i; if (process_getregs(ps, &r)) return (-1); if (frame == 0) { pc = r.r_pc; fp = r.r_out[6] + BIAS; /* * XXX - we need some kind of heuristics here to decide * if the function has done a save or not and then pick * the in registers. the problem is just that there are * no in registers in PT_GETREGS. */ outs = (reg *)&r.r_out; goto out; } fp = r.r_out[6] + BIAS; pc = r.r_out[7]; for (i = 1; i < frame; i++) { /* Too low or unaligned frame pointer? */ if (fp < 8192 || (fp & 7) != 0) return (-1); if (process_read(ps, fp, &fr, sizeof(fr)) < 0) return (-1); fp = (unsigned long)v9next_frame((&fr)); pc = fr.fr_pc; /* Too low or unaligned pc ? */ if ((pc < 8192) || (pc & 3) != 0) return (-1); outs = (reg *)&fr.fr_arg; } out: fram->pc = pc; fram->fp = fp; fram->nargs = 6; /* XXX - don't know the real number */ for (i = 0; i < 6; i++) { fram->args[i] = fr.fr_arg[i]; } return (0); }