[DTrace-devel] [PATCH 2/2] Handle BPF_send_signal() return value

eugene.loh at oracle.com eugene.loh at oracle.com
Fri Jul 17 12:00:06 PDT 2020


From: Eugene Loh <eugene.loh at oracle.com>

Handle the return value of BPF_send_signal(), which is used to
implement raise().  Specifically, if the value is nonzero, store
it in dctx->mst->fault and jump to the exit label.

This patch is separate from the previous one, which introduced
raise() support, for the purpose of code review.  It can be
squashed into that previous patch if both patches are accepted.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_cg.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index e78491b7..4413e80b 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -701,6 +701,8 @@ dt_cg_act_raise(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 	struct bpf_insn	instr;
 	dt_irlist_t	*dlp = &pcb->pcb_ir;
 	dt_regset_t	*drp = pcb->pcb_regs;
+	uint_t		lbl_zero = dt_irlist_label(dlp);
+	int		r;
 
 	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, drp);
 
@@ -713,6 +715,34 @@ dt_cg_act_raise(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 	instr = BPF_CALL_HELPER(BPF_FUNC_send_signal);
 	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
 	dt_regset_free_args(drp);
+
+	/*
+	 * if (send_signal() != 0) {
+	 *     // lddw %r, [%fp + DT_STK_DCTX]
+	 *     // lddw %r, [%r + DCTX_MST]
+	 *     // stdw [%r + DMST_FAULT], %r0
+	 *     dctx->mst->fault = r0;
+	 *     exit;
+	 * }
+	 *
+	 * Note that we need a temporary register.
+	 * Since we know %r1-%r5 are free, we could just use
+	 * r=BPF_REG_1 and dispense with the dt_regset_free(drp,r).
+	 */
+	instr = BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_zero);
+	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+	if ((r = dt_regset_alloc(drp)) == -1)
+		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+	instr = BPF_LOAD(BPF_DW, r, BPF_REG_FP, DT_STK_DCTX);
+	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+	instr = BPF_LOAD(BPF_DW, r, r, DCTX_MST);
+	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+	instr = BPF_STORE(BPF_DW, r, DMST_FAULT, BPF_REG_0);
+	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+	dt_regset_free(drp, r);
+	instr = BPF_JUMP(pcb->pcb_exitlbl);
+	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+	dt_irlist_append(dlp, dt_cg_node_alloc(lbl_zero, BPF_NOP()));
 	dt_regset_free(drp, BPF_REG_0);
 }
 
-- 
2.18.2




More information about the DTrace-devel mailing list