[DTrace-devel] [PATCH 01/12] Support loading scalars from kernel addresses

Kris Van Hees kris.van.hees at oracle.com
Mon Jul 25 22:53:06 UTC 2022


On Thu, Jul 21, 2022 at 08:24:48PM -0700, Eugene Loh via DTrace-devel wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
> 
> Lots of test files are touched, but it seems not all have updated Copyright
> notices.

Done.  At times we have not updated them if we were simply removing the xfail
marker, but I prefer to update it anyway so that my checkCopyright script does
not complain.

> In
>     tst.kernel_read_deref_indirect_str.d
>     tst.kernel_read_index_indirect_str.d
> do not compare to 76 but to 'L' (and maybe even add a comment why 'L' so
> it's super obvious).

Done.

> For tst.kernel_read_str.d, check the result.  At least sanity check.   E.g.,
> .r.p file that prints the first two words and .r file with "Linux version".

Done.

> Similarly, for tst.read_index_indirect_str.d, do not check with 100 but with
> 'd', and with a quick comment why.

XXX

> For other new tests, other sanity checks?  E.g., that max_pfn is a multiple
> of 4096?  More stringent tests would be nice.

No, because that is not relevant to DTrace.  Yes, it should be, but that is an
aspect of what that variable means at the kernel level.

> A few other things.
> 
> On 7/13/22 12:17, Kris Van Hees via DTrace-devel wrote:
> > Data access for non-scalar datatypes was implemented using the
> > probe_read() BPF helper while scalar datatypes were accessed using
> > load and store instructions.  When loading scalar data from kernel
> > addresses, a load instruction cannot be used.  This patch ensures
> > that such accesses use the probe_read() BPF helper.  (Storing to
> > kernel addresses is not supported by DTrace so that case does not
> > need special handling.)
> > 
> > The new dt_cg_load_scalar() function implements the scalar kernel
> > access.
> > 
> > A new node flag is introduced: DT_NF_DPTR.  It is set for any pointer
> > that is known to be an internal pointer (i.e. address of a location
> > in a BPF map managed by DTrace).  Such pointers can be dereferenced
> > with a load instruction.  All other cases use dt_cg_load_scalar().
> > The DT_NF_DPTR is propagated across =, +, and -.
> > 
> > Comments and code about DT_NF_USERLAND save/restore across dt_cg_ldsize()
> > has been removed - it is no longer relevant.
> 
> s/has/have/
> s/it is/they are/

OK.

> > 
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> > 
> > diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> > index 36ee1e38..28f9171c 100644
> > --- a/libdtrace/dt_cg.c
> > +++ b/libdtrace/dt_cg.c
> > @@ -2123,6 +2123,23 @@ dt_cg_ldsize(dt_node_t *dnp, ctf_file_t *ctfp, ctf_id_t type, ssize_t *ret_size)
> >   	return ldstw[size];
> >   }
> > +static void
> > +dt_cg_load_scalar(dt_node_t *dnp, uint_t op, ssize_t size, dt_irlist_t *dlp,
> 
> Why pass in dnp, when all you need is dnp->dn_reg?

I generally pass in the node because the code generator works on nodes.

> Also, how about switching the first two arguments (so that op comes first)? 
> Calls to this function are often paired with BPF_LOAD(), so it's easier to
> read when their argument lists are more similar.

As far as order of arguments...  BPF_LOAD() is a macro that generate a BPF
instruction, whereas dt_cg_load_scalar() is a function that may generate one
or more BPF instructions.  They are not that similar.

> > +		  dt_regset_t *drp)
> > +{
> > +	if (dt_regset_xalloc_args(drp) == -1)
> > +		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> > +	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_SP));
> > +	emit(dlp, BPF_MOV_IMM(BPF_REG_2, size));
> > +	emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));

> It is conceivable that dnp->dn_reg is either %r1 or %r2, in which case we
> just finished overwriting that register.  Just make the %r3=%dnp->dn->reg
> instruction the first of the three.

This is the exiting issue with (lack of) proper register spilling.  In general,
our code generation fails miserably whenever we start using %r1-%r5 and yet
have to call a function (incl. helpers).  So while theoretically, the scenario
you suggest could happen, it generally means we're already going to get into
trouble.  Also, if dnp->dn_reg is %r1 ir %r2, then it is very likely some other
value is stored in %r3 (since we allocate registers in descending order) and
will get clobbered.

