The branch main has been updated by markj:

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

commit dabde7d97680cac7e0ead56693d424f4e5631019
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2025-07-21 13:34:30 +0000
Commit:     Mark Johnston <ma...@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 <ma...@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  \

Reply via email to