diff options
Diffstat (limited to 'cddl/contrib/opensolaris/common/ctf/ctf_create.c')
-rw-r--r-- | cddl/contrib/opensolaris/common/ctf/ctf_create.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c index 736481482751..a2ca81960f73 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c @@ -583,10 +583,10 @@ ctf_discard(ctf_file_t *fp) return (0); /* no update required */ for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { - if (dtd->dtd_type <= fp->ctf_dtoldid) + ntd = ctf_list_prev(dtd); + if (CTF_TYPE_TO_INDEX(dtd->dtd_type) <= fp->ctf_dtoldid) continue; /* skip types that have been committed */ - ntd = ctf_list_prev(dtd); ctf_dtd_delete(fp, dtd); } @@ -1313,10 +1313,13 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) * unless dst_type is a forward declaration and src_type is a struct, * union, or enum (i.e. the definition of the previous forward decl). */ - if (dst_type != CTF_ERR && dst_kind != kind && ( - dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM && - kind != CTF_K_STRUCT && kind != CTF_K_UNION))) - return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); + if (dst_type != CTF_ERR && dst_kind != kind) { + if (dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM && + kind != CTF_K_STRUCT && kind != CTF_K_UNION)) + return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); + else + dst_type = CTF_ERR; + } /* * If the non-empty name was not found in the appropriate hash, search @@ -1325,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 && - dtd->dtd_type > dst_fp->ctf_dtoldid; + 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); } } |