> > +	emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_1));

> It is conceivable that dnp->dn_reg is in the range %r1-%r5.  If that's the
> case, then free_args() will fill the register with an old value and the
> stack pointer will have been lost.  Might as well just omit this instruction
> and regenerate the stack pointer when you need it.

Same as above - I'd rather not optimmize based on the (broken) spill/fill
code.

> > +	dt_regset_xalloc(drp, BPF_REG_0);
> > +	emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_read));
> > +	dt_regset_free(drp, BPF_REG_0);
> > +	dt_regset_free_args(drp);
> > +	emit(dlp, BPF_LOAD(op, dnp->dn_reg, dnp->dn_reg, 0));
> 
> One of the lessons of the typecast patches is that when we load
> (less-than-64-bit) integers into 64-bit registers, we need to set the
> high-order bits correctly.  So stick the appropriate LSH/RSH instructions
> here.

Well, actually, it should be conditional based on the sign of the data we
are reading as far as I can see.  As far as I can see, BPF performs the loads
as DST = *(SIZE *)(SRC + off), where SIZE can be u8, u16, u32, or u64.  So,
for unsigned values this should already do the right thing.  For signed values,
we need to perform proper sign extension because BPF will not do that for us.

This also means we actually do need dnp because we need to know whether the
value is signed or not.

I will update the function.

At some point, I hope we can also change this to make uae of the extended BPF
instruction set that allows load instructions on kernel memory addresses.

