aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2015-05-10 21:39:24 +0000
committerMark Johnston <markj@FreeBSD.org>2015-05-10 21:39:24 +0000
commit3e5645b78f476816ca3b5acc28b29bbafbb9c444 (patch)
tree6b678e85c73a5c729ecc4e4a0cf188da3436a4bf /cddl/contrib
parent55b130956d63f4aa283b24b0db3dc3d61f6c0ec0 (diff)
downloadsrc-3e5645b78f476816ca3b5acc28b29bbafbb9c444.tar.gz
src-3e5645b78f476816ca3b5acc28b29bbafbb9c444.zip
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 Reported by: rwatson MFC after: 3 weeks
Notes
Notes: svn path=/head/; revision=282739
Diffstat (limited to 'cddl/contrib')
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_create.c21
1 files 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 1c0988a38783..a2ca81960f73 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);
}
}