[DTrace-devel] [PATCH] cg: add a function to scalarize pointers

Kris Van Hees kris.van.hees at oracle.com
Fri Feb 24 16:11:22 UTC 2023


The logic to scalarize a pointer was already present in dt_cg_typecast()
for ALLOCA and DPTR pointers, but new use cases are emerging.  Move the
logic to dt_cg_scalarize().

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_cg.c | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 6cf311be..60e05642 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -2739,6 +2739,31 @@ dt_cg_store(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dst)
 		dt_regset_free(drp, dreg);
 }
 
+/*
+ * Scalarize a pointer (turn it into a regular scalar).  This is often needed
+ * to ensure that the BPF verifier will no longer treat it as a pointer and
+ * therefore enforce boundary checking.
+ *
+ * There is no way back - once a value is scalarized it cannot be returned to
+ * being a pointer that is recognized by the BPF verifier.
+ */
+static void
+dt_cg_scalarize(const dt_node_t *src, const dt_node_t *dst,
+		dt_irlist_t *dlp, dt_regset_t *drp)
+{
+	int	mst;
+
+	if ((mst = dt_regset_alloc(drp)) == -1)
+		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+	emit(dlp,  BPF_LOAD(BPF_DW, mst, BPF_REG_FP, DT_STK_DCTX));
+	emit(dlp,  BPF_LOAD(BPF_DW, mst, mst, DCTX_MST));
+	emit(dlp,  BPF_STORE(BPF_DW, mst, DMST_SCALARIZER, src->dn_reg));
+	emit(dlp,  BPF_LOAD(BPF_DW, dst->dn_reg, mst, DMST_SCALARIZER));
+
+	dt_regset_free(drp, mst);
+}
+
 /*
  * Generate code for a typecast or for argument promotion from the type of the
  * actual to the type of the formal.  We need to generate code for casts when
@@ -2761,17 +2786,7 @@ dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
 
 	if (dt_node_is_arith(dst) && dt_node_is_pointer(src) &&
 	    (src->dn_flags & (DT_NF_ALLOCA | DT_NF_DPTR))) {
-		int	mst;
-
-		if ((mst = dt_regset_alloc(drp)) == -1)
-			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
-		emit(dlp,  BPF_LOAD(BPF_DW, mst, BPF_REG_FP, DT_STK_DCTX));
-		emit(dlp,  BPF_LOAD(BPF_DW, mst, mst, DCTX_MST));
-		emit(dlp,  BPF_STORE(BPF_DW, mst, DMST_SCALARIZER, src->dn_reg));
-		emit(dlp,  BPF_LOAD(BPF_DW, dst->dn_reg, mst, DMST_SCALARIZER));
-
-		dt_regset_free(drp, mst);
+		dt_cg_scalarize(src, dst, dlp, drp);
 	} else {
 		int	srcsigned = src->dn_flags & DT_NF_SIGNED;
 		int	dstsigned = dst->dn_flags & DT_NF_SIGNED;
-- 
2.39.1




More information about the DTrace-devel mailing list