> > +}
> > +
> >   static void
> >   dt_cg_load_var(dt_node_t *dst, dt_irlist_t *dlp, dt_regset_t *drp)
> >   {
> > @@ -2387,7 +2404,6 @@ dt_cg_field_set(dt_node_t *src, dt_irlist_t *dlp,
> >   	 * r2 <<= shift
> >   	 * r1 |= r2
> >   	 */
> > -	/* FIXME: Does not handle userland */
> >   	emit(dlp, BPF_LOAD(dt_cg_ldsize(dst, fp, m.ctm_type, NULL), r1, dst->dn_reg, 0));
> >   	dt_cg_setx(dlp, r2, cmask);
> >   	emit(dlp, BPF_ALU64_REG(BPF_AND, r1, r2));
> > @@ -5027,20 +5043,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> >   		dnp->dn_reg = dnp->dn_child->dn_reg;
> >   		if (!(dnp->dn_flags & DT_NF_REF)) {
> > -			uint_t	ubit;
> >   			uint_t	op;
> >   			ssize_t	size;
> > -			/*
> > -			 * Save and restore DT_NF_USERLAND across
> > -			 * dt_cg_ldsize(): we need the sign bit from dnp and
> > -			 * the user bit from dnp->dn_child in order to get the
> > -			 * proper opcode.
> > -			 */
> > -			ubit = dnp->dn_flags & DT_NF_USERLAND;
> > -			dnp->dn_flags |=
> > -			    (dnp->dn_child->dn_flags & DT_NF_USERLAND);
> > -
> >   			dt_cg_check_notnull(dlp, drp, dnp->dn_reg);
> >   			op = dt_cg_ldsize(dnp, ctfp, dnp->dn_type, &size);
> > @@ -5056,11 +5061,10 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> >   						 dnp->dn_reg);
> >   			}
> > -			/* FIXME: Does not handled signed or userland */
> > -			emit(dlp, BPF_LOAD(op, dnp->dn_reg, dnp->dn_reg, 0));
> > -
> > -			dnp->dn_flags &= ~DT_NF_USERLAND;
> > -			dnp->dn_flags |= ubit;
> > +			if (dnp->dn_child->dn_flags & DT_NF_DPTR)
> > +				emit(dlp, BPF_LOAD(op, dnp->dn_reg, dnp->dn_reg, 0));
> > +			else
> > +				dt_cg_load_scalar(dnp, op, size, dlp, drp);
> >   		}
> >   		break;
> > @@ -5141,9 +5145,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> >   	case DT_TOK_PTR:
> >   	case DT_TOK_DOT: {
> > -
> >   		assert(dnp->dn_right->dn_kind == DT_NODE_IDENT);
> >   		dt_cg_node(dnp->dn_left, dlp, drp);
> > +
> >   		dt_cg_check_notnull(dlp, drp, dnp->dn_left->dn_reg);
> >   		/*
> > @@ -5203,24 +5207,15 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> >   		}
> >   		if (!(dnp->dn_flags & DT_NF_REF)) {
> > -			uint_t ubit;
> > -
> > -			/*
> > -			 * Save and restore DT_NF_USERLAND across
> > -			 * dt_cg_ldsize(): we need the sign bit from dnp and
> > -			 * the user bit from dnp->dn_left in order to get the
> > -			 * proper opcode.
> > -			 */
> > -			ubit = dnp->dn_flags & DT_NF_USERLAND;
> > -			dnp->dn_flags |=
> > -			    (dnp->dn_left->dn_flags & DT_NF_USERLAND);
> > +			uint_t	op;
> > +			ssize_t	size;
> > -			/* FIXME: Does not handle signed and userland */
> > -			emit(dlp, BPF_LOAD(dt_cg_ldsize(dnp, ctfp, m.ctm_type, NULL),
> > -					   dnp->dn_left->dn_reg, dnp->dn_left->dn_reg, 0));
> > +			op = dt_cg_ldsize(dnp, ctfp, m.ctm_type, &size);
> > -			dnp->dn_flags &= ~DT_NF_USERLAND;
> > -			dnp->dn_flags |= ubit;
> > +			if (dnp->dn_left->dn_flags & DT_NF_DPTR)
> > +				emit(dlp, BPF_LOAD(op, dnp->dn_left->dn_reg, dnp->dn_left->dn_reg, 0));
> > +			else
> > +				dt_cg_load_scalar(dnp->dn_left, op, size, dlp, drp);
> >   			if (dnp->dn_flags & DT_NF_BITFIELD)
> >   				dt_cg_field_get(dnp, dlp, drp, ctfp, &m);
> > @@ -5323,13 +5318,16 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> >   			if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
> >   				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> > -			dt_cg_xsetx(dlp, dnp->dn_ident,
> > -			    DT_LBL_NONE, dnp->dn_reg, sym.st_value);
> > +			dt_cg_xsetx(dlp, dnp->dn_ident, DT_LBL_NONE,
> > +				    dnp->dn_reg, sym.st_value);
> >   			if (!(dnp->dn_flags & DT_NF_REF)) {
> > -				/* FIXME: NO signed or userland yet */
> > -				emit(dlp, BPF_LOAD(dt_cg_ldsize(dnp, ctfp, dnp->dn_type, NULL),
> > -						   dnp->dn_reg, dnp->dn_reg, 0));
> > +				uint_t	op;
> > +				ssize_t	size;
> > +
> > +				op = dt_cg_ldsize(dnp, ctfp, dnp->dn_type, &size);
> > +
> > +				dt_cg_load_scalar(dnp, op, size, dlp, drp);
> >   			}
> >   			break;
> >   		}
> > diff --git a/libdtrace/dt_parser.c b/libdtrace/dt_parser.c
> > index fd89b2c7..49d3ce77 100644
> > --- a/libdtrace/dt_parser.c
> > +++ b/libdtrace/dt_parser.c
> > @@ -2781,6 +2781,13 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
> >   		dnp->dn_ident = idp;
> >   		dnp->dn_flags |= DT_NF_LVALUE;
> > +		/*
> > +		 * If the type of the variable is a REF-type, we mark this
> > +		 * variable node as a pointer to DTrace-managed storage (DPTR).
> > +		 */
> > +		if (dnp->dn_flags & DT_NF_REF)
> > +			dnp->dn_flags |= DT_NF_DPTR;
> > +
> >   		if (idp->di_flags & DT_IDFLG_WRITE)
> >   			dnp->dn_flags |= DT_NF_WRITABLE;
> > @@ -2907,6 +2914,13 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
> >   		dnp->dn_ident = idp;
> >   		dnp->dn_flags |= DT_NF_LVALUE | DT_NF_WRITABLE;
> > +		/*
> > +		 * If the type of the variable is a REF-type, we mark this
> > +		 * variable node as a pointer to DTrace-managed storage (DPTR).
> > +		 */
> > +		if (dnp->dn_flags & DT_NF_REF)
> > +			dnp->dn_flags |= DT_NF_DPTR;
> > +
> >   		/*
> >   		 * Still a good idea, but not relevant for assignments: see
> >   		 * dt_cook_ident:DT_TOK_ASGN for more.  In particular, this is
> > @@ -3235,7 +3249,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   	ctf_membinfo_t m;
> >   	ctf_file_t *ctfp;
> >   	ctf_id_t type;
> > -	int kind, val, uref;
> > +	int kind, val, xflags;
> >   	dt_ident_t *idp;
> >   	char n1[DT_TYPE_NAMELEN];
> > @@ -3465,20 +3479,20 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   		if (lp_is_int && rp_is_int) {
> >   			dt_type_promote(lp, rp, &ctfp, &type);
> > -			uref = 0;
> > +			xflags = 0;
> >   		} else if (lp_is_ptr && rp_is_int) {
> >   			ctfp = lp->dn_ctfp;
> >   			type = lp->dn_type;
> > -			uref = lp->dn_flags & DT_NF_USERLAND;
> > +			xflags = lp->dn_flags & (DT_NF_USERLAND | DT_NF_DPTR);
> >   		} else if (lp_is_int && rp_is_ptr && op == DT_TOK_ADD) {
> >   			ctfp = rp->dn_ctfp;
> >   			type = rp->dn_type;
> > -			uref = rp->dn_flags & DT_NF_USERLAND;
> > +			xflags = rp->dn_flags & (DT_NF_USERLAND | DT_NF_DPTR);
> >   		} else if (lp_is_ptr && rp_is_ptr && op == DT_TOK_SUB &&
> >   		    dt_node_is_ptrcompat(lp, rp, NULL, NULL)) {
> >   			ctfp = dtp->dt_ddefs->dm_ctfp;
> >   			type = ctf_lookup_by_name(ctfp, "ptrdiff_t");
> > -			uref = 0;
> > +			xflags = 0;
> >   		} else
> >   			xyerror(D_OP_INCOMPAT, "operands have incompatible "
> >   			    "types: \"%s\" %s \"%s\"\n",
> > @@ -3503,7 +3517,6 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   		/*
> >   		 * Array bounds-checking.  (Non-associative arrays only.)
> >   		 */
> > -
> >   		artype = ctf_type_resolve(lp->dn_ctfp, lp->dn_type);
> >   		arkind = ctf_type_kind(lp->dn_ctfp, artype);
> > @@ -3525,8 +3538,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   		dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
> >   		dt_node_prop_alloca(dnp, lp, rp);
> > -		if (uref)
> > -			dnp->dn_flags |= DT_NF_USERLAND;
> > +		if (xflags)
> > +			dnp->dn_flags |= xflags;
> >   		break;
> >   	}
> > @@ -3649,11 +3662,11 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   		if ((idp = dt_node_resolve(rp, DT_IDENT_XLSOU)) != NULL) {
> >   			ctfp = idp->di_ctfp;
> >   			type = idp->di_type;
> > -			uref = idp->di_flags & DT_IDFLG_USER;
> > +			xflags = idp->di_flags & DT_IDFLG_USER;
> >   		} else {
> >   			ctfp = rp->dn_ctfp;
> >   			type = rp->dn_type;
> > -			uref = rp->dn_flags & DT_NF_USERLAND;
> > +			xflags = rp->dn_flags & DT_NF_USERLAND;
> >   		}
> >   		/*
> > @@ -3679,7 +3692,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
> >   			dt_ident_type_assign(lp->dn_ident, ctfp, type);
> >   			dt_ident_set_storage(lp->dn_ident, alignment, size);
> > -			if (uref) {
> > +			if (xflags) {
> >   				lp->dn_flags |= DT_NF_USERLAND;
> >   				lp->dn_ident->di_flags |= DT_IDFLG_USER;
> >   			}
> > @@ -3861,11 +3874,11 @@ asgn_common:
> >   			ctfp = idp->di_ctfp;
> >   			type = ctf_type_resolve(ctfp, idp->di_type);
> > -			uref = idp->di_flags & DT_IDFLG_USER;
> > +			xflags = idp->di_flags & DT_IDFLG_USER;
> >   		} else {
> >   			ctfp = lp->dn_ctfp;
> >   			type = ctf_type_resolve(ctfp, lp->dn_type);
> > -			uref = lp->dn_flags & DT_NF_USERLAND;
> > +			xflags = lp->dn_flags & DT_NF_USERLAND;
> >   		}
> >   		kind = ctf_type_kind(ctfp, type);
> > @@ -3936,7 +3949,7 @@ asgn_common:
> >   		if (lp->dn_flags & DT_NF_WRITABLE)
> >   			dnp->dn_flags |= DT_NF_WRITABLE;
> > -		if (uref && (kind == CTF_K_POINTER ||
> > +		if (xflags && (kind == CTF_K_POINTER ||
> >   		    (dnp->dn_flags & DT_NF_REF)))
> >   			dnp->dn_flags |= DT_NF_USERLAND;
> >   		break;
> > @@ -4855,6 +4868,8 @@ dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
> >   			strcat(n, ",ALLOCA");
> >   		if (dnp->dn_flags & DT_NF_NONASSIGN)
> >   			strcat(n, ",NONASSIGN");
> > +		if (dnp->dn_flags & DT_NF_DPTR)
> > +			strcat(n, ",DPTR");
> >   		strcat(buf, n + 1);
> >   	} else
> >   		strcat(buf, "0");
> > diff --git a/libdtrace/dt_parser.h b/libdtrace/dt_parser.h
> > index 941ca47b..a8aecb9a 100644
> > --- a/libdtrace/dt_parser.h
> > +++ b/libdtrace/dt_parser.h
> > @@ -160,6 +160,7 @@ typedef struct dt_node {
> >   #define	DT_NF_USERLAND	0x40	/* data is a userland address */
> >   #define	DT_NF_ALLOCA	0x80	/* pointer derived from alloca() */
> >   #define	DT_NF_NONASSIGN	0x100	/* node is not assignable */
> > +#define	DT_NF_DPTR	0x200	/* node is a ptr to DTrace-managed storage */
> >   #define	DT_TYPE_NAMELEN	128	/* reasonable size for ctf_type_name() */
> > diff --git a/test/unittest/arrays/tst.ctf-bounds.d b/test/unittest/arrays/tst.ctf-bounds.d
> > index e60bd5aa..aff9b7f1 100644
> > --- a/test/unittest/arrays/tst.ctf-bounds.d
> > +++ b/test/unittest/arrays/tst.ctf-bounds.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/arrays/tst.ctf-bounds.oob-cast.d b/test/unittest/arrays/tst.ctf-bounds.oob-cast.d
> > index 2ee701e5..988f3472 100644
> > --- a/test/unittest/arrays/tst.ctf-bounds.oob-cast.d
> > +++ b/test/unittest/arrays/tst.ctf-bounds.oob-cast.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/arrays/tst.declared-bounds.oob-cast.d b/test/unittest/arrays/tst.declared-bounds.oob-cast.d
> > index fe63ee8e..296b4ccf 100644
> > --- a/test/unittest/arrays/tst.declared-bounds.oob-cast.d
> > +++ b/test/unittest/arrays/tst.declared-bounds.oob-cast.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/builtinvar/tst.hpriority.d b/test/unittest/builtinvar/tst.hpriority.d
> > index f5adf3f5..a77c87f1 100644
> > --- a/test/unittest/builtinvar/tst.hpriority.d
> > +++ b/test/unittest/builtinvar/tst.hpriority.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 - uses reading from kernel addresses */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/builtinvar/tst.lwpsinfo.d b/test/unittest/builtinvar/tst.lwpsinfo.d
> > index 272ecdfe..1e476bde 100644
> > --- a/test/unittest/builtinvar/tst.lwpsinfo.d
> > +++ b/test/unittest/builtinvar/tst.lwpsinfo.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/builtinvar/tst.lwpsinfo1.d b/test/unittest/builtinvar/tst.lwpsinfo1.d
> > index 6011670d..a445f190 100644
> > --- a/test/unittest/builtinvar/tst.lwpsinfo1.d
> > +++ b/test/unittest/builtinvar/tst.lwpsinfo1.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 - uses reading from kernel addresses */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/codegen/tst.kernel_read_deref_indirect_scalar.d b/test/unittest/codegen/tst.kernel_read_deref_indirect_scalar.d
> > new file mode 100644
> > index 00000000..9d8bdc69
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_deref_indirect_scalar.d
> > @@ -0,0 +1,20 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	ptr = &`max_pfn;
> > +	trace(*ptr);
> > +	exit(0);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_deref_indirect_str.d b/test/unittest/codegen/tst.kernel_read_deref_indirect_str.d
> > new file mode 100644
> > index 00000000..81a1671c
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_deref_indirect_str.d
> > @@ -0,0 +1,18 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	exit(*`linux_banner == 76 ? 0 : 1);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_deref_struct.d b/test/unittest/codegen/tst.kernel_read_deref_struct.d
> > new file mode 100644
> > index 00000000..5baf604c
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_deref_struct.d
> > @@ -0,0 +1,19 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	trace(*`cad_pid);
> > +	exit(0);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_index_indirect_str.d b/test/unittest/codegen/tst.kernel_read_index_indirect_str.d
> > new file mode 100644
> > index 00000000..7aa89a40
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_index_indirect_str.d
> > @@ -0,0 +1,21 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +char	*s;
> > +
> > +BEGIN
> > +{
> > +	s = `linux_banner;
> > +	exit(s[0] == 76 ? 0 : 1);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_indirect_scalar.d b/test/unittest/codegen/tst.kernel_read_indirect_scalar.d
> > new file mode 100644
> > index 00000000..3683d4aa
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_indirect_scalar.d
> > @@ -0,0 +1,19 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	trace(`cad_pid->level);
> > +	exit(0);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_mixed.d b/test/unittest/codegen/tst.kernel_read_mixed.d
> > new file mode 100644
> > index 00000000..d1cf9ec6
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_mixed.d
> > @@ -0,0 +1,18 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	exit(curthread->thread_pid->numbers[0].nr == pid ? 0 : 1);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_scalar.d b/test/unittest/codegen/tst.kernel_read_scalar.d
> > new file mode 100644
> > index 00000000..bbc2d06f
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_scalar.d
> > @@ -0,0 +1,19 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	trace(`max_pfn);
> > +	exit(0);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.kernel_read_str.d b/test/unittest/codegen/tst.kernel_read_str.d
> > new file mode 100644
> > index 00000000..4ff61b8c
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.kernel_read_str.d
> > @@ -0,0 +1,19 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +BEGIN
> > +{
> > +	trace((string)`linux_banner);
> > +	exit(0);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/codegen/tst.read_index_indirect_str.d b/test/unittest/codegen/tst.read_index_indirect_str.d
> > new file mode 100644
> > index 00000000..a1a1a293
> > --- /dev/null
> > +++ b/test/unittest/codegen/tst.read_index_indirect_str.d
> > @@ -0,0 +1,21 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +#pragma D option quiet
> > +
> > +char	*s;
> > +
> > +BEGIN
> > +{
> > +	s = probeprov;
> > +	exit(s[0] == 100 ? 0 : 1);
> > +}
> > +
> > +ERROR
> > +{
> > +	exit(1);
> > +}
> > diff --git a/test/unittest/funcs/tst.bcopy.d b/test/unittest/funcs/tst.bcopy.d
> > index 797e891e..6806efec 100644
> > --- a/test/unittest/funcs/tst.bcopy.d
> > +++ b/test/unittest/funcs/tst.bcopy.d
> > @@ -22,8 +22,7 @@ BEGIN
> >   	ptr = alloca(sizeof(unsigned long));
> >   	bcopy((void *)&`max_pfn, ptr, sizeof(unsigned long));
> >   	ulongp = (unsigned long *)ptr;
> > -        /* DTv2: doing this needs deref-implies-copyin, which isn't there yet. */
> > -/*	ret = (`max_pfn == *ulongp) ? 0 : 1; */
> > +	ret = (`max_pfn == *ulongp) ? 0 : 1;
> >   	ret = *ulongp; ret = 0;
> >   	ulong_deref = *ulongp;
> >   }
> > @@ -37,9 +36,8 @@ tick-1
> >   tick-1
> >   /ret == 1/
> >   {
> > -	/* DTdv2: this error message has the same problem.  */
> > -/*	printf("memory address contained 0x%x, expected 0x%x\n",
> > -		ulong_deref, `max_pfn); */
> > +	printf("memory address contained 0x%x, expected 0x%x\n",
> > +		ulong_deref, `max_pfn);
> >   	printf("memory address contained wrong contents\n");
> >   	exit(1);
> >   }
> > diff --git a/test/unittest/inline/tst.InlineTypedef.d b/test/unittest/inline/tst.InlineTypedef.d
> > index d69185ca..21a7a3df 100644
> > --- a/test/unittest/inline/tst.InlineTypedef.d
> > +++ b/test/unittest/inline/tst.InlineTypedef.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 - uses reading from kernel addresses */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/lexer/tst.keyword-member.d b/test/unittest/lexer/tst.keyword-member.d
> > index 6d7ea159..42c0db78 100644
> > --- a/test/unittest/lexer/tst.keyword-member.d
> > +++ b/test/unittest/lexer/tst.keyword-member.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 - uses reading from kernel addresses */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/pointers/tst.ArrayPointer2.d b/test/unittest/pointers/tst.ArrayPointer2.d
> > index 61168647..ed4b77bb 100644
> > --- a/test/unittest/pointers/tst.ArrayPointer2.d
> > +++ b/test/unittest/pointers/tst.ArrayPointer2.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION: D permits the use of array [] index notation with both pointer
> > diff --git a/test/unittest/pointers/tst.ArrayPointer3.d b/test/unittest/pointers/tst.ArrayPointer3.d
> > index fd1dad3d..2421bcd7 100644
> > --- a/test/unittest/pointers/tst.ArrayPointer3.d
> > +++ b/test/unittest/pointers/tst.ArrayPointer3.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION: In D, the an array variable can be assigned to a pointer.
> > diff --git a/test/unittest/pointers/tst.GlobalVar.d b/test/unittest/pointers/tst.GlobalVar.d
> > index 3ec73bd3..9127eb69 100644
> > --- a/test/unittest/pointers/tst.GlobalVar.d
> > +++ b/test/unittest/pointers/tst.GlobalVar.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION: Pointer declarations are global.
> > diff --git a/test/unittest/pointers/tst.IntegerArithmetic1.d b/test/unittest/pointers/tst.IntegerArithmetic1.d
> > index 7bf97574..b109e5bb 100644
> > --- a/test/unittest/pointers/tst.IntegerArithmetic1.d
> > +++ b/test/unittest/pointers/tst.IntegerArithmetic1.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/pointers/tst.PointerArithmetic2.d b/test/unittest/pointers/tst.PointerArithmetic2.d
> > index 1e9ed77e..9574cacc 100644
> > --- a/test/unittest/pointers/tst.PointerArithmetic2.d
> > +++ b/test/unittest/pointers/tst.PointerArithmetic2.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/pointers/tst.VoidCast.d b/test/unittest/pointers/tst.VoidCast.d
> > index 8c831e6a..9b8e1395 100644
> > --- a/test/unittest/pointers/tst.VoidCast.d
> > +++ b/test/unittest/pointers/tst.VoidCast.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/pointers/tst.basic1.d b/test/unittest/pointers/tst.basic1.d
> > index e0b9e3cd..d0d50a24 100644
> > --- a/test/unittest/pointers/tst.basic1.d
> > +++ b/test/unittest/pointers/tst.basic1.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION: Pointers can be stored in variables.
> > diff --git a/test/unittest/printf/tst.str.d b/test/unittest/printf/tst.str.d
> > index ce5af45e..2ea55277 100644
> > --- a/test/unittest/printf/tst.str.d
> > +++ b/test/unittest/printf/tst.str.d
> > @@ -1,10 +1,9 @@
> >   /*
> >    * Oracle Linux DTrace.
> > - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> > + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 - uses reading from kernel addresses */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/sched/tst.var-curcpu.d b/test/unittest/sched/tst.var-curcpu.d
> > index 2f047342..113401ae 100644
> > --- a/test/unittest/sched/tst.var-curcpu.d
> > +++ b/test/unittest/sched/tst.var-curcpu.d
> > @@ -5,7 +5,6 @@
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /* @@trigger: none */
> >   cpuinfo_t	*cpuinfo;
> > diff --git a/test/unittest/trace/tst.misc.d b/test/unittest/trace/tst.misc.d
> > index cbb8a003..96d9c3d7 100644
> > --- a/test/unittest/trace/tst.misc.d
> > +++ b/test/unittest/trace/tst.misc.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /*
> >    * ASSERTION:
> > diff --git a/test/unittest/translators/tst.TestTransStability.d b/test/unittest/translators/tst.TestTransStability.d
> > index 477733e5..fcdbbee1 100644
> > --- a/test/unittest/translators/tst.TestTransStability.d
> > +++ b/test/unittest/translators/tst.TestTransStability.d
> > @@ -5,7 +5,6 @@
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   /* @@runtest-opts: -v */
> >   /*
> > diff --git a/test/unittest/vars/tst.gid.d b/test/unittest/vars/tst.gid.d
> > index e4b6872e..6260bbdb 100644
> > --- a/test/unittest/vars/tst.gid.d
> > +++ b/test/unittest/vars/tst.gid.d
> > @@ -4,7 +4,6 @@
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > -/* @@xfail: dtv2 */
> >   #pragma D option quiet
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list