From 237f43434eda4d5ec56a015e2865c3747cf36da3 Mon Sep 17 00:00:00 2001 From: markj Date: Sun, 7 Jun 2015 19:48:21 +0000 Subject: [PATCH] MFC r282739: ctf_add_type(): when looking up an integer or floating point type in the list of pending dynamic type definitions, a match on the type name is not sufficient - we need to compare the type encodings as well. For example, bitfields have their own distinct type definitions which share the name of the underlying integer type, and these types aren't generally interchangeable. This bug was causing the following libdtrace error when attempting to trace the th_flags member of a struct tcphdr: cg: bad field: off 104 type <32877> bits 539620016 git-svn-id: svn://svn.freebsd.org/base/stable/10@284132 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- .../opensolaris/common/ctf/ctf_create.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c index 452c748a3..c5feb3f08 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c @@ -1328,15 +1328,28 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) * we are looking for. This is necessary to permit ctf_add_type() to * operate recursively on entities such as a struct that contains a * pointer member that refers to the same struct type. + * + * In the case of integer and floating point types, we match using the + * type encoding as well - else we may incorrectly return a bitfield + * type, for instance. */ if (dst_type == CTF_ERR && name[0] != '\0') { for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL && CTF_TYPE_TO_INDEX(dtd->dtd_type) > dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) { - if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) == kind && - dtd->dtd_name != NULL && - strcmp(dtd->dtd_name, name) == 0) - return (dtd->dtd_type); + if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != kind || + dtd->dtd_name == NULL || + strcmp(dtd->dtd_name, name) != 0) + continue; + if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT) { + if (ctf_type_encoding(src_fp, src_type, + &src_en) != 0) + continue; + if (bcmp(&src_en, &dtd->dtd_u.dtu_enc, + sizeof (ctf_encoding_t)) != 0) + continue; + } + return (dtd->dtd_type); } } -- 2.45.2