[DTrace-devel] [PATCH] Fix DT_TOK_INT for values between INT32_MAX and UINT32_MAX

eugene.loh at oracle.com eugene.loh at oracle.com
Wed Jul 15 17:28:58 PDT 2020


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

An earlier commit
("Use MOV instead of LDDW when value is less than UINT32_MAX")
attempted to optimize away one BPF instruction for storing a constant
in a BPF register.  In the dt_cg_node() handling of DT_TOK_INT, a
64-bit dnp->dn_value constant must be stored in a 64-bit BPF register.
In general, this uses an LDDW double instruction (via dt_cg_setx).
If the value fits into the 32-bit IMM, however, one might get by
with a single MOV_IMM instruction.  The earlier commit tested for
this optimization opportunity by checking the value against UINT32_MAX
-- that is, whether the value fits into 32 bits.

The problem with this approach is that if the uppermost bit of the IMM
is set, then MOV_IMM will sign extend the value when it fills the BPF
register.  For example,

        # dtrace -qn 'BEGIN {x = 3000000000; trace(x); exit(0)}'
        -1294967296

Change the check to INT32_MAX.

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

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 26172432..b80e464d 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -2884,7 +2884,7 @@ if ((idp = dnp->dn_ident)->di_kind != DT_IDENT_FUNC)
 		if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
 			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
 
-		if (dnp->dn_value > UINT32_MAX)
+		if (dnp->dn_value > INT32_MAX)
 			dt_cg_setx(dlp, dnp->dn_reg, dnp->dn_value);
 		else {
 			instr = BPF_MOV_IMM(dnp->dn_reg, dnp->dn_value);
-- 
2.18.2




More information about the DTrace-devel mailing list