git: 4196f227aa84 - main - libdtrace: Be less strict when comparing pointer types

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 01 Jan 2025 00:05:14 UTC
The branch main has been updated by markj:

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

commit 4196f227aa84448ef3cae9e99678fbe787726cf7
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-12-31 19:25:52 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-01 00:05:03 +0000

    libdtrace: Be less strict when comparing pointer types
    
    If one of two pointers refers to a forward declaration, let the pointers
    be compatible so long as the referred types have the same name.
    Otherwise we can get spurious errors.
    
    To give a specific example, this can happen when ipfw_nat.ko is loaded
    before ipfw.ko and /usr/lib/dtrace/ipfw.d is processed.  Currently,
    ipfw_nat.ko does not have a definition for struct inpcb (i.e., none of
    its files include in_pcb.h), so in the CTF type graph, struct
    ip_fw_args' "inp" member refers to a forward declaration, represented in
    CTF with CTF_K_FORWARD.
    
    Then, when libdtrace processes the ipfw_match_info_t translator in
    ipfw.d, it decides that the "inp" field assignment is incorrect because
    the two pointers are incompatible.  However, there's no harm in allowing
    this assignment.  Add some logic to dt_node_is_ptrcompat() to detect
    this case and declare the pointers as compatible so long as the name of
    the thing they refer to is the same, similar to how any pointer is
    compatible with a void *.
    
    Reported by:    marck
    Reviewed by:    Domagoj Stolfa <domagoj.stolfa@gmail.com>
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D48254
---
 .../opensolaris/lib/libdtrace/common/dt_parser.c   | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index 2b85dd2b26b6..d1ebaa8791da 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -1130,6 +1130,29 @@ dt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp,
 	lp_is_void = ctf_type_encoding(lfp, lref, &e) == 0 && IS_VOID(e);
 	rp_is_void = ctf_type_encoding(rfp, rref, &e) == 0 && IS_VOID(e);
 
+	/*
+	 * Let a pointer to a forward declaration be compatible with a pointer
+	 * to a struct or union of the same name.
+	 */
+	if (lkind == CTF_K_POINTER && rkind == CTF_K_POINTER) {
+		int lrkind, rrkind;
+
+		lrkind = ctf_type_kind(lfp, lref);
+		rrkind = ctf_type_kind(rfp, rref);
+		if (lrkind == CTF_K_FORWARD || rrkind == CTF_K_FORWARD) {
+			const char *lname, *rname;
+			char ln[DT_TYPE_NAMELEN], rn[DT_TYPE_NAMELEN];
+
+			lname = ctf_type_name(lfp, lref, ln, sizeof (ln));
+			rname = ctf_type_name(rfp, rref, rn, sizeof (rn));
+			if (lname != NULL && rname != NULL &&
+			    strcmp(lname, rname) == 0) {
+				lp_is_void = lrkind == CTF_K_FORWARD;
+				rp_is_void = rrkind == CTF_K_FORWARD;
+			}
+		}
+	}
+
 	/*
 	 * The types are compatible if both are pointers to the same type, or
 	 * if either pointer is a void pointer.  If they are compatible, set