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

Kris Van Hees kris.van.hees at oracle.com
Tue Mar 23 14:20:22 PDT 2021


On Tue, Mar 23, 2021 at 04:56:23PM -0400, Kris Van Hees wrote:
> 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 :)

This is not my day :)  The instruction should be there but the value 1234 is
rather random and pointless.   Tne instruction should be:

		emit(dlp,  BPF_MOV_IMM(BPF_REG_1, 0));

This is also reflected in the comment block before these instructions.

Arguably, perhaps a fault should be raised whenwe cannot read from the stack
address (BPF_probe_read fails) but then again, this code does not know what
to expect in terms of available values.  Since we're populating function
argument values, it is reasonable (and safer) to just store 0 and move on.

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