int Pstack_iter(struct ps_prochandle *P, const prgregset_t regs, proc_stack_f *func, void *arg) { prgreg_t *prevfp = NULL; uint_t pfpsize = 0; int nfp = 0; prgregset_t gregs; long args[6]; prgreg_t fp; int i; int rv; uintptr_t sp; ssize_t n; uclist_t ucl; ucontext_t uc; init_uclist(&ucl, P); (void) memcpy(gregs, regs, sizeof (gregs)); for (;;) { fp = gregs[R_FP]; if (stack_loop(fp, &prevfp, &nfp, &pfpsize)) break; for (i = 0; i < 6; i++) args[i] = gregs[R_I0 + i]; if ((rv = func(arg, gregs, 6, args)) != 0) break; gregs[R_PC] = gregs[R_I7]; gregs[R_nPC] = gregs[R_PC] + 4; (void) memcpy(&gregs[R_O0], &gregs[R_I0], 8*sizeof (prgreg_t)); if ((sp = gregs[R_FP]) == 0) break; sp += STACK_BIAS; if (find_uclink(&ucl, sp + SA(sizeof (struct frame))) && Pread(P, &uc, sizeof (uc), sp + SA(sizeof (struct frame))) == sizeof (uc)) { ucontext_n_to_prgregs(&uc, gregs); sp = gregs[R_SP] + STACK_BIAS; } n = Pread(P, &gregs[R_L0], sizeof (struct rwindow), sp); if (n == sizeof (struct rwindow)) continue; /* * If we get here, then our Pread of the register window * failed. If this is because the address was not mapped, * then we attempt to read this window via any gwindows * information we have. If that too fails, abort our loop. */ if (n > 0) break; /* Failed for reason other than not mapped */ if (read_gwin(P, (struct rwindow *)&gregs[R_L0], sp) == -1) break; /* No gwindows match either */ } if (prevfp) free(prevfp); free_uclist(&ucl); return (rv); }
static int Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs, proc_stack_f *func, void *arg) { prgreg_t *prevfp = NULL; uint_t pfpsize = 0; int nfp = 0; struct { prgreg32_t fp; prgreg32_t pc; prgreg32_t args[32]; } frame; uint_t argc; ssize_t sz; prgregset_t gregs; uint32_t fp, pfp, pc; long args[32]; int rv; int i; /* * Type definition for a structure corresponding to an IA32 * signal frame. Refer to the comments in Pstack.c for more info */ typedef struct { prgreg32_t fp; prgreg32_t pc; int signo; caddr32_t ucp; caddr32_t sip; } sf_t; uclist_t ucl; ucontext32_t uc; uintptr_t uc_addr; init_uclist(&ucl, P); (void) memcpy(gregs, regs, sizeof (gregs)); fp = regs[R_FP]; pc = regs[R_PC]; while (fp != 0 || pc != 0) { if (stack_loop(fp, &prevfp, &nfp, &pfpsize)) break; if (fp != 0 && (sz = Pread(P, &frame, sizeof (frame), (uintptr_t)fp) >= (ssize_t)(2* sizeof (uint32_t)))) { /* * One more trick for signal frames: the kernel sets * the return pc of the signal frame to 0xffffffff on * Intel IA32, so argcount won't work. */ if (frame.pc != -1L) { sz -= 2* sizeof (uint32_t); argc = argcount(P, (uint32_t)frame.pc, sz); } else argc = 3; /* sighandler(signo, sip, ucp) */ } else { (void) memset(&frame, 0, sizeof (frame)); argc = 0; } gregs[R_FP] = fp; gregs[R_PC] = pc; for (i = 0; i < argc; i++) args[i] = (uint32_t)frame.args[i]; if ((rv = func(arg, gregs, argc, args)) != 0) break; /* * In order to allow iteration over java frames (which can have * their own frame pointers), we allow the iterator to change * the contents of gregs. If we detect a change, then we assume * that the new values point to the next frame. */ if (gregs[R_FP] != fp || gregs[R_PC] != pc) { fp = gregs[R_FP]; pc = gregs[R_PC]; continue; } pfp = fp; fp = frame.fp; pc = frame.pc; if (find_uclink(&ucl, pfp + sizeof (sf_t))) uc_addr = pfp + sizeof (sf_t); else uc_addr = NULL; if (uc_addr != NULL && Pread(P, &uc, sizeof (uc), uc_addr) == sizeof (uc)) { ucontext_32_to_prgregs(&uc, gregs); fp = gregs[R_FP]; pc = gregs[R_PC]; } } if (prevfp) free(prevfp); free_uclist(&ucl); return (rv); }
int Pstack_iter(struct ps_prochandle *P, const prgregset_t regs, proc_stack_f *func, void *arg) { struct { uintptr_t fp; uintptr_t pc; } frame; uint_t pfpsize = 0; prgreg_t *prevfp = NULL; prgreg_t fp, pfp; prgreg_t pc; prgregset_t gregs; int nfp = 0; uclist_t ucl; int rv = 0; int argc; uintptr_t uc_addr; ucontext_t uc; /* * Type definition for a structure corresponding to an IA32 * signal frame. Refer to the comments in Pstack.c for more info */ typedef struct { prgreg_t fp; prgreg_t pc; prgreg_t signo; siginfo_t *sip; } sigframe_t; prgreg_t args[32] = {0}; if (P->status.pr_dmodel != PR_MODEL_LP64) return (Pstack_iter32(P, regs, func, arg)); init_uclist(&ucl, P); (void) memcpy(gregs, regs, sizeof (gregs)); fp = gregs[R_FP]; pc = gregs[R_PC]; while (fp != 0 || pc != 0) { if (stack_loop(fp, &prevfp, &nfp, &pfpsize)) break; if (fp != 0 && Pread(P, &frame, sizeof (frame), (uintptr_t)fp) == sizeof (frame)) { if (frame.pc == -1) { argc = 3; args[2] = fp + sizeof (sigframe_t); if (Pread(P, &args, 2 * sizeof (prgreg_t), fp + 2 * sizeof (prgreg_t)) != 2 * sizeof (prgreg_t)) argc = 0; } else { argc = read_args(P, fp, pc, args, sizeof (args)); } } else { (void) memset(&frame, 0, sizeof (frame)); argc = 0; } gregs[R_FP] = fp; gregs[R_PC] = pc; if ((rv = func(arg, gregs, argc, args)) != 0) break; pfp = fp; fp = frame.fp; pc = frame.pc; if (pc == -1 && find_uclink(&ucl, pfp + sizeof (sigframe_t))) { uc_addr = pfp + sizeof (sigframe_t); if (Pread(P, &uc, sizeof (uc), uc_addr) == sizeof (uc)) { ucontext_n_to_prgregs(&uc, gregs); fp = gregs[R_FP]; pc = gregs[R_PC]; } } } if (prevfp) free(prevfp); free_uclist(&ucl); return (rv); }
void Mrf24w::loop() { if (wf_connected) { stack_loop(); } wf_macProcess(); }