[DTrace-devel] [PATCH v4 07/10] cg: support casts of pointers to integers

Kris Van Hees kris.van.hees at oracle.com
Wed Apr 13 16:19:07 UTC 2022


On Tue, Apr 12, 2022 at 11:59:06AM +0100, Nick Alcock wrote:
> When we cast a pointer to an integer, we want to scalarize it,
> i.e. ensure that it is no longer a map_value, so that the user can
> compare it freely to other integers.
> 
> Add a new DMST_SCALARIZER field to the machine state that anyone
> can stuff map_values into and pull them right back out of to
> scalarize them.
> 
> Signed-off-by: Nick Alcock <nick.alcock at oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>

> ---
>  libdtrace/dt_cg.c   | 20 +++++++++++++++++++-
>  libdtrace/dt_dctx.h |  2 ++
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 900b3381d02c..efb640426d85 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -2468,6 +2468,8 @@ dt_cg_store(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dst)
>   * a scalar type is being narrowed or changing signed-ness.  We first shift the
>   * desired bits high (losing excess bits if narrowing) and then shift them down
>   * using logical shift (unsigned result) or arithmetic shift (signed result).
> + *
> + * We also need to scalarize pointers if we are casting them to an integral type.
>   */
>  static void
>  dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
> @@ -2489,11 +2491,27 @@ dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
>  	else
>  		n = sizeof(uint64_t) * NBBY - srcsize * NBBY;
>  
> -	if (dt_node_is_scalar(dst) && n != 0 && (dstsize < srcsize ||
> +	if (!dt_node_is_scalar(dst))
> +		return;
> +
> +	if (n != 0 && (dstsize < srcsize ||
>  	    (src->dn_flags & DT_NF_SIGNED) ^ (dst->dn_flags & DT_NF_SIGNED))) {
>  		emit(dlp, BPF_MOV_REG(dst->dn_reg, src->dn_reg));
>  		emit(dlp, BPF_ALU64_IMM(BPF_LSH, dst->dn_reg, n));
>  		emit(dlp, BPF_ALU64_IMM((dst->dn_flags & DT_NF_SIGNED) ? BPF_ARSH : BPF_RSH, dst->dn_reg, n));
> +	} else if (dt_node_is_arith(dst) && dt_node_is_pointer(src) &&
> +		   (src->dn_flags & DT_NF_ALLOCA)) {
> +		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);
>  	}
>  }
>  
> diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
> index 1ce7fc9100ea..e41f36036612 100644
> --- a/libdtrace/dt_dctx.h
> +++ b/libdtrace/dt_dctx.h
> @@ -24,6 +24,7 @@ typedef struct dt_mstate {
>  	uint32_t	tag;		/* Tag (for future use) */
>  	uint32_t	scratch_top;	/* Current top of scratch space */
>  	int32_t		syscall_errno;	/* syscall errno */
> +	uint64_t	scalarizer;	/* used to scalarize pointers */
>  	uint64_t	fault;		/* DTrace fault flags */
>  	uint64_t	tstamp;		/* cached timestamp value */
>  	dt_pt_regs	regs;		/* CPU registers */
> @@ -36,6 +37,7 @@ typedef struct dt_mstate {
>  #define DMST_TAG		offsetof(dt_mstate_t, tag)
>  #define DMST_SCRATCH_TOP	offsetof(dt_mstate_t, scratch_top)
>  #define DMST_ERRNO		offsetof(dt_mstate_t, syscall_errno)
> +#define DMST_SCALARIZER		offsetof(dt_mstate_t, scalarizer)
>  #define DMST_FAULT		offsetof(dt_mstate_t, fault)
>  #define DMST_TSTAMP		offsetof(dt_mstate_t, tstamp)
>  #define DMST_REGS		offsetof(dt_mstate_t, regs)
> -- 
> 2.35.1



More information about the DTrace-devel mailing list