[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