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

Eugene Loh eugene.loh at oracle.com
Fri Jul 2 11:48:27 PDT 2021


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?

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++)



More information about the DTrace-devel mailing list