[DTrace-devel] [PATCH 11/16] Unify common argument retrieval for providers

Kris Van Hees kris.van.hees at oracle.com
Tue Mar 23 13:56:23 PDT 2021


On Fri, Mar 19, 2021 at 12:54:47AM -0400, Kris Van Hees wrote:
> Multiple providers retrieve the probe arguments from the register set
> and from the stack.  Function dt_cg_tramp_copy_args_from_regs() can be
> called to do this in a trampoline.  The trampoline prologue will now
> set up %r7 as a pointer to the mstate and %r8 as a pointer to the BPF
> context.
> 
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>  libdtrace/dt_cg.c           | 128 ++++++++++++++++++++++++++++++++----
>  libdtrace/dt_cg.h           |   1 +
>  libdtrace/dt_prov_dtrace.c  |  57 ++--------------
>  libdtrace/dt_prov_fbt.c     |  40 +----------
>  libdtrace/dt_prov_profile.c |  11 +---
>  libdtrace/dt_prov_sdt.c     |   7 +-
>  libdtrace/dt_prov_syscall.c |   7 +-
>  libdtrace/dt_pt_regs.h      |  12 ++++
>  8 files changed, 144 insertions(+), 119 deletions(-)
> 
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 9ffc5834..35691a26 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -36,8 +36,11 @@ static void dt_cg_node(dt_node_t *, dt_irlist_t *, dt_regset_t *);
>   *
>   * The trampoline prologue will populate the dt_dctx_t structure on the stack.
>   *
> - * The caller should NOT depend on any register values that exist at the end of
> - * the trampoline prologue.
> + * The caller can depend on the following registers being set when this
> + * function returns:
> + *
> + *	%r7 contains a pointer to dctx->mst
> + *	%r8 contains a pointer to dctx->ctx
>   */
>  void
>  dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
> @@ -60,17 +63,20 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
>  	 *	uintptr_t	rc;
>  	 *	char		*buf;
>  	 *
> -	 *	dctx.ctx = ctx;		// stdw [%fp + DCTX_FP(DCTX_CTX)], %r1
> +	 *				//     (%r8 = pointer to BPF context)
> +	 *				// mov %r8, %r1
> +	 *	dctx.ctx = ctx;		// stdw [%fp + DCTX_FP(DCTX_CTX)], %r8
>  	 */
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DCTX_FP(DCTX_CTX), BPF_REG_1));
> +	emit(dlp, BPF_MOV_REG(BPF_REG_8, BPF_REG_1));
> +	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DCTX_FP(DCTX_CTX), BPF_REG_8));
>  
>  	/*
> -	 *	key = DT_STATE_ACTIVITY;// stw [%fp + DCTX_FP(DCTX_MST)],
> +	 *	key = DT_STATE_ACTIVITY;// stw [%fp + DCTX_FP(DCTX_ACT)],
>  	 *				//		DT_STATE_ACTIVITY
>  	 *	rc = bpf_map_lookup_elem(&state, &key);
>  	 *				// lddw %r1, &state
>  	 *				// mov %r2, %fp
> -	 *				// add %r2, DCTX_FP(DCTX_MST)
> +	 *				// add %r2, DCTX_FP(DCTX_ACT)
>  	 *				// call bpf_map_lookup_elem
>  	 *				//     (%r1 ... %r5 clobbered)
>  	 *				//     (%r0 = map value)
> @@ -81,10 +87,10 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
>  	 *
>  	 *	dctx.act = rc;		// stdw [%fp + DCTX_FP(DCTX_ACT)], %r0
>  	 */
> -	emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_FP, DCTX_FP(DCTX_MST), DT_STATE_ACTIVITY));
> +	emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_FP, DCTX_FP(DCTX_ACT), DT_STATE_ACTIVITY));
>  	dt_cg_xsetx(dlp, state, DT_LBL_NONE, BPF_REG_1, state->di_id);
>  	emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_FP));
> -	emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DCTX_FP(DCTX_MST)));
> +	emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DCTX_FP(DCTX_ACT)));
>  	emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_lookup_elem));
>  	emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_exit));
>  	emit(dlp, BPF_LOAD(BPF_W, BPF_REG_1, BPF_REG_0, 0));
> @@ -102,8 +108,10 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
>  	 *				//     (%r0 = 'mem' BPF map value)
>  	 *	if (rc == 0)		// jeq %r0, 0, lbl_exit
>  	 *		goto exit;
> -	 *				//     (%r0 = pointer to dt_mstate_t)
> -	 *	dctx.mst = rc;		// stdw [%fp + DCTX_FP(DCTX_MST)], %r0
> +	 *				//     (%r0 = map value)
> +	 *				//     (%r7 = pointer to dt_mstate_t)
> +	 *				// mov %r7, %r0
> +	 *	dctx.mst = rc;		// stdw [%fp + DCTX_FP(DCTX_MST)], %r7
>  	 */
>  	emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_FP, DCTX_FP(DCTX_MST), 0));
>  	dt_cg_xsetx(dlp, mem, DT_LBL_NONE, BPF_REG_1, mem->di_id);
> @@ -111,7 +119,8 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
>  	emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DCTX_FP(DCTX_MST)));
>  	emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_lookup_elem));
>  	emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_exit));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DCTX_FP(DCTX_MST), BPF_REG_0));
> +	emit(dlp, BPF_MOV_REG(BPF_REG_7, BPF_REG_0));
> +	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DCTX_FP(DCTX_MST), BPF_REG_7));
>  
>  	/*
>  	 *	buf = rc + roundup(sizeof(dt_mstate_t), 8);
> @@ -161,6 +170,103 @@ dt_cg_tramp_prologue(dt_pcb_t *pcb)
>  	dt_cg_tramp_prologue_act(pcb, DT_ACTIVITY_ACTIVE);
>  }
>  
> +/*
> + * Copy arguments from a dt_pt_regs structure referenced by the 'rp' argument.
> + *
> + * The caller must ensure that %r7 and %r8 contain the values set by the
> + * dt_cg_tramp_prologue*() functions.
> + */
> +void
> +dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
> +{
> +	dt_irlist_t	*dlp = &pcb->pcb_ir;
> +	int		i;
> +	uint_t		lbl_store = dt_irlist_label(dlp);
> +
> +	/*
> +	 *	for (i = 0; i < PT_REGS_ARGC; i++)
> +	 *		dctx->mst->argv[i] = PT_REGS_PARAMi((dt_pt_regs *)rp);
> +	 *				// lddw %r0, [%rp + PT_REGS_ARGi]
> +	 *				// stdw [%r7 + DMST_ARG(i)], %r0
> +	 */
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG0));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG1));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG2));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(2), BPF_REG_0));
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG3));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(3), BPF_REG_0));
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG4));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(4), BPF_REG_0));
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG5));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(5), BPF_REG_0));
> +#ifdef PT_REGS_ARG6
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG6));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(6), BPF_REG_0));
> +#endif
> +#ifdef PT_REGS_ARG7
> +	emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG7));
> +	emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(7), BPF_REG_0));
> +#endif
> +
> +	/*
> +	 * Generate code to read the remainder of the arguments from the stack
> +	 * (if possible).  We (ab)use the %r0 spill slot on the stack to read
> +	 * values using bpf_probe_read() because we know that it cannot be in
> +	 * use at this point.
> +	 *
> +	 *	for (i = PT_REGS_ARGC;
> +	 *	     i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++) {
> +	 *		uint64_t	val, tmp;
> +	 *		int		rc;
> +	 *		uint64_t	*sp;
> +	 *
> +	 *		sp = (uint64_t *)(((dt_pt_regs *)rp)->sp;
> +	 *		rc = bpf_probe_read(&tmp, sizeof(tmp),
> +	 *				    &sp[i - PT_REGS_ARGC +
> +	 *					    PT_REGS_ARGSTKBASE]);
> +	 *				// mov %r1, %fp
> +	 *				// add %r1, DT_STK_SPILL(0)
> +	 *				// mov %r2, sizeof(uint64_t)
> +	 *				// lddw %r3, [%rp + PT_REGS_SP]
> +	 *				// mov %r0, i - PT_REGS_ARGC +
> +	 *						PT_REGS_ARGSTKBASE
> +	 *				// mul %r0, sizeof(uint64_t)
> +	 *				// add %r3, %r0
> +	 *				// call bpf_probe_read
> +	 *		val = 0;
> +	 *				// mov %r1, 0
> +	 *		if (rc != 0)
> +	 *			goto store:
> +	 *				// jne %r0, 0, lbl_store
> +	 *		val = tmp;
> +	 *				// lddw %r1, [%rp + DT_STK_SPILL(0)]
> +	 *
> +	 *	store:
> +	 *		dctx->mst->argv[i] = val;
> +	 *				// store:
> +	 *				// stdw [%r7 + DMST_ARG(i)], %r1
> +	 *	}
> +	 *
> +	 */
> +	for (i = PT_REGS_ARGC; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++) {
> +		emit(dlp,  BPF_MOV_REG(BPF_REG_1, BPF_REG_FP));
> +		emit(dlp,  BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, DT_STK_SPILL(0)));
> +		emit(dlp,  BPF_MOV_IMM(BPF_REG_2, sizeof(uint64_t)));
> +		emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_3, rp, PT_REGS_SP));
> +		emit(dlp,  BPF_MOV_IMM(BPF_REG_0, i - PT_REGS_ARGC + PT_REGS_ARGSTKBASE));
> +		emit(dlp,  BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, sizeof(uint64_t)));
> +		emit(dlp,  BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_0));
> +		emit(dlp,  BPF_CALL_HELPER(BPF_FUNC_probe_read));
> +		emit(dlp,  BPF_MOV_IMM(BPF_REG_1, 1234));

