Skip to content

Commit

Permalink
Standardize use of %r7, %r8, and %r9 in trampoline generation
Browse files Browse the repository at this point in the history
In libdtrace/dt_cg.c, a number of functions generate the trampoline.

After a call to dt_cg_tramp_prologue[_act](), we can expect:
    %r7 contains a pointer to dctx->mst
    %r8 contains a pointer to dctx->ctx
    %r9 contains a pointer to dctx

Most other calls to dt_cg_tramp_*() functions rely on these values.
However,
    dt_cg_tramp_copy_args_from_regs()
    dt_cg_tramp_copy_regs()
    dt_cg_tramp_copy_rval_from_regs()
all pass BPF_REG_8 in via an argument rp.  This is unnecessary.  In fact,
the last two functions don't even use the passed-in argument, already using
the known, hard-wired value BPF_REG_8 instead.

Do not pass BPF_REG_8 in to these functions.  Clean up the comments and
interfaces and switch dt_cg_tramp_copy_args_from_regs() to use BPF_REG_8
explicitly, as the other functions already do.

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>
  • Loading branch information
euloh authored and kvanhees committed Jan 18, 2023
1 parent d090056 commit ca761db
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 36 deletions.
50 changes: 25 additions & 25 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,20 +287,20 @@ dt_cg_tramp_clear_regs(dt_pcb_t *pcb)
}

/*
* Copy the content of a dt_pt_regs structure referenced by the 'rp' argument
* into the 'regs' member of the machine state.
* Copy the content of a dt_pt_regs structure referenced by %r8 into the 'regs'
* member of the machine state.
*
* The caller must ensure that %r7 contains the value set by the
* The caller must ensure that %r7 and %r8 contain the values set by the
* dt_cg_tramp_prologue*() functions.
*/
void
dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp)
dt_cg_tramp_copy_regs(dt_pcb_t *pcb)
{
dt_irlist_t *dlp = &pcb->pcb_ir;
int i;

/*
* dctx->mst->regs = *(dt_pt_regs *)rp;
* dctx->mst->regs = *(dt_pt_regs *)%r8;
*/
for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
Expand All @@ -309,45 +309,45 @@ dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp)
}

/*
* Copy arguments from a dt_pt_regs structure referenced by the 'rp' argument.
* Copy arguments from a dt_pt_regs structure referenced by %r8.
* If 'called' is nonzero, the registers are laid out as when inside the
* function: if zero, they are laid out as at the call instruction, before the
* function is called (as is done for e.g. usdt).
*
* The caller must ensure that %r7 contains the value set by the
* 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, int called)
dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called)
{
dtrace_hdl_t *dtp = pcb->pcb_hdl;
dt_irlist_t *dlp = &pcb->pcb_ir;
int i;

/*
* for (i = 0; i < PT_REGS_ARGC; i++)
* dctx->mst->argv[i] = PT_REGS_ARGi((dt_pt_regs *)rp);
* // lddw %r0, [%rp + PT_REGS_ARGi]
* dctx->mst->argv[i] = PT_REGS_ARGi((dt_pt_regs *)%r8);
* // lddw %r0, [%r8 + 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_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, rp, PT_REGS_ARG1));
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, rp, PT_REGS_ARG2));
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, rp, PT_REGS_ARG3));
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, rp, PT_REGS_ARG4));
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, rp, PT_REGS_ARG5));
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));
#ifdef PT_REGS_ARG6
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, rp, PT_REGS_ARG6));
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, 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_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG7));
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(7), BPF_REG_0));
#endif

Expand All @@ -360,15 +360,15 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp, int called)
* int rc;
* uint64_t *sp;
*
* sp = (uint64_t *)(((dt_pt_regs *)rp)->sp;
* sp = (uint64_t *)(((dt_pt_regs *)%r8)->sp;
* rc = bpf_probe_read[_user](dctx->mst->argv[i],
* sizeof(uint64_t),
* &sp[i - PT_REGS_ARGC +
* (called ? PT_REGS_ARGSTKBASE : 0)]);
* // mov %r1, %r7
* // add %r1, DMST_ARG(i)
* // mov %r2, sizeof(uint64_t)
* // lddw %r3, [%rp + PT_REGS_SP]
* // lddw %r3, [%r8 + PT_REGS_SP]
* // add %r3, (i - PT_REGS_ARGC +
* (called ? PT_REGS_ARGSTKBASE : 0)) *
* sizeof(uint64_t)
Expand All @@ -389,7 +389,7 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp, int called)
emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_7));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, DMST_ARG(i)));
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_LOAD(BPF_DW, BPF_REG_3, BPF_REG_8, PT_REGS_SP));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, (i - PT_REGS_ARGC +
(called ? PT_REGS_ARGSTKBASE : 0)) * sizeof(uint64_t)));
emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_user]));
Expand All @@ -401,14 +401,14 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp, int called)
}

/*
* Copy return value from a dt_pt_regs structure referenced by the 'rp' argument.
* to mst->arg[1]. Zero the other args.
* Copy return value from a dt_pt_regs structure referenced by %r8 to
* mst->arg[1]. Zero the other args.
*
* The caller must ensure that %r7 contains the value set by the
* The caller must ensure that %r7 and %r8 contain the values set by the
* dt_cg_tramp_prologue*() functions.
*/
void
dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp)
dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb)
{
dt_irlist_t *dlp = &pcb->pcb_ir;
int i;
Expand Down
6 changes: 3 additions & 3 deletions libdtrace/dt_cg.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ 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, int called);
extern void dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp);
extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb);
extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called);
extern void dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb);
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);
Expand Down
2 changes: 1 addition & 1 deletion libdtrace/dt_prov_dtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,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));

dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_regs(pcb);

/* zero the probe args */
for (i = 0; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
Expand Down
6 changes: 3 additions & 3 deletions libdtrace/dt_prov_fbt.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ static void trampoline(dt_pcb_t *pcb)
* // (%r7 = dctx->mst)
* // (%r8 = dctx->ctx)
*/
dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_regs(pcb);
if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
dt_irlist_t *dlp = &pcb->pcb_ir;

dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_rval_from_regs(pcb);

/*
* fbt:::return arg0 should be the function offset for
Expand All @@ -175,7 +175,7 @@ static void trampoline(dt_pcb_t *pcb)
dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_0, -1);
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
} else
dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8, 1);
dt_cg_tramp_copy_args_from_regs(pcb, 1);
dt_cg_tramp_epilogue(pcb);
}

Expand Down
2 changes: 1 addition & 1 deletion libdtrace/dt_prov_profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static void trampoline(dt_pcb_t *pcb)
* // (%r8 = dctx->ctx)
*/

dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_regs(pcb);

/*
* TODO:
Expand Down
6 changes: 3 additions & 3 deletions libdtrace/dt_prov_uprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,11 @@ static void trampoline(dt_pcb_t *pcb)
* // (%r8 = dctx->ctx)
*/

dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_regs(pcb);
if (upp->flags & PP_IS_RETURN)
dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
dt_cg_tramp_copy_rval_from_regs(pcb);
else
dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8,
dt_cg_tramp_copy_args_from_regs(pcb,
!(upp->flags & PP_IS_FUNCALL));

/*
Expand Down

0 comments on commit ca761db

Please sign in to comment.