Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jul 2025 14:58:16 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: dabde7d97680 - main - libdtrace: Permit taking the address of an identifier without type info
Message-ID:  <202507211458.56LEwGL7053851@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=dabde7d97680cac7e0ead56693d424f4e5631019

commit dabde7d97680cac7e0ead56693d424f4e5631019
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-07-21 13:34:30 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-21 14:57:58 +0000

    libdtrace: Permit taking the address of an identifier without type info
    
    Symbols defined using assembler directives lack type info, but in this
    case one ought to be able to cast a pointer to the symbol and
    dereference the pointer to get a value.  Without this change, D
    disallows this trick since it requires all identifiers to have a type.
    
    Relax the rules slightly and allow an identifier to have type "void" if
    we know we're just taking its address.
    
    As a result, the following dtrace invocation works:
    
      dtrace -n 'tick-1s {printf("%d", *(int *)&`ticks);}'
    
    In particular, since commit b2b974f7ef4c ("clock: Simplify subr_ticks
    and rename"), "ticks" does not have any type info associated with it, so
    its value couldn't be printed.  This trick provides a workaround and is
    probably generally useful.
    
    Add a regression test which exercises this functionality.
    
    PR:             287752
    Reviewed by:    avg
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D51417
---
 .../dtrace/test/tst/common/profile-n/tst.ticks.d   | 54 ++++++++++++++++++++++
 .../opensolaris/lib/libdtrace/common/dt_parser.c   | 25 ++++++++--
 .../opensolaris/lib/libdtrace/common/dt_parser.h   |  1 +
 .../dtrace/tests/common/profile-n/Makefile         |  1 +
 4 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ticks.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ticks.d
new file mode 100644
index 000000000000..4061db9858c1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ticks.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2025 Mark Johnston <markj@FreeBSD.org>
+ */
+
+/*
+ * For 10s, verify that the value of `ticks goes up by `hz each second.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	i = 0;
+}
+
+tick-1s
+{
+	if (i == 0) {
+		t = *(int *)&`ticks;
+		i++;
+	} else {
+		u = *(int *)&`ticks;
+		if (u - t != `hz) {
+			printf("ticks: %d, expected %d\n", u - t, `hz);
+			exit(1);
+		}
+		t = u;
+		i++;
+		if (i == 10) {
+			exit(0);
+		}
+	}
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index dd68f9278308..8cc504856567 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -1918,6 +1918,14 @@ dt_node_op1(int op, dt_node_t *cp)
 		return (cp);
 	}
 
+	/*
+	 * When applying the addressof operator to an identifier, it's okay if
+	 * we can't find type information for the identifier, so flag the node
+	 * to ensure that we don't raise an error.
+	 */
+	if (op == DT_TOK_ADDROF && cp->dn_kind == DT_NODE_IDENT)
+		cp->dn_flags |= DT_NF_IDENTADDR;
+
 	dnp = dt_node_alloc(DT_NODE_OP1);
 	assert(op <= USHRT_MAX);
 	dnp->dn_op = (ushort_t)op;
@@ -2786,10 +2794,21 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 				    dt_module_modelname(dtp->dt_ddefs));
 			}
 
-			xyerror(D_SYM_NOTYPES,
+			/*
+			 * If we're taking the address of an identifier that
+			 * doesn't have type info, try to make it a void *.
+			 * This lets us use identifiers that are defined in
+			 * assembly and don't have type information.
+			 */
+			if ((dnp->dn_flags & DT_NF_IDENTADDR) == 0 ||
+			    dtrace_lookup_by_type(dtp, DTRACE_OBJ_CDEFS,
+			    "void", &dtt) != 0) {
+				xyerror(D_SYM_NOTYPES,
 			    "no symbolic type information is available for "
-			    "%s%s%s: %s\n", dts.dts_object, mark, dts.dts_name,
-			    dtrace_errmsg(dtp, dtrace_errno(dtp)));
+				    "%s%s%s: %s\n", dts.dts_object, mark,
+				    dts.dts_name,
+				    dtrace_errmsg(dtp, dtrace_errno(dtp)));
+			}
 		}
 
 		idp = dt_ident_create(name, DT_IDENT_SYMBOL, 0, 0,
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
index 3a146c5d2592..1d2f33beee0f 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
@@ -182,6 +182,7 @@ typedef struct dt_node {
 #define	DT_NF_WRITABLE	0x10	/* node is writable (can be modified) */
 #define	DT_NF_BITFIELD	0x20	/* node is an integer bitfield */
 #define	DT_NF_USERLAND	0x40	/* data is a userland address */
+#define	DT_NF_IDENTADDR	0x80	/* node is an identifier address */
 
 #define	DT_TYPE_NAMELEN	128	/* reasonable size for ctf_type_name() */
 
diff --git a/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile b/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile
index 84f4706b61ee..ceb52fcf5bd0 100644
--- a/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile
+++ b/cddl/usr.sbin/dtrace/tests/common/profile-n/Makefile
@@ -37,6 +37,7 @@ ${PACKAGE}FILES= \
      tst.profileusec.d  \
      tst.profileusec.d.out  \
      tst.sym.ksh  \
+     tst.ticks.d  \
      tst.ufunc.ksh  \
      tst.ufuncsort.ksh  \
      tst.ufuncsort.ksh.out  \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202507211458.56LEwGL7053851>