예제 #1
0
파일: Pisadep.c 프로젝트: kele/illumos-fsd
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
void Mrf24w::loop() {
  if (wf_connected) {
    stack_loop();
  }
  wf_macProcess();
}