git: a49aa9da7835 - stable/13 - libctf: Handle CTFv3 containers

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 07 Apr 2022 00:31:03 UTC
The branch stable/13 has been updated by markj:

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

commit a49aa9da7835742aa455c7eec4493f0034b4e197
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-03-07 13:53:27 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-04-07 00:30:45 +0000

    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.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit a6fb86917362e3f6d24e95e940e80845c2cfde8a)
---
 cddl/contrib/opensolaris/common/ctf/ctf_create.c   | 371 ++++++++++-------
 cddl/contrib/opensolaris/common/ctf/ctf_decl.c     |  19 +-
 cddl/contrib/opensolaris/common/ctf/ctf_hash.c     |  16 +-
 cddl/contrib/opensolaris/common/ctf/ctf_impl.h     |  65 ++-
 cddl/contrib/opensolaris/common/ctf/ctf_lookup.c   |  38 +-
 cddl/contrib/opensolaris/common/ctf/ctf_open.c     | 367 +++++++++++++----
 cddl/contrib/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 35a43cc4e790..154cefb775ba 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 6bf57001570f..63d173c15f5f 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 b10a7618f66e..5a36fbbd88cf 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_hash.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_hash.c
@@ -29,7 +29,7 @@
 
 #include <ctf_impl.h>
 
-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 dd6167856074..774eff1380fa 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 <sys/ctf.h>) */
+	struct ctf_type_v3 dtd_data;	/* type node (see <sys/ctf.h>) */
 	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,
*** 1528 LINES SKIPPED ***