The instruction above should not be here!  It was placed for debugging purposes
and therefore should not be in the actual patch.  I'll await review comments
before sending a v2 because sending one with just that line removed seems a bit
silly :)

> +		emit(dlp,  BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, 0, lbl_store));
> +		emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_SPILL(0)));
> +		emitl(dlp, lbl_store,
> +			   BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_1));
> +	}
> +}
> +
>  typedef struct {
>  	dt_irlist_t	*dlp;
>  	dt_activity_t	act;
> diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
> index be430c28..96ce56f8 100644
> --- a/libdtrace/dt_cg.h
> +++ b/libdtrace/dt_cg.h
> @@ -22,6 +22,7 @@ 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_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);
>  extern void dt_cg_tramp_return(dt_pcb_t *pcb);
> diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> index 55090e53..fe0b8d86 100644
> --- a/libdtrace/dt_prov_dtrace.c
> +++ b/libdtrace/dt_prov_dtrace.c
> @@ -78,7 +78,6 @@ static int populate(dtrace_hdl_t *dtp)
>   */
>  static void trampoline(dt_pcb_t *pcb)
>  {
> -	int		i;
>  	dt_irlist_t	*dlp = &pcb->pcb_ir;
>  	dt_activity_t	act = DT_ACTIVITY_ACTIVE;
>  	int		adv_act;
> @@ -124,6 +123,12 @@ static void trampoline(dt_pcb_t *pcb)
>  
>  	dt_cg_tramp_prologue_act(pcb, act);
>  
> +	/*
> +	 * After the dt_cg_tramp_prologue_act() call, we have:
> +	 *				//     (%r7 = dctx->mst)
> +	 *				//     (%r8 = dctx->ctx)
> +	 */
> +
>  	if (key) {
>  		/*
>  		 *     key = DT_STATE_(BEGANON|ENDEDON);
> @@ -155,17 +160,6 @@ static void trampoline(dt_pcb_t *pcb)
>  		emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_update_elem));
>  	}
>  
> -	/*
> -	 * We cannot assume anything about the state of any registers so set up
> -	 * the ones we need:
> -	 *				//     (%r7 = dctx->mst)
> -	 *				// lddw %r7, [%fp + DCTX_FP(DCTX_MST)]
> -	 *				//     (%r8 = dctx->ctx)
> -	 *				// lddw %r8, [%fp + DCTX_FP(DCTX_CTX)]
> -	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_7, BPF_REG_FP, DCTX_FP(DCTX_MST)));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_8, BPF_REG_FP, DCTX_FP(DCTX_CTX)));
> -
>  #if 0
>  	/*
>  	 *     dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> @@ -181,44 +175,7 @@ static void trampoline(dt_pcb_t *pcb)
>  	}
>  #endif
>  
> -	/*
> -	 *	dctx->mst->argv[0] = PT_REGS_PARAM1((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG0]
> -	 *				// stdw [%r7 + DMST_ARG(0)], %r0
> -	 *	dctx->mst->argv[1] = PT_REGS_PARAM2((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG1]
> -	 *				// stdw [%r7 + DMST_ARG(1)], %r0
> -	 *	dctx->mst->argv[2] = PT_REGS_PARAM3((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG2]
> -	 *				// stdw [%r7 + DMST_ARG(2)], %r0
> -	 *	dctx->mst->argv[3] = PT_REGS_PARAM4((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG3]
> -	 *				// stdw [%r7 + DMST_ARG(3)], %r0
> -	 *	dctx->mst->argv[4] = PT_REGS_PARAM5((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG4]
> -	 *				// stdw [%r7 + DMST_ARG(4)], %r0
> -	 *	dctx->mst->argv[5] = PT_REGS_PARAM6((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG5]
> -	 *				// stdw [%r7 + DMST_ARG(5)], %r0
> -	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG0));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG1));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG2));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(2), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG3));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(3), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG4));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(4), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG5));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(5), BPF_REG_0));
> -
> -	/*
> -	 *     (we clear dctx->mst->argv[6] and on)
> -	 */
> -	for (i = 6; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> -		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(i), 0));
> +	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
>  
>  	if (adv_act)
>  		dt_cg_tramp_epilogue_advance(pcb, act);
> diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> index 6db41767..c344aa4c 100644
> --- a/libdtrace/dt_prov_fbt.c
> +++ b/libdtrace/dt_prov_fbt.c
> @@ -166,15 +166,10 @@ static void trampoline(dt_pcb_t *pcb)
>  	dt_cg_tramp_prologue(pcb);
>  
>  	/*
> -	 * We cannot assume anything about the state of any registers so set up
> -	 * the ones we need:
> +	 * After the dt_cg_tramp_prologue() call, we have:
>  	 *				//     (%r7 = dctx->mst)
> -	 *				// lddw %r7, [%fp + DCTX_FP(DCTX_MST)]
>  	 *				//     (%r8 = dctx->ctx)
> -	 *				// lddw %r8, [%fp + DCTX_FP(DCTX_CTX)]
>  	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_7, BPF_REG_FP, DCTX_FP(DCTX_MST)));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_8, BPF_REG_FP, DCTX_FP(DCTX_CTX)));
>  
>  #if 0
>  	/*
> @@ -186,38 +181,7 @@ static void trampoline(dt_pcb_t *pcb)
>  	}
>  #endif
>  
> -	/*
> -	 *	dctx->mst->argv[0] = PT_REGS_PARAM1((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG0]
> -	 *				// stdw [%r7 + DMST_ARG(0)], %r0
> -	 *	dctx->mst->argv[1] = PT_REGS_PARAM2((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG1]
> -	 *				// stdw [%r7 + DMST_ARG(1)], %r0
> -	 *	dctx->mst->argv[2] = PT_REGS_PARAM3((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG2]
> -	 *				// stdw [%r7 + DMST_ARG(2)], %r0
> -	 *	dctx->mst->argv[3] = PT_REGS_PARAM4((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG3]
> -	 *				// stdw [%r7 + DMST_ARG(3)], %r0
> -	 *	dctx->mst->argv[4] = PT_REGS_PARAM5((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG4]
> -	 *				// stdw [%r7 + DMST_ARG(4)], %r0
> -	 *	dctx->mst->argv[5] = PT_REGS_PARAM6((dt_pt_regs *)dctx->ctx);
> -	 *				// lddw %r0, [%r8 + PT_REGS_ARG5]
> -	 *				// stdw [%r7 + DMST_ARG(5)], %r0
> -	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG0));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG1));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG2));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(2), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG3));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(3), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG4));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(4), BPF_REG_0));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG5));
> -	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(5), BPF_REG_0));
> +	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
>  
>  	/*
>  	 *     (we clear dctx->mst->argv[6] and on)
> diff --git a/libdtrace/dt_prov_profile.c b/libdtrace/dt_prov_profile.c
> index f7512387..313c8c9c 100644
> --- a/libdtrace/dt_prov_profile.c
> +++ b/libdtrace/dt_prov_profile.c
> @@ -221,15 +221,10 @@ static void trampoline(dt_pcb_t *pcb)
>  	dt_cg_tramp_prologue(pcb);
>  
>  	/*
> -	 * We cannot assume anything about the state of any registers so set up
> -	 * the ones we need:
> -	 *                              //     (%r7 = dctx->mst)
> -	 *                              // lddw %r7, [%fp + DCTX_FP(DCTX_MST)]
> -	 *                              //     (%r8 = dctx->ctx)
> -	 *                              // lddw %r8, [%fp + DCTX_FP(DCTX_CTX)]
> +	 * After the dt_cg_tramp_prologue() call, we have:
> +	 *				//     (%r7 = dctx->mst)
> +	 *				//     (%r8 = dctx->ctx)
>  	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_7, BPF_REG_FP, DCTX_FP(DCTX_MST)));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_8, BPF_REG_FP, DCTX_FP(DCTX_CTX)));
>  
>  #if 0
>  	/*
> diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
> index bd8a201b..cf62d01a 100644
> --- a/libdtrace/dt_prov_sdt.c
> +++ b/libdtrace/dt_prov_sdt.c
> @@ -146,15 +146,10 @@ static void trampoline(dt_pcb_t *pcb)
>  	dt_cg_tramp_prologue(pcb);
>  
>  	/*
> -	 * We cannot assume anything about the state of any registers so set up
> -	 * the ones we need:
> +	 * After the dt_cg_tramp_prologue() call, we have:
>  	 *				//     (%r7 = dctx->mst)
> -	 *				// lddw %r7, [%fp + DCTX_FP(DCTX_MST)]
>  	 *				//     (%r8 = dctx->ctx)
> -	 *				// lddw %r8, [%fp + DCTX_FP(DCTX_CTX)]
>  	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_7, BPF_REG_FP, DCTX_FP(DCTX_MST)));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_8, BPF_REG_FP, DCTX_FP(DCTX_CTX)));
>  
>  #if 0
>  	/*
> diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
> index 5b142733..15099b59 100644
> --- a/libdtrace/dt_prov_syscall.c
> +++ b/libdtrace/dt_prov_syscall.c
> @@ -151,15 +151,10 @@ static void trampoline(dt_pcb_t *pcb)
>  	dt_cg_tramp_prologue(pcb);
>  
>  	/*
> -	 * We cannot assume anything about the state of any registers so set up
> -	 * the ones we need:
> +	 * After the dt_cg_tramp_prologue() call, we have:
>  	 *				//     (%r7 = dctx->mst)
> -	 *				// lddw %r7, [%fp + DCTX_FP(DCTX_MST)]
>  	 *				//     (%r8 = dctx->ctx)
> -	 *				// lddw %r8, [%fp + DCTX_FP(DCTX_CTX)]
>  	 */
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_7, BPF_REG_FP, DCTX_FP(DCTX_MST)));
> -	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_8, BPF_REG_FP, DCTX_FP(DCTX_CTX)));
>  
>  #if 0
>  	/*
> diff --git a/libdtrace/dt_pt_regs.h b/libdtrace/dt_pt_regs.h
> index 72e065c1..0bbb1be2 100644
> --- a/libdtrace/dt_pt_regs.h
> +++ b/libdtrace/dt_pt_regs.h
> @@ -26,7 +26,10 @@ typedef struct pt_regs		dt_pt_regs;
>  # define PT_REGS_ARG3		offsetof(dt_pt_regs, rcx)
>  # define PT_REGS_ARG4		offsetof(dt_pt_regs, r8)
>  # define PT_REGS_ARG5		offsetof(dt_pt_regs, r9)
> +# define PT_REGS_ARGC		6
> +# define PT_REGS_ARGSTKBASE	1
>  # define PT_REGS_IP		offsetof(dt_pt_regs, rip)
> +# define PT_REGS_SP		offsetof(dt_pt_regs, rsp)
>  
>  # define PT_REGS_BPF_ARG0(r)	((r)->rdi)
>  # define PT_REGS_BPF_ARG1(r)	((r)->rsi)
> @@ -35,6 +38,7 @@ typedef struct pt_regs		dt_pt_regs;
>  # define PT_REGS_BPF_ARG4(r)	((r)->r8)
>  # define PT_REGS_BPF_ARG5(r)	((r)->r9)
>  # define PT_REGS_BPF_IP(r)	((r)->rip)
> +# define PT_REGS_BPF_SP(r)	((r)->rsp)
>  #elif defined(__aarch64__)
>  typedef struct user_pt_regs	dt_pt_regs;
>  # define PT_REGS_ARG0		offsetof(dt_pt_regs, regs[0])
> @@ -43,7 +47,12 @@ typedef struct user_pt_regs	dt_pt_regs;
>  # define PT_REGS_ARG3		offsetof(dt_pt_regs, regs[3])
>  # define PT_REGS_ARG4		offsetof(dt_pt_regs, regs[4])
>  # define PT_REGS_ARG5		offsetof(dt_pt_regs, regs[5])
> +# define PT_REGS_ARG6		offsetof(dt_pt_regs, regs[6])
> +# define PT_REGS_ARG7		offsetof(dt_pt_regs, regs[7])
> +# define PT_REGS_ARGC		8
> +# define PT_REGS_ARGSTKBASE	2
>  # define PT_REGS_IP		offsetof(dt_pt_regs, pc)
> +# define PT_REGS_SP		offsetof(dt_pt_regs, sp)
>  
>  # define PT_REGS_BPF_ARG0(r)	((r)->regs[0])
>  # define PT_REGS_BPF_ARG1(r)	((r)->regs[1])
> @@ -51,7 +60,10 @@ typedef struct user_pt_regs	dt_pt_regs;
>  # define PT_REGS_BPF_ARG3(r)	((r)->regs[3])
>  # define PT_REGS_BPF_ARG4(r)	((r)->regs[4])
>  # define PT_REGS_BPF_ARG5(r)	((r)->regs[5])
> +# define PT_REGS_BPF_ARG5(r)	((r)->regs[6])
> +# define PT_REGS_BPF_ARG5(r)	((r)->regs[7])
>  # define PT_REGS_BPF_IP(r)	((r)->pc)
> +# define PT_REGS_BPF_SP(r)	((r)->sp)
>  #else
>  # error ISA not supported
>  #endif
> -- 
> 2.28.0
> 
> 
> _______________________________________________
> 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