[DTrace-devel] [PATCH 2/3] Provide and use standard functions to clear or copy CPU registers

Kris Van Hees kris.van.hees at oracle.com
Tue Jul 6 10:56:04 PDT 2021


On Fri, Jul 02, 2021 at 02:48:27PM -0400, Eugene Loh wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
> Out of personal curiosity, why are %r7 and %r8 handled differently?  
> That is, r7 is hardwired into the callees while r8 is passed in as an 
> arg.  Why not consistent?  That is, both hardwired in or (more likely) 
> both passed in as args?

The main reason is a bit historical.  The prologue to the trampoline sets up
%r7 and %r8 as specific values.  Those may be used by the provider-specific
code to do some work, and then there are other trampoline functions we call
that depend on %r7.  We use %r8 or a derivative value when we need to pass
access to the pt_regs struct.

I could perhaps pass %r7 as a return value from the prologue, and then pass
it to the other functions, but the desisgn right now is very much based on
%r7 being reserved for this use during the trampoline creation.  Passing it
as a value would make it seem more 'dynamic' (in my opinion) than it really is.

	Kris

> On 7/2/21 2:19 PM, Kris Van Hees wrote:
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> > ---
> >   libdtrace/dt_cg.c           | 44 +++++++++++++++++++++++++++++++++++++
> >   libdtrace/dt_cg.h           |  2 ++
> >   libdtrace/dt_dctx.h         |  2 --
> >   libdtrace/dt_prov_dtrace.c  | 16 +-------------
> >   libdtrace/dt_prov_fbt.c     | 11 +---------
> >   libdtrace/dt_prov_pid.c     | 16 +-------------
> >   libdtrace/dt_prov_profile.c | 13 +----------
> >   libdtrace/dt_prov_sdt.c     | 16 +++-----------
> >   libdtrace/dt_prov_syscall.c | 11 +---------
> >   9 files changed, 54 insertions(+), 77 deletions(-)
> >
> > diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> > index 99e5c05a..be61b4b0 100644
> > --- a/libdtrace/dt_cg.c
> > +++ b/libdtrace/dt_cg.c
> > @@ -196,6 +196,50 @@ dt_cg_tramp_prologue(dt_pcb_t *pcb)
> >   	dt_cg_tramp_prologue_act(pcb, DT_ACTIVITY_ACTIVE);
> >   }
> >   
> > +/*
> > + * Clear the content of the 'regs' member of the machine state.
> > + *
> > + * The caller must ensure that %r7 contains the value set by the
> > + * dt_cg_tramp_prologue*() functions.
> > + */
> > +void
> > +dt_cg_tramp_clear_regs(dt_pcb_t *pcb)
> > +{
> > +	dt_irlist_t	*dlp = &pcb->pcb_ir;
> > +	int		i;
> > +
> > +	/*
> > +	 *	memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > +	 *				// stdw [%7 + DMST_REGS + 0 * 8], 0
> > +	 *				// stdw [%7 + DMST_REGS + 1 * 8], 0
> > +	 *				//     (...)
> > +	 */
> > +	for (i = 0; i < sizeof(dt_pt_regs); i += 8)
> > +		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > +}
> > +
> > +/*
> > + * Copy the content of a dt_pt_regs structure referenced by the 'rp' argument
> > + * into the 'regs' member of the machine state.
> > + *
> > + * The caller must ensure that %r7 contains the value set by the
> > + * dt_cg_tramp_prologue*() functions.
> > + */
> > +void
> > +dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp)
> > +{
> > +	dt_irlist_t	*dlp = &pcb->pcb_ir;
> > +	int		i;
> > +
> > +	/*
> > +	 *	dctx->mst->regs = *(dt_pt_regs *)rp;
> > +	 */
> > +	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > +		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > +		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > +	}
> > +}
> > +
> >   /*
> >    * Copy arguments from a dt_pt_regs structure referenced by the 'rp' argument.
> >    *
> > diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
> > index 96ce56f8..5752151b 100644
> > --- a/libdtrace/dt_cg.h
> > +++ b/libdtrace/dt_cg.h
> > @@ -22,6 +22,8 @@ extern void dt_cg_xsetx(dt_irlist_t *, dt_ident_t *, uint_t, int, uint64_t);
> >   extern dt_irnode_t *dt_cg_node_alloc(uint_t, struct bpf_insn);
> >   extern void dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act);
> >   extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
> > +extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
> > +extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp);
> >   extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp);
> >   extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
> >   				     dt_activity_t act);
> > diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
> > index f0d42f4b..c065dc70 100644
> > --- a/libdtrace/dt_dctx.h
> > +++ b/libdtrace/dt_dctx.h
> > @@ -25,9 +25,7 @@ typedef struct dt_mstate {
> >   	int32_t		syscall_errno;	/* syscall errno */
> >   	uint64_t	fault;		/* DTrace fault flags */
> >   	uint64_t	tstamp;		/* cached timestamp value */
> > -#if 0
> >   	dt_pt_regs	regs;		/* CPU registers */
> > -#endif
> >   	uint64_t	argv[10];	/* Probe arguments */
> >   } dt_mstate_t;
> >   
> > diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> > index 1c40c233..c8a55475 100644
> > --- a/libdtrace/dt_prov_dtrace.c
> > +++ b/libdtrace/dt_prov_dtrace.c
> > @@ -155,21 +155,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	emit(dlp, BPF_MOV_IMM(BPF_REG_4, BPF_ANY));
> >   	emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_update_elem));
> >   
> > -#if 0
> > -	/*
> > -	 *     dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > -	 *				// lddw %r0, [%r8 + 0]
> > -	 *				// stdw [%r7 + DMST_REGS + 0], %r0
> > -	 *				// lddw %r0, [%r8 + 8]
> > -	 *				// stdw [%r7 + DMST_REGS + 8], %r0
> > -	 *				//     (...)
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > -		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > -		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > -	}
> > -#endif
> > -
> > +	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> >   	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> >   
> >   	dt_cg_tramp_epilogue_advance(pcb, act);
> > diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> > index 80bbf721..62fea51e 100644
> > --- a/libdtrace/dt_prov_fbt.c
> > +++ b/libdtrace/dt_prov_fbt.c
> > @@ -168,16 +168,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	 *				//     (%r8 = dctx->ctx)
> >   	 */
> >   
> > -#if 0
> > -	/*
> > -	 *	dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > -		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > -		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > -	}
> > -#endif
> > -
> > +	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> >   	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> >   	dt_cg_tramp_epilogue(pcb);
> >   }
> > diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
> > index 2e9c5bee..af894f79 100644
> > --- a/libdtrace/dt_prov_pid.c
> > +++ b/libdtrace/dt_prov_pid.c
> > @@ -210,21 +210,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	 *				//     (%r8 = dctx->ctx)
> >   	 */
> >   
> > -#if 0
> > -	/*
> > -	 *     dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > -	 *				// lddw %r0, [%r8 + 0]
> > -	 *				// stdw [%r7 + DMST_REGS + 0], %r0
> > -	 *				// lddw %r0, [%r8 + 8]
> > -	 *				// stdw [%r7 + DMST_REGS + 8], %r0
> > -	 *				//     (...)
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > -		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > -		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > -	}
> > -#endif
> > -
> > +	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> >   	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> >   
> >   	/*
> > diff --git a/libdtrace/dt_prov_profile.c b/libdtrace/dt_prov_profile.c
> > index 313c8c9c..caa414ca 100644
> > --- a/libdtrace/dt_prov_profile.c
> > +++ b/libdtrace/dt_prov_profile.c
> > @@ -226,18 +226,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	 *				//     (%r8 = dctx->ctx)
> >   	 */
> >   
> > -#if 0
> > -	/*
> > -	 *     dctx->mst->regs = *(dt_pt_regs *)&dctx->ctx->regs;
> > -	 *                              // (we use the fact that regs is the
> > -	 *                              //  member at offset 0, and there can
> > -	 *                              //  copy *(dt_pt_regs *)dctx->ctx)
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > -		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > -		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > -	}
> > -#endif
> > +	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> >   
> >   	/*
> >   	 * TODO:
> > diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
> > index 320edbd2..712f533f 100644
> > --- a/libdtrace/dt_prov_sdt.c
> > +++ b/libdtrace/dt_prov_sdt.c
> > @@ -121,7 +121,7 @@ static int populate(dtrace_hdl_t *dtp)
> >    * The trampoline function is called when a SDT probe triggers, and it must
> >    * satisfy the following prototype:
> >    *
> > - *	int dt_sdt(struct syscall_data *scd)
> > + *	int dt_sdt(void *data)
> >    *
> >    * The trampoline will populate a dt_dctx_t struct and then call the function
> >    * that implements the compiled D clause.  It returns the value that it gets
> > @@ -142,17 +142,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	 *				//     (%r8 = dctx->ctx)
> >   	 */
> >   
> > -#if 0
> > -	/*
> > -	 *	memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > -	 *				// stdw [%7 + DMST_REGS + 0], 0
> > -	 *				// stdw [%7 + DMST_REGS + 8], 0
> > -	 *				//     (...)
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > -		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > -	}
> > -#endif
> > +	dt_cg_tramp_clear_regs(pcb);
> >   
> >   	/*
> >   	 *	for (i = 0; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> > @@ -175,7 +165,7 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> >   
> >   	/*
> >   	 * If the tracepoint has already been created and we have its info,
> > -	 * there is no need to retrive the info again.
> > +	 * there is no need to retrieve the info again.
> >   	 */
> >   	if (dt_tp_is_created(tpp))
> >   		return -1;
> > diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
> > index bbf45888..2c6644d4 100644
> > --- a/libdtrace/dt_prov_syscall.c
> > +++ b/libdtrace/dt_prov_syscall.c
> > @@ -156,16 +156,7 @@ static void trampoline(dt_pcb_t *pcb)
> >   	 *				//     (%r8 = dctx->ctx)
> >   	 */
> >   
> > -#if 0
> > -	/*
> > -	 *	memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > -	 *				// stdw [%7 + DMST_REGS + 0], 0
> > -	 *				// stdw [%7 + DMST_REGS + 8], 0
> > -	 *				//     (...)
> > -	 */
> > -	for (i = 0; i < sizeof(dt_pt_regs); i += 8)
> > -		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > -#endif
> > +	dt_cg_tramp_clear_regs(pcb);
> >   
> >   	/*
> >   	 *	for (i = 0; i < argc; i++)
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list