mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 01:30:30 -04:00
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 b2b974f7ef ("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
This commit is contained in:
parent
654dea5967
commit
dabde7d976
4 changed files with 78 additions and 3 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
Loading…
Reference in a new issue