⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtrace_isa.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (lwp == NULL || p == NULL || lwp->lwp_regs == NULL)		return;	if (pcstack_limit <= 0)		return;	*pcstack++ = (uint64_t)p->p_pid;	pcstack_limit--;	if (pcstack_limit <= 0)		return;	rp = lwp->lwp_regs;	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {		*fpstack++ = 0;		*pcstack++ = (uint64_t)rp->r_pc;		pcstack_limit--;		if (pcstack_limit <= 0)			return;		*fpstack++ = (uint64_t)rp->r_sp;		*pcstack++ = (uint64_t)rp->r_o7;		pcstack_limit--;	} else {		*fpstack++ = (uint64_t)rp->r_sp;		*pcstack++ = (uint64_t)rp->r_pc;		pcstack_limit--;	}	if (pcstack_limit <= 0)		return;	sp = rp->r_sp;	dtrace_flush_user_windows();	if (p->p_model == DATAMODEL_NATIVE) {		while (pcstack_limit > 0) {			struct frame *fr = (struct frame *)(sp + STACK_BIAS);			uintptr_t pc;			if (sp == 0 || fr == NULL ||			    ((uintptr_t)&fr->fr_savpc & 3) != 0 ||			    ((uintptr_t)&fr->fr_savfp & 3) != 0)				break;			pc = dtrace_fulword(&fr->fr_savpc);			sp = dtrace_fulword(&fr->fr_savfp);			if (pc == 0)				break;			*fpstack++ = sp;			*pcstack++ = pc;			pcstack_limit--;		}	} else {		while (pcstack_limit > 0) {			struct frame32 *fr = (struct frame32 *)sp;			uint32_t pc;			if (sp == 0 ||			    ((uintptr_t)&fr->fr_savpc & 3) != 0 ||			    ((uintptr_t)&fr->fr_savfp & 3) != 0)				break;			pc = dtrace_fuword32(&fr->fr_savpc);			sp = dtrace_fuword32(&fr->fr_savfp);			*fpstack++ = sp;			*pcstack++ = pc;			pcstack_limit--;		}	}	while (pcstack_limit-- > 0)		*pcstack++ = NULL;}uint64_tdtrace_getarg(int arg, int aframes){	uintptr_t val;	struct frame *fp;	uint64_t rval;	/*	 * Account for the fact that dtrace_getarg() consumes an additional	 * stack frame.	 */	aframes++;	if (arg < 6) {		if (dtrace_fish(aframes, DTRACE_REG_I0 + arg, &val) == 0)			return (val);	} else {		if (dtrace_fish(aframes, DTRACE_REG_I6, &val) == 0) {			/*			 * We have a stack pointer; grab the argument.			 */			fp = (struct frame *)(val + STACK_BIAS);			DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);			rval = fp->fr_argx[arg - 6];			DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);			return (rval);		}	}	/*	 * There are other ways to do this.  But the slow, painful way works	 * just fine.  Because this requires some loads, we need to set	 * CPU_DTRACE_NOFAULT to protect against looking for an argument that	 * isn't there.	 */	fp = (struct frame *)((caddr_t)dtrace_getfp() + STACK_BIAS);	dtrace_flush_windows();	DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);	for (aframes -= 1; aframes; aframes--)		fp = (struct frame *)((caddr_t)fp->fr_savfp + STACK_BIAS);	if (arg < 6) {		rval = fp->fr_arg[arg];	} else {		fp = (struct frame *)((caddr_t)fp->fr_savfp + STACK_BIAS);		rval = fp->fr_argx[arg - 6];	}	DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);	return (rval);}intdtrace_getstackdepth(int aframes){	struct frame *fp, *nextfp, *minfp, *stacktop;	int depth = 0;	int on_intr;	fp = (struct frame *)((caddr_t)dtrace_getfp() + STACK_BIAS);	dtrace_flush_windows();	if ((on_intr = CPU_ON_INTR(CPU)) != 0)		stacktop = (struct frame *)CPU->cpu_intr_stack + SA(MINFRAME);	else		stacktop = (struct frame *)curthread->t_stk;	minfp = fp;	for (;;) {		nextfp = (struct frame *)((caddr_t)fp->fr_savfp + STACK_BIAS);		if (nextfp <= minfp || nextfp >= stacktop) {			if (on_intr) {				/*				 * Hop from interrupt stack to thread stack.				 */				stacktop = (struct frame *)curthread->t_stk;				minfp = (struct frame *)curthread->t_stkbase;				on_intr = 0;				continue;			}			return (++depth);		}		if (aframes > 0) {			aframes--;		} else {			depth++;		}		fp = nextfp;		minfp = fp;	}}/* * This uses the same register numbering scheme as in sys/procfs_isa.h. */ulong_tdtrace_getreg(struct regs *rp, uint_t reg){	ulong_t value;	uintptr_t fp;	struct machpcb *mpcb;	if (reg == R_G0)		return (0);	if (reg <= R_G7)		return ((&rp->r_g1)[reg - 1]);	if (reg > R_I7) {		switch (reg) {		case R_CCR:			return ((rp->r_tstate >> TSTATE_CCR_SHIFT) &			    TSTATE_CCR_MASK);		case R_PC:			return (rp->r_pc);		case R_nPC:			return (rp->r_npc);		case R_Y:			return (rp->r_y);		case R_ASI:			return ((rp->r_tstate >> TSTATE_ASI_SHIFT) &			    TSTATE_ASI_MASK);		case R_FPRS:			return (dtrace_getfprs());		default:			DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);			return (0);		}	}	/*	 * We reach go to the fake restore case if the probe we hit was a pid	 * return probe on a restore instruction. We partially emulate the	 * restore in the kernel and then execute a simple restore	 * instruction that we've secreted away to do the actual register	 * window manipulation. We need to go one register window further	 * down to get at the %ls, and %is and we need to treat %os like %is	 * to pull them out of the topmost user frame.	 */	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAKERESTORE)) {		if (reg > R_O7)			goto fake_restore;		else			reg += R_I0 - R_O0;	} else if (reg <= R_O7) {		return ((&rp->r_g1)[reg - 1]);	}	if (dtrace_getotherwin() > 0)		return (dtrace_getreg_win(reg, 1));	mpcb = (struct machpcb *)((caddr_t)rp - REGOFF);	if (curproc->p_model == DATAMODEL_NATIVE) {		struct frame *fr = (void *)(rp->r_sp + STACK_BIAS);		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == rp->r_sp)					return (rwin[i].rw_local[reg - 16]);			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		value = dtrace_fulword(&fr->fr_local[reg - 16]);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);	} else {		struct frame32 *fr = (void *)(caddr32_t)rp->r_sp;		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow32 *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == rp->r_sp)					return (rwin[i].rw_local[reg - 16]);			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		value = dtrace_fuword32(&fr->fr_local[reg - 16]);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);	}	return (value);fake_restore:	ASSERT(R_L0 <= reg && reg <= R_I7);	/*	 * We first look two user windows down to see if we can dig out	 * the register we're looking for.	 */	if (dtrace_getotherwin() > 1)		return (dtrace_getreg_win(reg, 2));	/*	 * First we need to get the frame pointer and then we perform	 * the same computation as in the non-fake-o-restore case.	 */	mpcb = (struct machpcb *)((caddr_t)rp - REGOFF);	if (dtrace_getotherwin() > 0) {		fp = dtrace_getreg_win(R_FP, 1);		goto got_fp;	}	if (curproc->p_model == DATAMODEL_NATIVE) {		struct frame *fr = (void *)(rp->r_sp + STACK_BIAS);		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == rp->r_sp) {					fp = rwin[i].rw_fp;					goto got_fp;				}			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		fp = dtrace_fulword(&fr->fr_savfp);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);		if (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & CPU_DTRACE_FAULT)			return (0);	} else {		struct frame32 *fr = (void *)(caddr32_t)rp->r_sp;		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow32 *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == rp->r_sp) {					fp = rwin[i].rw_fp;					goto got_fp;				}			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		fp = dtrace_fuword32(&fr->fr_savfp);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);		if (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & CPU_DTRACE_FAULT)			return (0);	}got_fp:	if (curproc->p_model == DATAMODEL_NATIVE) {		struct frame *fr = (void *)(fp + STACK_BIAS);		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == fp)					return (rwin[i].rw_local[reg - 16]);			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		value = dtrace_fulword(&fr->fr_local[reg - 16]);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);	} else {		struct frame32 *fr = (void *)(caddr32_t)fp;		if (mpcb->mpcb_wbcnt > 0) {			struct rwindow32 *rwin = (void *)mpcb->mpcb_wbuf;			int i = mpcb->mpcb_wbcnt;			do {				i--;				if ((long)mpcb->mpcb_spbuf[i] == fp)					return (rwin[i].rw_local[reg - 16]);			} while (i > 0);		}		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);		value = dtrace_fuword32(&fr->fr_local[reg - 16]);		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);	}	return (value);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -