From a6fb86917362e3f6d24e95e940e80845c2cfde8a Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 7 Mar 2022 08:53:27 -0500 Subject: [PATCH] libctf: Handle CTFv3 containers In general, the patch adds indirection to minimize the amount of code that needs to know about differences between v2 and v3. Specifically, some new ctf_get_ctt_* functions are added, and new LCTF_* macros are added to use the underlying container's version to do the right thing. CTF containers can have parent/child relationships, wherein a type ID in one container refers to a type in the parent. It is permitted for the parent and child to have different versions. MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34363 --- .../opensolaris/common/ctf/ctf_create.c | 371 +++++++++------ .../contrib/opensolaris/common/ctf/ctf_decl.c | 19 +- .../contrib/opensolaris/common/ctf/ctf_hash.c | 16 +- .../contrib/opensolaris/common/ctf/ctf_impl.h | 65 ++- .../opensolaris/common/ctf/ctf_lookup.c | 38 +- .../contrib/opensolaris/common/ctf/ctf_open.c | 367 +++++++++++---- .../opensolaris/common/ctf/ctf_types.c | 437 ++++++++++++------ .../opensolaris/lib/libctf/common/ctf_lib.c | 3 +- 8 files changed, 895 insertions(+), 421 deletions(-) diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c index 35a43cc4e79..154cefb775b 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c @@ -87,48 +87,85 @@ ctf_create(int *errp) } static uchar_t * -ctf_copy_smembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) +ctf_copy_smembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff, + uchar_t *t) { ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); - ctf_member_t ctm; + size_t sz; + uint_t name; for (; dmd != NULL; dmd = ctf_list_next(dmd)) { if (dmd->dmd_name) { - ctm.ctm_name = soff; + name = soff; soff += strlen(dmd->dmd_name) + 1; } else - ctm.ctm_name = 0; + name = 0; - ctm.ctm_type = (ushort_t)dmd->dmd_type; - ctm.ctm_offset = (ushort_t)dmd->dmd_offset; + if (fp->ctf_version == CTF_VERSION_2) { + struct ctf_member_v2 ctm; - bcopy(&ctm, t, sizeof (ctm)); - t += sizeof (ctm); + ctm.ctm_name = name; + ctm.ctm_type = (ushort_t)dmd->dmd_type; + ctm.ctm_offset = (ushort_t)dmd->dmd_offset; + + sz = sizeof (ctm); + bcopy(&ctm, t, sz); + t += sz; + } else { + struct ctf_member_v3 ctm; + + ctm.ctm_name = name; + ctm.ctm_type = dmd->dmd_type; + ctm.ctm_offset = dmd->dmd_offset; + + sz = sizeof (ctm); + bcopy(&ctm, t, sz); + t += sz; + } } return (t); } static uchar_t * -ctf_copy_lmembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) +ctf_copy_lmembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff, + uchar_t *t) { ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); - ctf_lmember_t ctlm; + size_t sz; + uint_t name; for (; dmd != NULL; dmd = ctf_list_next(dmd)) { if (dmd->dmd_name) { - ctlm.ctlm_name = soff; + name = soff; soff += strlen(dmd->dmd_name) + 1; } else - ctlm.ctlm_name = 0; + name = 0; + + if (fp->ctf_version == CTF_VERSION_2) { + struct ctf_lmember_v2 ctlm; - ctlm.ctlm_type = (ushort_t)dmd->dmd_type; - ctlm.ctlm_pad = 0; - ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); - ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); + ctlm.ctlm_name = name; + ctlm.ctlm_type = (ushort_t)dmd->dmd_type; + ctlm.ctlm_pad = 0; + ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); + ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); - bcopy(&ctlm, t, sizeof (ctlm)); - t += sizeof (ctlm); + sz = sizeof (ctlm); + bcopy(&ctlm, t, sz); + t += sz; + } else { + struct ctf_lmember_v3 ctlm; + + ctlm.ctlm_name = name; + ctlm.ctlm_type = dmd->dmd_type; + ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); + ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); + + sz = sizeof (ctlm); + bcopy(&ctlm, t, sz); + t += sz; + } } return (t); @@ -259,7 +296,7 @@ ctf_update(ctf_file_t *fp) */ bzero(&hdr, sizeof (hdr)); hdr.cth_magic = CTF_MAGIC; - hdr.cth_version = CTF_VERSION; + hdr.cth_version = fp->ctf_version; if (fp->ctf_flags & LCTF_CHILD) hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */ @@ -271,13 +308,20 @@ ctf_update(ctf_file_t *fp) for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next(dtd)) { - uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); - uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); + uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); + uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); - if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT) - size += sizeof (ctf_stype_t); - else - size += sizeof (ctf_type_t); + if (fp->ctf_version == CTF_VERSION_2) { + if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT) + size += sizeof (struct ctf_stype_v2); + else + size += sizeof (struct ctf_type_v2); + } else { + if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp)) + size += sizeof (struct ctf_stype_v3); + else + size += sizeof (struct ctf_type_v3); + } switch (kind) { case CTF_K_INTEGER: @@ -285,17 +329,32 @@ ctf_update(ctf_file_t *fp) size += sizeof (uint_t); break; case CTF_K_ARRAY: - size += sizeof (ctf_array_t); + size += fp->ctf_version == CTF_VERSION_2 ? + sizeof (struct ctf_array_v2) : + sizeof (struct ctf_array_v3); break; case CTF_K_FUNCTION: - size += sizeof (ushort_t) * (vlen + (vlen & 1)); + size += roundup2(fp->ctf_idwidth * vlen, 4); break; case CTF_K_STRUCT: case CTF_K_UNION: - if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH) - size += sizeof (ctf_member_t) * vlen; - else - size += sizeof (ctf_lmember_t) * vlen; + if (fp->ctf_version == CTF_VERSION_2) { + if (dtd->dtd_data.ctt_size < + LCTF_LSTRUCT_THRESH(fp)) + size += sizeof (struct ctf_member_v2) * + vlen; + else + size += sizeof (struct ctf_lmember_v2) * + vlen; + } else { + if (dtd->dtd_data.ctt_size < + LCTF_LSTRUCT_THRESH(fp)) + size += sizeof (struct ctf_member_v3) * + vlen; + else + size += sizeof (struct ctf_lmember_v3) * + vlen; + } break; case CTF_K_ENUM: size += sizeof (ctf_enum_t) * vlen; @@ -328,11 +387,11 @@ ctf_update(ctf_file_t *fp) */ for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next(dtd)) { + void *tp; + uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); + uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); + struct ctf_type_v2 ctt; - uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); - uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); - - ctf_array_t cta; uint_t encoding; size_t len; @@ -344,12 +403,27 @@ ctf_update(ctf_file_t *fp) } else dtd->dtd_data.ctt_name = 0; - if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT) - len = sizeof (ctf_stype_t); - else - len = sizeof (ctf_type_t); + if (fp->ctf_version == CTF_VERSION_2) { + ctt.ctt_name = dtd->dtd_data.ctt_name; + ctt.ctt_info = (ushort_t)dtd->dtd_data.ctt_info; + ctt.ctt_size = (ushort_t)dtd->dtd_data.ctt_size; + if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT) + len = sizeof (struct ctf_stype_v2); + else { + len = sizeof (struct ctf_type_v2); + ctt.ctt_lsizehi = dtd->dtd_data.ctt_lsizehi; + ctt.ctt_lsizelo = dtd->dtd_data.ctt_lsizelo; + } + tp = &ctt; + } else { + if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp)) + len = sizeof (struct ctf_stype_v3); + else + len = sizeof (struct ctf_type_v3); + tp = &dtd->dtd_data; + } - bcopy(&dtd->dtd_data, t, len); + bcopy(tp, t, len); t += len; switch (kind) { @@ -371,24 +445,52 @@ ctf_update(ctf_file_t *fp) break; case CTF_K_ARRAY: - cta.cta_contents = (ushort_t) - dtd->dtd_u.dtu_arr.ctr_contents; - cta.cta_index = (ushort_t) - dtd->dtd_u.dtu_arr.ctr_index; - cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; - bcopy(&cta, t, sizeof (cta)); - t += sizeof (cta); + if (fp->ctf_version == CTF_VERSION_2) { + struct ctf_array_v2 cta; + + cta.cta_contents = + (uint16_t)dtd->dtd_u.dtu_arr.ctr_contents; + cta.cta_index = + (uint16_t)dtd->dtd_u.dtu_arr.ctr_index; + cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; + + bcopy(&cta, t, sizeof (cta)); + t += sizeof (cta); + } else { + struct ctf_array_v3 cta; + + cta.cta_contents = + dtd->dtd_u.dtu_arr.ctr_contents; + cta.cta_index = dtd->dtd_u.dtu_arr.ctr_index; + cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; + + bcopy(&cta, t, sizeof (cta)); + t += sizeof (cta); + } break; case CTF_K_FUNCTION: { - ushort_t *argv = (ushort_t *)(uintptr_t)t; + char *argv = (char *)(uintptr_t)t; uint_t argc; - for (argc = 0; argc < vlen; argc++) - *argv++ = (ushort_t)dtd->dtd_u.dtu_argv[argc]; + if (fp->ctf_version == CTF_VERSION_2) { + ushort_t arg; - if (vlen & 1) - *argv++ = 0; /* pad to 4-byte boundary */ + for (argc = 0; argc < vlen; + argc++, argv += sizeof(arg)) { + arg = + (ushort_t)dtd->dtd_u.dtu_argv[argc]; + memcpy(argv, &arg, sizeof(arg)); + } + } else { + uint_t arg; + + for (argc = 0; argc < vlen; + argc++, argv += sizeof(arg)) { + arg = (uint_t)dtd->dtd_u.dtu_argv[argc]; + memcpy(argv, &arg, sizeof(arg)); + } + } t = (uchar_t *)argv; break; @@ -396,10 +498,12 @@ ctf_update(ctf_file_t *fp) case CTF_K_STRUCT: case CTF_K_UNION: - if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH) - t = ctf_copy_smembers(dtd, (uint_t)(s - s0), t); + if (dtd->dtd_data.ctt_size < LCTF_LSTRUCT_THRESH(fp)) + t = ctf_copy_smembers(fp, dtd, (uint_t)(s - s0), + t); else - t = ctf_copy_lmembers(dtd, (uint_t)(s - s0), t); + t = ctf_copy_lmembers(fp, dtd, (uint_t)(s - s0), + t); s = ctf_copy_membnames(dtd, s); break; @@ -495,7 +599,7 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd) if (p != NULL) *q = p->dtd_hash; - kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); + kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); switch (kind) { case CTF_K_STRUCT: case CTF_K_UNION: @@ -515,11 +619,11 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd) break; case CTF_K_FUNCTION: ctf_ref_dec(fp, dtd->dtd_data.ctt_type); - for (i = 0; i < CTF_INFO_VLEN(dtd->dtd_data.ctt_info); i++) + for (i = 0; i < LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); i++) if (dtd->dtd_u.dtu_argv[i] != 0) ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]); ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) * - CTF_INFO_VLEN(dtd->dtd_data.ctt_info)); + LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info)); break; case CTF_K_ARRAY: ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents); @@ -584,7 +688,7 @@ ctf_discard(ctf_file_t *fp) for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { ntd = ctf_list_prev(dtd); - if (CTF_TYPE_TO_INDEX(dtd->dtd_type) <= fp->ctf_dtoldid) + if (LCTF_TYPE_TO_INDEX(fp, dtd->dtd_type) <= fp->ctf_dtoldid) continue; /* skip types that have been committed */ ctf_dtd_delete(fp, dtd); @@ -609,7 +713,7 @@ ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp) if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); - if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE) + if (LCTF_INDEX_TO_TYPE(fp, fp->ctf_dtnextid, 1) > LCTF_MAX_TYPE(fp)) return (ctf_set_errno(fp, ECTF_FULL)); if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL) @@ -621,7 +725,7 @@ ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp) } type = fp->ctf_dtnextid++; - type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD)); + type = LCTF_INDEX_TO_TYPE(fp, type, (fp->ctf_flags & LCTF_CHILD)); bzero(dtd, sizeof (ctf_dtdef_t)); dtd->dtd_name = s; @@ -669,7 +773,7 @@ ctf_add_encoded(ctf_file_t *fp, uint_t flag, if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0); dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY); dtd->dtd_u.dtu_enc = *ep; @@ -682,7 +786,7 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind) ctf_dtdef_t *dtd; ctf_id_t type; - if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) + if (ref == CTF_ERR || ref > LCTF_MAX_TYPE(fp)) return (ctf_set_errno(fp, EINVAL)); if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) @@ -690,8 +794,8 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind) ctf_ref_inc(fp, ref); - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); - dtd->dtd_data.ctt_type = (ushort_t)ref; + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0); + dtd->dtd_data.ctt_type = (uint_t)ref; return (type); } @@ -739,7 +843,7 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp) if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ARRAY, flag, 0); dtd->dtd_data.ctt_size = 0; dtd->dtd_u.dtu_arr = *arp; ctf_ref_inc(fp, arp->ctr_contents); @@ -757,7 +861,8 @@ ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp) if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); - if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY) + if (dtd == NULL || + LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY) return (ctf_set_errno(fp, ECTF_BADID)); fpd = fp; @@ -799,7 +904,7 @@ ctf_add_function(ctf_file_t *fp, uint_t flag, if (ctc->ctc_flags & CTF_FUNC_VARARG) vlen++; /* add trailing zero to indicate varargs (see below) */ - if (vlen > CTF_MAX_VLEN) + if (vlen > LCTF_MAX_VLEN(fp)) return (ctf_set_errno(fp, EOVERFLOW)); fpd = fp; @@ -822,8 +927,8 @@ ctf_add_function(ctf_file_t *fp, uint_t flag, return (CTF_ERR); /* errno is set for us */ } - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen); - dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return; + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FUNCTION, flag, vlen); + dtd->dtd_data.ctt_type = ctc->ctc_return; ctf_ref_inc(fp, ctc->ctc_return); for (i = 0; i < ctc->ctc_argc; i++) @@ -853,7 +958,7 @@ ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name) else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_STRUCT, flag, 0); dtd->dtd_data.ctt_size = 0; return (type); @@ -875,7 +980,7 @@ ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name) else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_UNION, flag, 0); dtd->dtd_data.ctt_size = 0; return (type); @@ -897,7 +1002,7 @@ ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name) else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ENUM, flag, 0); dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int; return (type); @@ -936,7 +1041,7 @@ ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind) if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FORWARD, flag, 0); dtd->dtd_data.ctt_type = kind; return (type); @@ -957,8 +1062,8 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref) if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0); - dtd->dtd_data.ctt_type = (ushort_t)ref; + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_TYPEDEF, flag, 0); + dtd->dtd_data.ctt_type = ref; ctf_ref_inc(fp, ref); return (type); @@ -1000,14 +1105,14 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value) if (dtd == NULL) return (ctf_set_errno(fp, ECTF_BADID)); - kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); - root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); - vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); + kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); + root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info); + vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); if (kind != CTF_K_ENUM) return (ctf_set_errno(fp, ECTF_NOTENUM)); - if (vlen == CTF_MAX_VLEN) + if (vlen > LCTF_MAX_VLEN(fp)) return (ctf_set_errno(fp, ECTF_DTFULL)); for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); @@ -1029,7 +1134,7 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value) dmd->dmd_offset = 0; dmd->dmd_value = value; - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1); ctf_list_append(&dtd->dtd_u.dtu_members, dmd); fp->ctf_dtstrlen += strlen(s) + 1; @@ -1054,14 +1159,14 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type) if (dtd == NULL) return (ctf_set_errno(fp, ECTF_BADID)); - kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); - root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); - vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); + kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); + root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info); + vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno(fp, ECTF_NOTSOU)); - if (vlen == CTF_MAX_VLEN) + if (vlen > LCTF_MAX_VLEN(fp)) return (ctf_set_errno(fp, ECTF_DTFULL)); if (name != NULL) { @@ -1121,14 +1226,14 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type) ssize = MAX(ssize, msize); } - if (ssize > CTF_MAX_SIZE) { - dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; + if (ssize > LCTF_MAX_SIZE(fp)) { + dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(fp); dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize); dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize); } else - dtd->dtd_data.ctt_size = (ushort_t)ssize; + dtd->dtd_data.ctt_size = ssize; - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1); ctf_list_append(&dtd->dtd_u.dtu_members, dmd); if (s != NULL) @@ -1233,10 +1338,10 @@ static long soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp, ctf_id_t dst_type) { - const ctf_type_t *src_tp, *dst_tp; + const void *src_tp, *dst_tp; const char *src_name, *dst_name; ssize_t src_sz, dst_sz, src_inc, dst_inc; - uint_t kind, n; + uint_t dst_kind, dst_vlen, src_kind, src_vlen, n; if ((src_type = ctf_type_resolve(src_fp, src_type)) == CTF_ERR) return (CTF_ERR); @@ -1248,47 +1353,37 @@ soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp, if ((dst_tp = ctf_lookup_by_id(&dst_fp, dst_type)) == NULL) return (CTF_ERR); - if ((kind = LCTF_INFO_KIND(src_fp, src_tp->ctt_info)) != - LCTF_INFO_KIND(dst_fp, dst_tp->ctt_info)) + ctf_get_ctt_info(src_fp, src_tp, &src_kind, &src_vlen, NULL); + ctf_get_ctt_info(dst_fp, dst_tp, &dst_kind, &dst_vlen, NULL); + + if (src_kind != dst_kind) return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) + if (src_kind != CTF_K_STRUCT && src_kind != CTF_K_UNION) return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - if ((n = LCTF_INFO_VLEN(src_fp, src_tp->ctt_info)) != - LCTF_INFO_VLEN(dst_fp, dst_tp->ctt_info)) + if (src_vlen != dst_vlen) return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); (void) ctf_get_ctt_size(src_fp, src_tp, &src_sz, &src_inc); (void) ctf_get_ctt_size(dst_fp, dst_tp, &dst_sz, &dst_inc); - if (src_sz != dst_sz || src_inc != dst_inc) + if (src_sz != dst_sz) return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - if (src_sz < CTF_LSTRUCT_THRESH) { - const ctf_member_t *src_mp, *dst_mp; + const char *src_mp, *dst_mp; + ulong_t src_offset, dst_offset; - src_mp = (const ctf_member_t *)((uintptr_t)src_tp + src_inc); - dst_mp = (const ctf_member_t *)((uintptr_t)dst_tp + dst_inc); - for (; n != 0; n--, src_mp++, dst_mp++) { - if (src_mp->ctm_offset != dst_mp->ctm_offset) - return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - src_name = ctf_strptr(src_fp, src_mp->ctm_name); - dst_name = ctf_strptr(dst_fp, dst_mp->ctm_name); - if (strcmp(src_name, dst_name) != 0) - return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - } - } else { - const ctf_lmember_t *src_mp, *dst_mp; + src_mp = (const char *)src_tp + src_inc; + dst_mp = (const char *)dst_tp + dst_inc; + for (n = src_vlen; n != 0; + n--, src_mp += src_inc, dst_mp += dst_inc) { + ctf_get_ctm_info(src_fp, src_mp, src_sz, &src_inc, NULL, + &src_offset, &src_name); + ctf_get_ctm_info(dst_fp, dst_mp, dst_sz, &dst_inc, NULL, + &dst_offset, &dst_name); - src_mp = (const ctf_lmember_t *)((uintptr_t)src_tp + src_inc); - dst_mp = (const ctf_lmember_t *)((uintptr_t)dst_tp + dst_inc); - for (; n != 0; n--, src_mp++, dst_mp++) { - if (src_mp->ctlm_offsethi != dst_mp->ctlm_offsethi || - src_mp->ctlm_offsetlo != dst_mp->ctlm_offsetlo) - return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - src_name = ctf_strptr(src_fp, src_mp->ctlm_name); - dst_name = ctf_strptr(dst_fp, dst_mp->ctlm_name); - if (strcmp(src_name, dst_name) != 0) - return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); - } + if (src_offset != dst_offset) + return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); + if (strcmp(src_name, dst_name) != 0) + return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); } return (0); @@ -1307,9 +1402,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) ctf_id_t dst_type = CTF_ERR; uint_t dst_kind = CTF_K_UNKNOWN; - const ctf_type_t *tp; + const void *tp; const char *name; - uint_t kind, flag, vlen; + uint_t type, kind, flag, vlen; ctf_bundle_t src, dst; ctf_encoding_t src_en, main_en, dst_en; @@ -1331,10 +1426,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL) return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); - name = ctf_strptr(src_fp, tp->ctt_name); - kind = LCTF_INFO_KIND(src_fp, tp->ctt_info); - flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info); - vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info); + name = ctf_type_rname(src_fp, tp); + + ctf_get_ctt_info(src_fp, tp, &kind, &vlen, &flag); switch (kind) { case CTF_K_STRUCT: @@ -1389,10 +1483,10 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) */ 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 || + LCTF_TYPE_TO_INDEX(dst_fp, dtd->dtd_type) > + dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) { + if (LCTF_INFO_KIND(dst_fp, 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) { @@ -1499,7 +1593,8 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) break; case CTF_K_FUNCTION: - ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type); + ctf_get_ctt_index(src_fp, tp, NULL, &type, NULL); + ctc.ctc_return = ctf_add_type(dst_fp, src_fp, type); ctc.ctc_argc = 0; ctc.ctc_flags = 0; @@ -1541,14 +1636,16 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0) errs++; /* increment errs and fail at bottom of case */ - if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) { - dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; + if ((size = ctf_type_size(src_fp, src_type)) > + LCTF_MAX_SIZE(src_fp)) { + dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(dst_fp); dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); } else - dtd->dtd_data.ctt_size = (ushort_t)size; + dtd->dtd_data.ctt_size = size; - dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen); + dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(dst_fp, kind, flag, + vlen); /* * Make a final pass through the members changing each dmd_type diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_decl.c b/cddl/contrib/opensolaris/common/ctf/ctf_decl.c index 6bf57001570..63d173c15f5 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_decl.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_decl.c @@ -88,10 +88,10 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type) { ctf_decl_node_t *cdp; ctf_decl_prec_t prec; - uint_t kind, n = 1; + uint_t ctype, kind, n = 1; int is_qual = 0; - const ctf_type_t *tp; + const void *tp; ctf_arinfo_t ar; if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) { @@ -99,7 +99,10 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type) return; } - switch (kind = LCTF_INFO_KIND(fp, tp->ctt_info)) { + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL); + + switch (kind) { case CTF_K_ARRAY: (void) ctf_array_info(fp, type, &ar); ctf_decl_push(cd, fp, ar.ctr_contents); @@ -108,27 +111,27 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type) break; case CTF_K_TYPEDEF: - if (ctf_strptr(fp, tp->ctt_name)[0] == '\0') { - ctf_decl_push(cd, fp, tp->ctt_type); + if (ctf_type_rname(fp, tp)[0] == '\0') { + ctf_decl_push(cd, fp, ctype); return; } prec = CTF_PREC_BASE; break; case CTF_K_FUNCTION: - ctf_decl_push(cd, fp, tp->ctt_type); + ctf_decl_push(cd, fp, ctype); prec = CTF_PREC_FUNCTION; break; case CTF_K_POINTER: - ctf_decl_push(cd, fp, tp->ctt_type); + ctf_decl_push(cd, fp, ctype); prec = CTF_PREC_POINTER; break; case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - ctf_decl_push(cd, fp, tp->ctt_type); + ctf_decl_push(cd, fp, ctype); prec = cd->cd_qualp; is_qual++; break; diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_hash.c b/cddl/contrib/opensolaris/common/ctf/ctf_hash.c index b10a7618f66..5a36fbbd88c 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_hash.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_hash.c @@ -29,7 +29,7 @@ #include -static const ushort_t _CTF_EMPTY[1] = { 0 }; +static const uint_t _CTF_EMPTY[1] = { 0 }; int ctf_hash_create(ctf_hash_t *hp, ulong_t nelems) @@ -43,7 +43,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems) */ if (nelems == 0) { bzero(hp, sizeof (ctf_hash_t)); - hp->h_buckets = (ushort_t *)_CTF_EMPTY; + hp->h_buckets = (uint_t *)_CTF_EMPTY; hp->h_nbuckets = 1; return (0); } @@ -52,7 +52,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems) hp->h_nelems = nelems + 1; /* we use index zero as a sentinel */ hp->h_free = 1; /* first free element is index 1 */ - hp->h_buckets = ctf_alloc(sizeof (ushort_t) * hp->h_nbuckets); + hp->h_buckets = ctf_alloc(sizeof (uint_t) * hp->h_nbuckets); hp->h_chains = ctf_alloc(sizeof (ctf_helem_t) * hp->h_nelems); if (hp->h_buckets == NULL || hp->h_chains == NULL) { @@ -60,7 +60,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems) return (EAGAIN); } - bzero(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets); + bzero(hp->h_buckets, sizeof (uint_t) * hp->h_nbuckets); bzero(hp->h_chains, sizeof (ctf_helem_t) * hp->h_nelems); return (0); @@ -92,7 +92,7 @@ ctf_hash_compute(const char *key, size_t len) } int -ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name) +ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, uint_t type, uint_t name) { ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)]; const char *str = ctsp->cts_strs + CTF_NAME_OFFSET(name); @@ -129,7 +129,7 @@ ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name) * If the key is not present, then call ctf_hash_insert() and hash it in. */ int -ctf_hash_define(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name) +ctf_hash_define(ctf_hash_t *hp, ctf_file_t *fp, uint_t type, uint_t name) { const char *str = ctf_strptr(fp, name); ctf_helem_t *hep = ctf_hash_lookup(hp, fp, str, strlen(str)); @@ -147,7 +147,7 @@ ctf_hash_lookup(ctf_hash_t *hp, ctf_file_t *fp, const char *key, size_t len) ctf_helem_t *hep; ctf_strs_t *ctsp; const char *str; - ushort_t i; + uint_t i; ulong_t h = ctf_hash_compute(key, len) % hp->h_nbuckets; @@ -167,7 +167,7 @@ void ctf_hash_destroy(ctf_hash_t *hp) { if (hp->h_buckets != NULL && hp->h_nbuckets != 1) { - ctf_free(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets); + ctf_free(hp->h_buckets, sizeof (uint_t) * hp->h_nbuckets); hp->h_buckets = NULL; } diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_impl.h b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h index dd616785607..774eff1380f 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_impl.h +++ b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h @@ -65,15 +65,15 @@ extern "C" { typedef struct ctf_helem { uint_t h_name; /* reference to name in string table */ - ushort_t h_type; /* corresponding type ID number */ - ushort_t h_next; /* index of next element in hash chain */ + uint_t h_type; /* corresponding type ID number */ + uint_t h_next; /* index of next element in hash chain */ } ctf_helem_t; typedef struct ctf_hash { - ushort_t *h_buckets; /* hash bucket array (chain indices) */ + uint_t *h_buckets; /* hash bucket array (chain indices) */ ctf_helem_t *h_chains; /* hash chains buffer */ - ushort_t h_nbuckets; /* number of elements in bucket array */ - ushort_t h_nelems; /* number of elements in hash table */ + uint_t h_nbuckets; /* number of elements in bucket array */ + uint_t h_nelems; /* number of elements in hash table */ uint_t h_free; /* index of next free hash element */ } ctf_hash_t; @@ -99,9 +99,20 @@ typedef struct ctf_lookup { } ctf_lookup_t; typedef struct ctf_fileops { - ushort_t (*ctfo_get_kind)(ushort_t); - ushort_t (*ctfo_get_root)(ushort_t); - ushort_t (*ctfo_get_vlen)(ushort_t); + uint_t (*ctfo_get_kind)(uint_t); + uint_t (*ctfo_get_root)(uint_t); + uint_t (*ctfo_get_vlen)(uint_t); + uint_t (*ctfo_get_max_vlen)(void); + uint_t (*ctfo_get_max_size)(void); + uint_t (*ctfo_get_max_type)(void); + uint_t (*ctfo_get_lsize_sent)(void); + uint_t (*ctfo_get_lstruct_thresh)(void); + + uint_t (*ctfo_type_info)(uint_t, uint_t, uint_t); + int (*ctfo_type_isparent)(uint_t); + int (*ctfo_type_ischild)(uint_t); + uint_t (*ctfo_type_to_index)(uint_t); + uint_t (*ctfo_index_to_type)(uint_t, uint_t); } ctf_fileops_t; typedef struct ctf_list { @@ -149,7 +160,7 @@ typedef struct ctf_dtdef { struct ctf_dtdef *dtd_hash; /* hash chain pointer for ctf_dthash */ char *dtd_name; /* name associated with definition (if any) */ ctf_id_t dtd_type; /* type identifier for this definition */ - ctf_type_t dtd_data; /* type node (see ) */ + struct ctf_type_v3 dtd_data; /* type node (see ) */ int dtd_ref; /* recfount for dyanmic types */ union { ctf_list_t dtu_members; /* struct, union, or enum */ @@ -194,7 +205,7 @@ struct ctf_file { uint_t *ctf_sxlate; /* translation table for symtab entries */ ulong_t ctf_nsyms; /* number of entries in symtab xlate table */ uint_t *ctf_txlate; /* translation table for type IDs */ - ushort_t *ctf_ptrtab; /* translation table for pointer-to lookups */ + uint_t *ctf_ptrtab; /* translation table for pointer-to lookups */ ulong_t ctf_typemax; /* maximum valid type ID number */ const ctf_dmodel_t *ctf_dmodel; /* data model pointer (see above) */ struct ctf_file *ctf_parent; /* parent CTF container (if any) */ @@ -204,6 +215,7 @@ struct ctf_file { uint_t ctf_flags; /* libctf flags (see below) */ int ctf_errno; /* error code for most recent error */ int ctf_version; /* CTF data version */ + size_t ctf_idwidth; /* Size, in bytes, of a type ID */ ctf_dtdef_t **ctf_dthash; /* hash of dynamic type definitions */ ulong_t ctf_dthashlen; /* size of dynamic type hash bucket array */ ctf_list_t ctf_dtdefs; /* list of dynamic type definitions */ @@ -214,11 +226,24 @@ struct ctf_file { }; #define LCTF_INDEX_TO_TYPEPTR(fp, i) \ - ((ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)])) + ((void *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)])) #define LCTF_INFO_KIND(fp, info) ((fp)->ctf_fileops->ctfo_get_kind(info)) #define LCTF_INFO_ROOT(fp, info) ((fp)->ctf_fileops->ctfo_get_root(info)) #define LCTF_INFO_VLEN(fp, info) ((fp)->ctf_fileops->ctfo_get_vlen(info)) +#define LCTF_MAX_VLEN(fp) ((fp)->ctf_fileops->ctfo_get_max_vlen()) +#define LCTF_MAX_SIZE(fp) ((fp)->ctf_fileops->ctfo_get_max_size()) +#define LCTF_MAX_TYPE(fp) ((fp)->ctf_fileops->ctfo_get_max_type()) +#define LCTF_LSIZE_SENT(fp) \ + ((fp)->ctf_fileops->ctfo_get_lsize_sent()) +#define LCTF_LSTRUCT_THRESH(fp) \ + ((fp)->ctf_fileops->ctfo_get_lstruct_thresh()) + +#define LCTF_TYPE_INFO(fp, k, r, l) ((fp)->ctf_fileops->ctfo_type_info(k, r, l)) +#define LCTF_TYPE_ISPARENT(fp, id) ((fp)->ctf_fileops->ctfo_type_isparent(id)) +#define LCTF_TYPE_ISCHILD(fp, id) ((fp)->ctf_fileops->ctfo_type_ischild(id)) +#define LCTF_TYPE_TO_INDEX(fp, t) ((fp)->ctf_fileops->ctfo_type_to_index(t)) +#define LCTF_INDEX_TO_TYPE(fp, id, c) ((fp)->ctf_fileops->ctfo_index_to_type(id, c)) #define LCTF_MMAP 0x0001 /* libctf should munmap buffers on close */ #define LCTF_CHILD 0x0002 /* CTF container is a child */ @@ -276,14 +301,22 @@ enum { ECTF_NOTDYN /* type is not a dynamic type */ }; -extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *, - ssize_t *, ssize_t *); +extern void ctf_get_ctt_index(const ctf_file_t *fp, const void *v, + uint_t *indexp, uint_t *typep, int *ischildp); +extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const void *v, ssize_t *, + ssize_t *); +extern void ctf_get_ctt_info(const ctf_file_t *, const void *v, uint_t *kind, + uint_t *vlen, int *isroot); -extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t); +extern void ctf_get_ctm_info(const ctf_file_t *fp, const void *v, size_t sz, + size_t *incrementp, uint_t *typep, ulong_t *offsetp, const char **namep); + +extern const void *ctf_lookup_by_id(ctf_file_t **, ctf_id_t); +extern const char *ctf_type_rname(ctf_file_t *, const void *); extern int ctf_hash_create(ctf_hash_t *, ulong_t); -extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t); -extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t); +extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, uint_t, uint_t); +extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, uint_t, uint_t); extern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *, const char *, size_t); extern uint_t ctf_hash_size(const ctf_hash_t *); diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c b/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c index cd9c7143693..e822e22f634 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c @@ -111,17 +111,17 @@ ctf_lookup_by_name(ctf_file_t *fp, const char *name) * data includes "struct foo *" but not "foo_t *" and * the user tries to access "foo_t *" in the debugger. */ - ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]; + ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)]; if (ntype == 0) { ntype = ctf_type_resolve(fp, type); if (ntype == CTF_ERR || (ntype = fp->ctf_ptrtab[ - CTF_TYPE_TO_INDEX(ntype)]) == 0) { + LCTF_TYPE_TO_INDEX(fp, ntype)]) == 0) { (void) ctf_set_errno(fp, ECTF_NOTYPE); goto err; } } - type = CTF_INDEX_TO_TYPE(ntype, + type = LCTF_INDEX_TO_TYPE(fp, ntype, (fp->ctf_flags & LCTF_CHILD)); q = p + 1; @@ -203,7 +203,7 @@ ctf_lookup_by_symbol(ctf_file_t *fp, ulong_t symidx) if (fp->ctf_sxlate[symidx] == -1u) return (ctf_set_errno(fp, ECTF_NOTYPEDAT)); - type = *(ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]); + type = *(uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]); if (type == 0) return (ctf_set_errno(fp, ECTF_NOTYPEDAT)); @@ -215,18 +215,24 @@ ctf_lookup_by_symbol(ctf_file_t *fp, ulong_t symidx) * given type ID. If the ID is invalid, the function returns NULL. * This function is not exported outside of the library. */ -const ctf_type_t * +const void * ctf_lookup_by_id(ctf_file_t **fpp, ctf_id_t type) { ctf_file_t *fp = *fpp; /* caller passes in starting CTF container */ - if ((fp->ctf_flags & LCTF_CHILD) && CTF_TYPE_ISPARENT(type) && - (fp = fp->ctf_parent) == NULL) { - (void) ctf_set_errno(*fpp, ECTF_NOPARENT); - return (NULL); + if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT(fp, type)) { + if (fp->ctf_parent == NULL) { + (void) ctf_set_errno(*fpp, ECTF_NOPARENT); + return (NULL); + } + + /* The parent may be using a different CTF version. */ + type = LCTF_TYPE_TO_INDEX(fp, type); + fp = fp->ctf_parent; + } else { + type = LCTF_TYPE_TO_INDEX(fp, type); } - type = CTF_TYPE_TO_INDEX(type); if (type > 0 && type <= fp->ctf_typemax) { *fpp = fp; /* function returns ending CTF container */ return (LCTF_INDEX_TO_TYPEPTR(fp, type)); @@ -244,8 +250,8 @@ int ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip) { const ctf_sect_t *sp = &fp->ctf_symtab; - const ushort_t *dp; - ushort_t info, kind, n; + const uint_t *dp; + uint_t info, kind, n; if (sp->cts_data == NULL) return (ctf_set_errno(fp, ECTF_NOSYMTAB)); @@ -266,7 +272,7 @@ ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip) if (fp->ctf_sxlate[symidx] == -1u) return (ctf_set_errno(fp, ECTF_NOFUNCDAT)); - dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]); + dp = (uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]); info = *dp++; kind = LCTF_INFO_KIND(fp, info); @@ -297,17 +303,17 @@ ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip) int ctf_func_args(ctf_file_t *fp, ulong_t symidx, uint_t argc, ctf_id_t *argv) { - const ushort_t *dp; + const uint_t *dp; ctf_funcinfo_t f; if (ctf_func_info(fp, symidx, &f) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ /* - * The argument data is two ushort_t's past the translation table + * The argument data is two uint_t's past the translation table * offset: one for the function info, and one for the return type. */ - dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]) + 2; + dp = (uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]) + 2; for (argc = MIN(argc, f.ctc_argc); argc != 0; argc--) *argv++ = *dp++; diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_open.c b/cddl/contrib/opensolaris/common/ctf/ctf_open.c index 5ab06890d7f..cdc3e2f028f 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_open.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_open.c @@ -44,28 +44,184 @@ const char _CTF_NULLSTR[] = ""; int _libctf_version = CTF_VERSION; /* library client version */ int _libctf_debug = 0; /* debugging messages enabled */ -static ushort_t -get_kind_v2(ushort_t info) +static uint_t +get_kind_v2(uint_t info) { - return (CTF_INFO_KIND(info)); + return (CTF_V2_INFO_KIND((ushort_t)info)); } -static ushort_t -get_root_v2(ushort_t info) +static uint_t +get_root_v2(uint_t info) { - return (CTF_INFO_ISROOT(info)); + return (CTF_V2_INFO_ISROOT((ushort_t)info)); } -static ushort_t -get_vlen_v2(ushort_t info) +static uint_t +get_vlen_v2(uint_t info) { - return (CTF_INFO_VLEN(info)); + return (CTF_V2_INFO_VLEN((ushort_t)info)); } +static uint_t +get_max_vlen_v2(void) +{ + return (CTF_V2_MAX_VLEN); +} + +static uint_t +get_max_size_v2(void) +{ + return (CTF_V2_MAX_SIZE); +} + +static uint_t +get_max_type_v2(void) +{ + return (CTF_V2_MAX_TYPE); +} + +static uint_t +get_lsize_sent_v2(void) +{ + return (CTF_V2_LSIZE_SENT); +} + +static uint_t +get_lstruct_thresh_v2(void) +{ + return (CTF_V2_LSTRUCT_THRESH); +} + +static uint_t +type_info_v2(uint_t kind, uint_t isroot, uint_t len) +{ + return (CTF_V2_TYPE_INFO(kind, isroot, len)); +} + +static int +type_isparent_v2(uint_t id) +{ + return (CTF_V2_TYPE_ISPARENT(id)); +} + +static int +type_ischild_v2(uint_t id) +{ + return (CTF_V2_TYPE_ISCHILD(id)); +} + +static uint_t +type_to_index_v2(uint_t t) +{ + return (CTF_V2_TYPE_TO_INDEX(t)); +} + +static uint_t +index_to_type_v2(uint_t id, uint_t child) +{ + return (CTF_V2_INDEX_TO_TYPE(id, child)); +} + +static uint_t +get_kind_v3(uint_t info) +{ + return (CTF_V3_INFO_KIND(info)); +} + +static uint_t +get_root_v3(uint_t info) +{ + return (CTF_V3_INFO_ISROOT(info)); +} + +static uint_t +get_vlen_v3(uint_t info) +{ + return (CTF_V3_INFO_VLEN(info)); +} + +static uint_t +get_max_vlen_v3(void) +{ + return (CTF_V3_MAX_VLEN); +} + +static uint_t +get_max_size_v3(void) +{ + return (CTF_V3_MAX_SIZE); +} + +static uint_t +get_max_type_v3(void) +{ + return (CTF_V3_MAX_TYPE); +} + +static uint_t +get_lsize_sent_v3(void) +{ + return (CTF_V3_LSIZE_SENT); +} + +static uint_t +get_lstruct_thresh_v3(void) +{ + return (CTF_V3_LSTRUCT_THRESH); +} + +static uint_t +type_info_v3(uint_t kind, uint_t isroot, uint_t len) +{ + return (CTF_V3_TYPE_INFO(kind, isroot, len)); +} + +static int +type_isparent_v3(uint_t id) +{ + return (CTF_V3_TYPE_ISPARENT(id)); +} + +static int +type_ischild_v3(uint_t id) +{ + return (CTF_V3_TYPE_ISCHILD(id)); +} + +static uint_t +type_to_index_v3(uint_t t) +{ + return (CTF_V3_TYPE_TO_INDEX(t)); +} + +static uint_t +index_to_type_v3(uint_t id, uint_t child) +{ + return (CTF_V3_INDEX_TO_TYPE(id, child)); +} + +#define CTF_FILEOPS_ENTRY(v) \ + { \ + .ctfo_get_kind = get_kind_v ## v, \ + .ctfo_get_root = get_root_v ## v, \ + .ctfo_get_vlen = get_vlen_v ## v, \ + .ctfo_get_max_vlen = get_max_vlen_v ## v, \ + .ctfo_get_max_size = get_max_size_v ## v, \ + .ctfo_get_max_type = get_max_type_v ## v, \ + .ctfo_get_lsize_sent = get_lsize_sent_v ## v, \ + .ctfo_get_lstruct_thresh = get_lstruct_thresh_v ## v, \ + .ctfo_type_info = type_info_v ## v, \ + .ctfo_type_isparent = type_isparent_v ## v, \ + .ctfo_type_ischild = type_ischild_v ## v, \ + .ctfo_type_to_index = type_to_index_v ## v, \ + .ctfo_index_to_type = index_to_type_v ## v \ + } + static const ctf_fileops_t ctf_fileops[] = { { NULL, NULL }, { NULL, NULL }, - { get_kind_v2, get_root_v2, get_vlen_v2 }, + CTF_FILEOPS_ENTRY(2), + CTF_FILEOPS_ENTRY(3), }; /* @@ -100,7 +256,8 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp, uint_t objtoff = hp->cth_objtoff; uint_t funcoff = hp->cth_funcoff; - ushort_t info, vlen; + uint_t info, vlen; + Elf64_Sym sym, *gsp; const char *name; @@ -138,7 +295,7 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp, } *xp = objtoff; - objtoff += sizeof (ushort_t); + objtoff += fp->ctf_idwidth; break; case STT_FUNC: @@ -149,7 +306,7 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp, *xp = funcoff; - info = *(ushort_t *)((uintptr_t)fp->ctf_buf + funcoff); + info = *(uint_t *)((uintptr_t)fp->ctf_buf + funcoff); vlen = LCTF_INFO_VLEN(fp, info); /* @@ -159,9 +316,10 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp, */ if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN && vlen == 0) - funcoff += sizeof (ushort_t); /* skip pad */ + funcoff += fp->ctf_idwidth; else - funcoff += sizeof (ushort_t) * (vlen + 2); + funcoff += + roundup2(fp->ctf_idwidth * (vlen + 2), 4); break; default: @@ -181,15 +339,13 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp, static int init_types(ctf_file_t *fp, const ctf_header_t *cth) { - /* LINTED - pointer alignment */ - const ctf_type_t *tbuf = (ctf_type_t *)(fp->ctf_buf + cth->cth_typeoff); - /* LINTED - pointer alignment */ - const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff); + const void *tbuf = (const void *)(fp->ctf_buf + cth->cth_typeoff); + const void *tend = (const void *)(fp->ctf_buf + cth->cth_stroff); ulong_t pop[CTF_K_MAX + 1] = { 0 }; - const ctf_type_t *tp; + const void *tp; ctf_hash_t *hp; - ushort_t id, dst; + uint_t id, dst; uint_t *xp; /* @@ -207,14 +363,14 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) * pass, we count the number of each type and the total number of types. */ for (tp = tbuf; tp < tend; fp->ctf_typemax++) { - ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info); - ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info); ssize_t size, increment; size_t vbytes; - uint_t n; + uint_t kind, n, type, vlen; (void) ctf_get_ctt_size(fp, tp, &size, &increment); + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + ctf_get_ctt_index(fp, tp, NULL, &type, NULL); switch (kind) { case CTF_K_INTEGER: @@ -222,30 +378,30 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) vbytes = sizeof (uint_t); break; case CTF_K_ARRAY: - vbytes = sizeof (ctf_array_t); + if (fp->ctf_version == CTF_VERSION_2) + vbytes = sizeof (struct ctf_array_v2); + else + vbytes = sizeof (struct ctf_array_v3); break; case CTF_K_FUNCTION: - vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); + vbytes = roundup2(fp->ctf_idwidth * vlen, 4); break; case CTF_K_STRUCT: - case CTF_K_UNION: - if (size < CTF_LSTRUCT_THRESH) { - ctf_member_t *mp = (ctf_member_t *) - ((uintptr_t)tp + increment); - - vbytes = sizeof (ctf_member_t) * vlen; - for (n = vlen; n != 0; n--, mp++) - child |= CTF_TYPE_ISCHILD(mp->ctm_type); - } else { - ctf_lmember_t *lmp = (ctf_lmember_t *) - ((uintptr_t)tp + increment); + case CTF_K_UNION: { + size_t increment1; + uint_t type; + const void *mp = + (const void *)((uintptr_t)tp + increment); - vbytes = sizeof (ctf_lmember_t) * vlen; - for (n = vlen; n != 0; n--, lmp++) - child |= - CTF_TYPE_ISCHILD(lmp->ctlm_type); + vbytes = 0; + for (n = vlen; n != 0; n--, mp += increment1) { + ctf_get_ctm_info(fp, mp, size, &increment1, &type, + NULL, NULL); + child |= LCTF_TYPE_ISCHILD(fp, type); + vbytes += increment1; } break; + } case CTF_K_ENUM: vbytes = sizeof (ctf_enum_t) * vlen; break; @@ -255,11 +411,10 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) * kind for the tag, so bump that population count too. * If ctt_type is unknown, treat the tag as a struct. */ - if (tp->ctt_type == CTF_K_UNKNOWN || - tp->ctt_type >= CTF_K_MAX) + if (type == CTF_K_UNKNOWN || type >= CTF_K_MAX) pop[CTF_K_STRUCT]++; else - pop[tp->ctt_type]++; + pop[type]++; /*FALLTHRU*/ case CTF_K_UNKNOWN: vbytes = 0; @@ -269,14 +424,14 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - child |= CTF_TYPE_ISCHILD(tp->ctt_type); + child |= LCTF_TYPE_ISCHILD(fp, type); vbytes = 0; break; default: ctf_dprintf("detected invalid CTF kind -- %u\n", kind); return (ECTF_CORRUPT); } - tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); + tp = (const void *)((uintptr_t)tp + increment + vbytes); pop[kind]++; } @@ -310,7 +465,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) return (err); fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1)); - fp->ctf_ptrtab = ctf_alloc(sizeof (ushort_t) * (fp->ctf_typemax + 1)); + fp->ctf_ptrtab = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1)); if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL) return (EAGAIN); /* memory allocation failed */ @@ -319,15 +474,15 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) *xp++ = 0; /* type id 0 is used as a sentinel value */ bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1)); - bzero(fp->ctf_ptrtab, sizeof (ushort_t) * (fp->ctf_typemax + 1)); + bzero(fp->ctf_ptrtab, sizeof (uint_t) * (fp->ctf_typemax + 1)); /* * In the second pass through the types, we fill in each entry of the * type and pointer tables and add names to the appropriate hashes. */ for (id = 1, tp = tbuf; tp < tend; xp++, id++) { - ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info); - ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info); + const struct ctf_type_v3 *ctt = tp; + uint_t kind, type, vlen; ssize_t size, increment; const char *name; @@ -336,7 +491,9 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) ctf_encoding_t cte; (void) ctf_get_ctt_size(fp, tp, &size, &increment); - name = ctf_strptr(fp, tp->ctt_name); + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + ctf_get_ctt_index(fp, tp, NULL, &type, NULL); + name = ctf_type_rname(fp, tp); switch (kind) { case CTF_K_INTEGER: @@ -349,7 +506,8 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) if ((hep = ctf_hash_lookup(&fp->ctf_names, fp, name, strlen(name))) == NULL) { err = ctf_hash_insert(&fp->ctf_names, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), + ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); } else if (ctf_type_encoding(fp, hep->h_type, @@ -358,56 +516,89 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) * Work-around SOS8 stabs bug: replace existing * intrinsic w/ same name if it was zero bits. */ - hep->h_type = CTF_INDEX_TO_TYPE(id, child); + hep->h_type = LCTF_INDEX_TO_TYPE(fp, id, child); } vbytes = sizeof (uint_t); break; case CTF_K_ARRAY: - vbytes = sizeof (ctf_array_t); + if (fp->ctf_version == CTF_VERSION_2) + vbytes = sizeof (struct ctf_array_v2); + else + vbytes = sizeof (struct ctf_array_v3); break; case CTF_K_FUNCTION: err = ctf_hash_insert(&fp->ctf_names, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); - vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); + vbytes = roundup2(fp->ctf_idwidth * vlen, 4); break; case CTF_K_STRUCT: err = ctf_hash_define(&fp->ctf_structs, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); - if (size < CTF_LSTRUCT_THRESH) - vbytes = sizeof (ctf_member_t) * vlen; - else { - vbytes = sizeof (ctf_lmember_t) * vlen; - nlstructs++; + if (fp->ctf_version == CTF_VERSION_2) { + if (size < LCTF_LSTRUCT_THRESH(fp)) + vbytes = sizeof (struct ctf_member_v2) * + vlen; + else { + vbytes = + sizeof (struct ctf_lmember_v2) * + vlen; + nlstructs++; + } + } else { + if (size < LCTF_LSTRUCT_THRESH(fp)) + vbytes = sizeof (struct ctf_member_v3) * + vlen; + else { + vbytes = + sizeof (struct ctf_lmember_v3) * + vlen; + nlstructs++; + } } break; case CTF_K_UNION: err = ctf_hash_define(&fp->ctf_unions, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); - if (size < CTF_LSTRUCT_THRESH) - vbytes = sizeof (ctf_member_t) * vlen; - else { - vbytes = sizeof (ctf_lmember_t) * vlen; - nlunions++; + if (fp->ctf_version == CTF_VERSION_2) { + if (size < LCTF_LSTRUCT_THRESH(fp)) + vbytes = sizeof (struct ctf_member_v2) * + vlen; + else { + vbytes = + sizeof (struct ctf_lmember_v2) * + vlen; + nlunions++; + } + } else { + if (size < LCTF_LSTRUCT_THRESH(fp)) + vbytes = sizeof (struct ctf_member_v3) * + vlen; + else { + vbytes = + sizeof (struct ctf_lmember_v3) * + vlen; + nlunions++; + } } break; case CTF_K_ENUM: err = ctf_hash_define(&fp->ctf_enums, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); @@ -417,7 +608,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) case CTF_K_TYPEDEF: err = ctf_hash_insert(&fp->ctf_names, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); vbytes = 0; @@ -428,7 +619,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) * Only insert forward tags into the given hash if the * type or tag name is not already present. */ - switch (tp->ctt_type) { + switch (type) { case CTF_K_STRUCT: hp = &fp->ctf_structs; break; @@ -445,7 +636,8 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) if (ctf_hash_lookup(hp, fp, name, strlen(name)) == NULL) { err = ctf_hash_insert(hp, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), + ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); } @@ -458,17 +650,17 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) * container, then store the index of the pointer type * in fp->ctf_ptrtab[ index of referenced type ]. */ - if (CTF_TYPE_ISCHILD(tp->ctt_type) == child && - CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax) + if (LCTF_TYPE_ISCHILD(fp, type) == child && + LCTF_TYPE_TO_INDEX(fp, type) <= fp->ctf_typemax) fp->ctf_ptrtab[ - CTF_TYPE_TO_INDEX(tp->ctt_type)] = id; + LCTF_TYPE_TO_INDEX(fp, type)] = id; /*FALLTHRU*/ case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: err = ctf_hash_insert(&fp->ctf_names, fp, - CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); + LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name); if (err != 0 && err != ECTF_STRTAB) return (err); /*FALLTHRU*/ @@ -479,7 +671,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) } *xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf); - tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); + tp = (const void *)((uintptr_t)tp + increment + vbytes); } ctf_dprintf("%lu total types processed\n", fp->ctf_typemax); @@ -499,14 +691,17 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth) */ for (id = 1; id <= fp->ctf_typemax; id++) { if ((dst = fp->ctf_ptrtab[id]) != 0) { + uint_t index, kind; + int ischild; + tp = LCTF_INDEX_TO_TYPEPTR(fp, id); + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + ctf_get_ctt_index(fp, tp, &index, NULL, &ischild); - if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF && - strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 && - CTF_TYPE_ISCHILD(tp->ctt_type) == child && - CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax) - fp->ctf_ptrtab[ - CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst; + if (kind == CTF_K_TYPEDEF && + strcmp(ctf_type_rname(fp, tp), "") == 0 && + ischild == child && index <= fp->ctf_typemax) + fp->ctf_ptrtab[index] = dst; } } @@ -560,7 +755,8 @@ ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (pp->ctp_magic != CTF_MAGIC) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); - if (pp->ctp_version == CTF_VERSION_2) { + if (pp->ctp_version == CTF_VERSION_2 || + pp->ctp_version == CTF_VERSION_3) { if (ctfsect->cts_size < sizeof (ctf_header_t)) return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); @@ -642,6 +838,7 @@ ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, bzero(fp, sizeof (ctf_file_t)); fp->ctf_version = hp.cth_version; + fp->ctf_idwidth = fp->ctf_version == CTF_VERSION_2 ? 2 : 4; fp->ctf_fileops = &ctf_fileops[hp.cth_version]; bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t)); @@ -911,7 +1108,7 @@ ctf_close(ctf_file_t *fp) if (fp->ctf_ptrtab != NULL) { ctf_free(fp->ctf_ptrtab, - sizeof (ushort_t) * (fp->ctf_typemax + 1)); + sizeof (uint_t) * (fp->ctf_typemax + 1)); } ctf_hash_destroy(&fp->ctf_structs); diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_types.c b/cddl/contrib/opensolaris/common/ctf/ctf_types.c index 5b6b07655d8..de8269659c2 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_types.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_types.c @@ -27,18 +27,90 @@ #include +void +ctf_get_ctt_index(const ctf_file_t *fp, const void *v, uint_t *indexp, + uint_t *typep, int *ischildp) +{ + uint_t index, type; + int ischild; + + if (fp->ctf_version == CTF_VERSION_2) { + const struct ctf_type_v2 *ctt = v; + + type = ctt->ctt_type; + index = CTF_V2_TYPE_TO_INDEX(ctt->ctt_type); + ischild = CTF_V2_TYPE_ISCHILD(ctt->ctt_type); + } else { + const struct ctf_type_v3 *ctt = v; + + type = ctt->ctt_type; + index = CTF_V3_TYPE_TO_INDEX(ctt->ctt_type); + ischild = CTF_V3_TYPE_ISCHILD(ctt->ctt_type); + } + + if (indexp != NULL) + *indexp = index; + if (typep != NULL) + *typep = type; + if (ischildp != NULL) + *ischildp = ischild; +} + +void +ctf_get_ctt_info(const ctf_file_t *fp, const void *v, uint_t *kindp, + uint_t *vlenp, int *isrootp) +{ + uint_t kind, vlen; + int isroot; + + if (fp->ctf_version == CTF_VERSION_2) { + const struct ctf_type_v2 *ctt = v; + + kind = CTF_V2_INFO_KIND(ctt->ctt_info); + vlen = CTF_V2_INFO_VLEN(ctt->ctt_info); + isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info); + } else { + const struct ctf_type_v3 *ctt = v; + + kind = CTF_V3_INFO_KIND(ctt->ctt_info); + vlen = CTF_V3_INFO_VLEN(ctt->ctt_info); + isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info); + } + + if (kindp != NULL) + *kindp = kind; + if (vlenp != NULL) + *vlenp = vlen; + if (isrootp != NULL) + *isrootp = isroot; +} + ssize_t -ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep, +ctf_get_ctt_size(const ctf_file_t *fp, const void *v, ssize_t *sizep, ssize_t *incrementp) { ssize_t size, increment; - if (tp->ctt_size == CTF_LSIZE_SENT) { - size = CTF_TYPE_LSIZE(tp); - increment = sizeof (ctf_type_t); + if (fp->ctf_version == CTF_VERSION_2) { + const struct ctf_type_v2 *ctt = v; + + if (ctt->ctt_size == CTF_V2_LSIZE_SENT) { + size = (size_t)CTF_TYPE_LSIZE(ctt); + increment = sizeof (struct ctf_type_v2); + } else { + size = ctt->ctt_size; + increment = sizeof (struct ctf_stype_v2); + } } else { - size = tp->ctt_size; - increment = sizeof (ctf_stype_t); + const struct ctf_type_v3 *ctt = v; + + if (ctt->ctt_size == CTF_V3_LSIZE_SENT) { + size = (size_t)CTF_TYPE_LSIZE(ctt); + increment = sizeof (struct ctf_type_v3); + } else { + size = ctt->ctt_size; + increment = sizeof (struct ctf_stype_v3); + } } if (sizep) @@ -49,6 +121,61 @@ ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep, return (size); } +/* + * Fetch info for a struct or union member. + */ +void +ctf_get_ctm_info(const ctf_file_t *fp, const void *v, size_t size, + size_t *incrementp, uint_t *typep, ulong_t *offsetp, const char **namep) +{ + size_t increment; + ulong_t offset; + uint_t name, type; + + if (fp->ctf_version == CTF_VERSION_2) { + if (size < CTF_V2_LSTRUCT_THRESH) { + const struct ctf_member_v2 *ctm = v; + + name = ctm->ctm_name; + type = ctm->ctm_type; + offset = ctm->ctm_offset; + increment = sizeof(*ctm); + } else { + const struct ctf_lmember_v2 *ctlm = v; + + name = ctlm->ctlm_name; + type = ctlm->ctlm_type; + offset = (ulong_t)CTF_LMEM_OFFSET(ctlm); + increment = sizeof(*ctlm); + } + } else { + if (size < CTF_V3_LSTRUCT_THRESH) { + const struct ctf_member_v3 *ctm = v; + + name = ctm->ctm_name; + type = ctm->ctm_type; + offset = ctm->ctm_offset; + increment = sizeof(*ctm); + } else { + const struct ctf_lmember_v3 *ctlm = v; + + name = ctlm->ctlm_name; + type = ctlm->ctlm_type; + offset = (ulong_t)CTF_LMEM_OFFSET(ctlm); + increment = sizeof(*ctlm); + } + } + + if (incrementp != NULL) + *incrementp = increment; + if (typep != NULL) + *typep = type; + if (offsetp != NULL) + *offsetp = offset; + if (namep != NULL) + *namep = ctf_strraw(fp, name); +} + /* * Iterate over the members of a STRUCT or UNION. We pass the name, member * type, and offset of each member to the specified callback function. @@ -57,9 +184,9 @@ int ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; ssize_t size, increment; - uint_t kind, n; + uint_t kind, n, vlen; int rc; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) @@ -69,32 +196,22 @@ ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) return (CTF_ERR); /* errno is set for us */ (void) ctf_get_ctt_size(fp, tp, &size, &increment); - kind = LCTF_INFO_KIND(fp, tp->ctt_info); + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno(ofp, ECTF_NOTSOU)); - if (size < CTF_LSTRUCT_THRESH) { - const ctf_member_t *mp = (const ctf_member_t *) - ((uintptr_t)tp + increment); + const char *mp = (const char *)((uintptr_t)tp + increment); - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) { - const char *name = ctf_strptr(fp, mp->ctm_name); - if ((rc = func(name, mp->ctm_type, mp->ctm_offset, - arg)) != 0) - return (rc); - } + for (n = vlen; n != 0; n--, mp += increment) { + const char *name; + ulong_t offset; + uint_t type; - } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) - ((uintptr_t)tp + increment); - - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) { - const char *name = ctf_strptr(fp, lmp->ctlm_name); - if ((rc = func(name, lmp->ctlm_type, - (ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0) - return (rc); - } + ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset, + &name); + if ((rc = func(name, type, offset, arg)) != 0) + return (rc); } return (0); @@ -108,10 +225,10 @@ int ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; const ctf_enum_t *ep; ssize_t increment; - uint_t n; + uint_t kind, n, vlen; int rc; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) @@ -120,14 +237,15 @@ ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ - if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + if (kind != CTF_K_ENUM) return (ctf_set_errno(ofp, ECTF_NOTENUM)); (void) ctf_get_ctt_size(fp, tp, NULL, &increment); ep = (const ctf_enum_t *)((uintptr_t)tp + increment); - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) { + for (n = vlen; n != 0; n--, ep++) { const char *name = ctf_strptr(fp, ep->cte_name); if ((rc = func(name, ep->cte_value, arg)) != 0) return (rc); @@ -145,11 +263,13 @@ ctf_type_iter(ctf_file_t *fp, ctf_type_f *func, void *arg) { ctf_id_t id, max = fp->ctf_typemax; int rc, child = (fp->ctf_flags & LCTF_CHILD); + int isroot; for (id = 1; id <= max; id++) { - const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id); - if (CTF_INFO_ISROOT(tp->ctt_info) && - (rc = func(CTF_INDEX_TO_TYPE(id, child), arg)) != 0) + const void *tp = LCTF_INDEX_TO_TYPEPTR(fp, id); + ctf_get_ctt_info(fp, tp, NULL, NULL, &isroot); + if (isroot && + (rc = func(LCTF_INDEX_TO_TYPE(fp, id, child), arg)) != 0) return (rc); } @@ -168,21 +288,23 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type) { ctf_id_t prev = type, otype = type; ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; + uint_t kind, ctype; while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) { - switch (LCTF_INFO_KIND(fp, tp->ctt_info)) { + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + switch (kind) { case CTF_K_TYPEDEF: case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - if (tp->ctt_type == type || tp->ctt_type == otype || - tp->ctt_type == prev) { + ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL); + if (ctype == type || ctype == otype || ctype == prev) { ctf_dprintf("type %ld cycle detected\n", otype); return (ctf_set_errno(ofp, ECTF_CORRUPT)); } prev = type; - type = tp->ctt_type; + type = ctype; break; default: return (type); @@ -237,9 +359,8 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, cdp != NULL; cdp = ctf_list_next(cdp)) { ctf_file_t *rfp = fp; - const ctf_type_t *tp = - ctf_lookup_by_id(&rfp, cdp->cd_type); - const char *name = ctf_strptr(rfp, tp->ctt_name); + const void *tp = ctf_lookup_by_id(&rfp, cdp->cd_type); + const char *name = ctf_type_rname(rfp, tp); if (k != CTF_K_POINTER && k != CTF_K_ARRAY) ctf_decl_sprintf(&cd, " "); @@ -335,6 +456,23 @@ ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, return (rv >= 0 && rv < len ? buf : NULL); } +const char * +ctf_type_rname(ctf_file_t *fp, const void *v) +{ + uint_t name; + + if (fp->ctf_version == CTF_VERSION_2) { + const struct ctf_type_v2 *ctt = v; + + name = ctt->ctt_name; + } else { + const struct ctf_type_v3 *ctt = v; + + name = ctt->ctt_name; + } + + return (ctf_strptr(fp, name)); +} /* * Resolve the type down to a base type node, and then return the size @@ -343,9 +481,10 @@ ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, ssize_t ctf_type_size(ctf_file_t *fp, ctf_id_t type) { - const ctf_type_t *tp; + const void *tp; ssize_t size; ctf_arinfo_t ar; + uint_t kind; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (-1); /* errno is set for us */ @@ -353,7 +492,9 @@ ctf_type_size(ctf_file_t *fp, ctf_id_t type) if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (-1); /* errno is set for us */ - switch (LCTF_INFO_KIND(fp, tp->ctt_info)) { + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + + switch (kind) { case CTF_K_POINTER: return (fp->ctf_dmodel->ctd_pointer); @@ -392,8 +533,9 @@ ctf_type_size(ctf_file_t *fp, ctf_id_t type) ssize_t ctf_type_align(ctf_file_t *fp, ctf_id_t type) { - const ctf_type_t *tp; + const void *tp; ctf_arinfo_t r; + uint_t kind, vlen; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (-1); /* errno is set for us */ @@ -401,7 +543,9 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type) if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (-1); /* errno is set for us */ - switch (LCTF_INFO_KIND(fp, tp->ctt_info)) { + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + + switch (kind) { case CTF_K_POINTER: case CTF_K_FUNCTION: return (fp->ctf_dmodel->ctd_pointer); @@ -413,7 +557,7 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type) case CTF_K_STRUCT: case CTF_K_UNION: { - uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info); + uint_t n = vlen; ssize_t size, increment; size_t align = 0; const void *vmp; @@ -421,21 +565,16 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type) (void) ctf_get_ctt_size(fp, tp, &size, &increment); vmp = (uchar_t *)tp + increment; - if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT) + if (kind == CTF_K_STRUCT) n = MIN(n, 1); /* only use first member for structs */ - if (size < CTF_LSTRUCT_THRESH) { - const ctf_member_t *mp = vmp; - for (; n != 0; n--, mp++) { - ssize_t am = ctf_type_align(fp, mp->ctm_type); - align = MAX(align, am); - } - } else { - const ctf_lmember_t *lmp = vmp; - for (; n != 0; n--, lmp++) { - ssize_t am = ctf_type_align(fp, lmp->ctlm_type); - align = MAX(align, am); - } + for (const char *mp = vmp; n != 0; n--, mp += increment) { + uint_t type; + + ctf_get_ctm_info(fp, mp, size, &increment, &type, + NULL, NULL); + ssize_t am = ctf_type_align(fp, type); + align = MAX(align, am); } return (align); @@ -455,12 +594,15 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type) int ctf_type_kind(ctf_file_t *fp, ctf_id_t type) { - const ctf_type_t *tp; + const void *tp; + uint_t kind; if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ - return (LCTF_INFO_KIND(fp, tp->ctt_info)); + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + + return (kind); } /* @@ -471,18 +613,22 @@ ctf_id_t ctf_type_reference(ctf_file_t *fp, ctf_id_t type) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; + uint_t ctype, kind; if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ - switch (LCTF_INFO_KIND(fp, tp->ctt_info)) { + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + + switch (kind) { case CTF_K_POINTER: case CTF_K_TYPEDEF: case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - return (tp->ctt_type); + ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL); + return (ctype); default: return (ctf_set_errno(ofp, ECTF_NOTREF)); } @@ -504,8 +650,8 @@ ctf_type_pointer(ctf_file_t *fp, ctf_id_t type) if (ctf_lookup_by_id(&fp, type) == NULL) return (CTF_ERR); /* errno is set for us */ - if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0) - return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD))); + if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)]) != 0) + return (LCTF_INDEX_TO_TYPE(fp, ntype, (fp->ctf_flags & LCTF_CHILD))); if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (ctf_set_errno(ofp, ECTF_NOTYPE)); @@ -513,8 +659,8 @@ ctf_type_pointer(ctf_file_t *fp, ctf_id_t type) if (ctf_lookup_by_id(&fp, type) == NULL) return (ctf_set_errno(ofp, ECTF_NOTYPE)); - if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0) - return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD))); + if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)]) != 0) + return (LCTF_INDEX_TO_TYPE(fp, ntype, (fp->ctf_flags & LCTF_CHILD))); return (ctf_set_errno(ofp, ECTF_NOTYPE)); } @@ -526,16 +672,17 @@ int ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; ssize_t increment; - uint_t data; + uint_t data, kind; if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ (void) ctf_get_ctt_size(fp, tp, NULL, &increment); + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); - switch (LCTF_INFO_KIND(fp, tp->ctt_info)) { + switch (kind) { case CTF_K_INTEGER: data = *(const uint_t *)((uintptr_t)tp + increment); ep->cte_format = CTF_INT_ENCODING(data); @@ -570,10 +717,10 @@ ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype) if (lfp == rfp) return (rval); - if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL) + if (LCTF_TYPE_ISPARENT(lfp, ltype) && lfp->ctf_parent != NULL) lfp = lfp->ctf_parent; - if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL) + if (LCTF_TYPE_ISPARENT(rfp, rtype) && rfp->ctf_parent != NULL) rfp = rfp->ctf_parent; if (lfp < rfp) @@ -595,7 +742,7 @@ int ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype) { - const ctf_type_t *ltp, *rtp; + const void *ltp, *rtp; ctf_encoding_t le, re; ctf_arinfo_t la, ra; uint_t lkind, rkind; @@ -612,8 +759,7 @@ ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype, if (lkind != rkind || (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL || (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL || - strcmp(ctf_strptr(lfp, ltp->ctt_name), - ctf_strptr(rfp, rtp->ctt_name)) != 0) + strcmp(ctf_type_rname(lfp, ltp), ctf_type_rname(rfp, rtp)) != 0) return (0); switch (lkind) { @@ -647,9 +793,9 @@ _ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name, ulong_t off, ctf_membinfo_t *mip) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; ssize_t size, increment; - uint_t kind, n; + uint_t kind, n, vlen; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ @@ -658,41 +804,27 @@ _ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name, ulong_t off, return (CTF_ERR); /* errno is set for us */ (void) ctf_get_ctt_size(fp, tp, &size, &increment); - kind = LCTF_INFO_KIND(fp, tp->ctt_info); + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno(ofp, ECTF_NOTSOU)); - if (size < CTF_LSTRUCT_THRESH) { - const ctf_member_t *mp = (const ctf_member_t *) - ((uintptr_t)tp + increment); - - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) { - if (mp->ctm_name == 0 && - _ctf_member_info(fp, mp->ctm_type, name, - mp->ctm_offset + off, mip) == 0) - return (0); - if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) { - mip->ctm_type = mp->ctm_type; - mip->ctm_offset = mp->ctm_offset + off; - return (0); - } - } - } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) - ((uintptr_t)tp + increment); - - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) { - if (lmp->ctlm_name == 0 && - _ctf_member_info(fp, lmp->ctlm_name, name, - (ulong_t)CTF_LMEM_OFFSET(lmp) + off, mip) == 0) - return (0); - if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) { - mip->ctm_type = lmp->ctlm_type; - mip->ctm_offset = - (ulong_t)CTF_LMEM_OFFSET(lmp) + off; - return (0); - } + const char *mp = (const char *)((uintptr_t)tp + increment); + + for (n = vlen; n != 0; n--, mp += increment) { + const char *name1; + ulong_t offset; + uint_t type; + + ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset, + &name1); + if (name1 == NULL && + _ctf_member_info(fp, type, name1, offset + off, mip) == 0) + return (0); + if (strcmp(name1, name) == 0) { + mip->ctm_type = type; + mip->ctm_offset = offset + off; + return (0); } } @@ -717,22 +849,34 @@ int ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; - const ctf_array_t *ap; + const void *ap, *tp; ssize_t increment; + uint_t kind; if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ - if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY) + ctf_get_ctt_info(fp, tp, &kind, NULL, NULL); + + if (kind != CTF_K_ARRAY) return (ctf_set_errno(ofp, ECTF_NOTARRAY)); (void) ctf_get_ctt_size(fp, tp, NULL, &increment); - ap = (const ctf_array_t *)((uintptr_t)tp + increment); - arp->ctr_contents = ap->cta_contents; - arp->ctr_index = ap->cta_index; - arp->ctr_nelems = ap->cta_nelems; + ap = (const void *)((uintptr_t)tp + increment); + if (fp->ctf_version == CTF_VERSION_2) { + const struct ctf_array_v2 *ap2 = ap; + + arp->ctr_contents = ap2->cta_contents; + arp->ctr_index = ap2->cta_index; + arp->ctr_nelems = ap2->cta_nelems; + } else { + const struct ctf_array_v3 *ap3 = ap; + + arp->ctr_contents = ap3->cta_contents; + arp->ctr_index = ap3->cta_index; + arp->ctr_nelems = ap3->cta_nelems; + } return (0); } @@ -745,10 +889,10 @@ const char * ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; const ctf_enum_t *ep; ssize_t increment; - uint_t n; + uint_t kind, n, vlen; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (NULL); /* errno is set for us */ @@ -756,7 +900,9 @@ ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value) if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (NULL); /* errno is set for us */ - if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) { + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + + if (kind != CTF_K_ENUM) { (void) ctf_set_errno(ofp, ECTF_NOTENUM); return (NULL); } @@ -765,7 +911,7 @@ ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value) ep = (const ctf_enum_t *)((uintptr_t)tp + increment); - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) { + for (n = vlen; n != 0; n--, ep++) { if (ep->cte_value == value) return (ctf_strptr(fp, ep->cte_name)); } @@ -782,10 +928,10 @@ int ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp) { ctf_file_t *ofp = fp; - const ctf_type_t *tp; + const void *tp; const ctf_enum_t *ep; ssize_t size, increment; - uint_t n; + uint_t kind, n, vlen; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ @@ -793,7 +939,9 @@ ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp) if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) return (CTF_ERR); /* errno is set for us */ - if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) { + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); + + if (kind != CTF_K_ENUM) { (void) ctf_set_errno(ofp, ECTF_NOTENUM); return (CTF_ERR); } @@ -802,7 +950,7 @@ ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp) ep = (const ctf_enum_t *)((uintptr_t)tp + increment); - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) { + for (n = vlen; n != 0; n--, ep++) { if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) { if (valp != NULL) *valp = ep->cte_value; @@ -826,9 +974,9 @@ ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg, const char *name, ulong_t offset, int depth) { ctf_id_t otype = type; - const ctf_type_t *tp; + const void *tp; ssize_t size, increment; - uint_t kind, n; + uint_t kind, n, vlen; int rc; if ((type = ctf_type_resolve(fp, type)) == CTF_ERR) @@ -840,35 +988,24 @@ ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg, if ((rc = func(name, otype, offset, depth, arg)) != 0) return (rc); - kind = LCTF_INFO_KIND(fp, tp->ctt_info); + ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL); if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (0); (void) ctf_get_ctt_size(fp, tp, &size, &increment); - if (size < CTF_LSTRUCT_THRESH) { - const ctf_member_t *mp = (const ctf_member_t *) - ((uintptr_t)tp + increment); + const char *mp = (const char *)((uintptr_t)tp + increment); + for (n = vlen; n != 0; n--, mp += increment) { + const char *name; + ulong_t offset1; + uint_t type; - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) { - if ((rc = ctf_type_rvisit(fp, mp->ctm_type, - func, arg, ctf_strptr(fp, mp->ctm_name), - offset + mp->ctm_offset, depth + 1)) != 0) - return (rc); - } - - } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) - ((uintptr_t)tp + increment); - - for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) { - if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type, - func, arg, ctf_strptr(fp, lmp->ctlm_name), - offset + (ulong_t)CTF_LMEM_OFFSET(lmp), - depth + 1)) != 0) - return (rc); - } + ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset1, + &name); + if ((rc = ctf_type_rvisit(fp, type, func, arg, name, + offset + offset1, depth + 1)) != 0) + return (rc); } return (0); diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c index f48c09cce0e..e1ba993a09a 100644 --- a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c +++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c @@ -245,7 +245,8 @@ ctf_fdopen(int fd, int *errp) */ if (nbytes >= (ssize_t) sizeof (ctf_preamble_t) && hdr.ctf.ctp_magic == CTF_MAGIC) { - if (hdr.ctf.ctp_version > CTF_VERSION) + if (hdr.ctf.ctp_version != CTF_VERSION_2 && + hdr.ctf.ctp_version != CTF_VERSION_3) return (ctf_set_open_errno(errp, ECTF_CTFVERS)); ctfsect.cts_data = mmap64(NULL, st.st_size, PROT_READ, -- 2.45.0