Home | History | Annotate | Line # | Download | only in ctf
ctf_create.c revision 1.3
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 
     23 /*
     24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     25  * Use is subject to license terms.
     26  */
     27 
     28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     29 
     30 #include <sys/sysmacros.h>
     31 #include <sys/param.h>
     32 #include <sys/mman.h>
     33 #include <ctf_impl.h>
     34 
     35 /*
     36  * This static string is used as the template for initially populating a
     37  * dynamic container's string table.  We always store \0 in the first byte,
     38  * and we use the generic string "PARENT" to mark this container's parent
     39  * if one is associated with the container using ctf_import().
     40  */
     41 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
     42 
     43 /*
     44  * To create an empty CTF container, we just declare a zeroed header and call
     45  * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
     46  * and initialize the dynamic members.  We set dtstrlen to 1 to reserve the
     47  * first byte of the string table for a \0 byte, and we start assigning type
     48  * IDs at 1 because type ID 0 is used as a sentinel.
     49  */
     50 ctf_file_t *
     51 ctf_create(int *errp)
     52 {
     53 	static const ctf_header_t hdr = { .cth_preamble = {
     54 		.ctp_magic = CTF_MAGIC,
     55 		.ctp_version = CTF_VERSION,
     56 		.ctp_flags = 0
     57 	} };
     58 
     59 	const ulong_t hashlen = 128;
     60 	ctf_dtdef_t **hash = ctf_alloc(hashlen * sizeof (ctf_dtdef_t *));
     61 	ctf_sect_t cts;
     62 	ctf_file_t *fp;
     63 
     64 	if (hash == NULL)
     65 		return (ctf_set_open_errno(errp, EAGAIN));
     66 
     67 	cts.cts_name = __UNCONST(_CTF_SECTION);
     68 	cts.cts_type = SHT_PROGBITS;
     69 	cts.cts_flags = 0;
     70 	cts.cts_data = __UNCONST(&hdr);
     71 	cts.cts_size = sizeof (hdr);
     72 	cts.cts_entsize = 1;
     73 	cts.cts_offset = 0;
     74 
     75 	if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) == NULL) {
     76 		ctf_free(hash, hashlen * sizeof (ctf_dtdef_t *));
     77 		return (NULL);
     78 	}
     79 
     80 	fp->ctf_flags |= LCTF_RDWR;
     81 	fp->ctf_dthashlen = hashlen;
     82 	bzero(hash, hashlen * sizeof (ctf_dtdef_t *));
     83 	fp->ctf_dthash = hash;
     84 	fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE);
     85 	fp->ctf_dtnextid = 1;
     86 	fp->ctf_dtoldid = 0;
     87 
     88 	return (fp);
     89 }
     90 
     91 static uchar_t *
     92 ctf_copy_smembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
     93 {
     94 	ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
     95 	ctf_member_t ctm;
     96 
     97 	for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
     98 		if (dmd->dmd_name) {
     99 			ctm.ctm_name = soff;
    100 			soff += strlen(dmd->dmd_name) + 1;
    101 		} else
    102 			ctm.ctm_name = 0;
    103 
    104 		ctm.ctm_type = (ushort_t)dmd->dmd_type;
    105 		ctm.ctm_offset = (ushort_t)dmd->dmd_offset;
    106 
    107 		bcopy(&ctm, t, sizeof (ctm));
    108 		t += sizeof (ctm);
    109 	}
    110 
    111 	return (t);
    112 }
    113 
    114 static uchar_t *
    115 ctf_copy_lmembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
    116 {
    117 	ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    118 	ctf_lmember_t ctlm;
    119 
    120 	for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
    121 		if (dmd->dmd_name) {
    122 			ctlm.ctlm_name = soff;
    123 			soff += strlen(dmd->dmd_name) + 1;
    124 		} else
    125 			ctlm.ctlm_name = 0;
    126 
    127 		ctlm.ctlm_type = (ushort_t)dmd->dmd_type;
    128 		ctlm.ctlm_pad = 0;
    129 		ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
    130 		ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
    131 
    132 		bcopy(&ctlm, t, sizeof (ctlm));
    133 		t += sizeof (ctlm);
    134 	}
    135 
    136 	return (t);
    137 }
    138 
    139 static uchar_t *
    140 ctf_copy_emembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
    141 {
    142 	ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    143 	ctf_enum_t cte;
    144 
    145 	for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
    146 		cte.cte_name = soff;
    147 		cte.cte_value = dmd->dmd_value;
    148 		soff += strlen(dmd->dmd_name) + 1;
    149 		bcopy(&cte, t, sizeof (cte));
    150 		t += sizeof (cte);
    151 	}
    152 
    153 	return (t);
    154 }
    155 
    156 static uchar_t *
    157 ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
    158 {
    159 	ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    160 	size_t len;
    161 
    162 	for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
    163 		if (dmd->dmd_name == NULL)
    164 			continue; /* skip anonymous members */
    165 		len = strlen(dmd->dmd_name) + 1;
    166 		bcopy(dmd->dmd_name, s, len);
    167 		s += len;
    168 	}
    169 
    170 	return (s);
    171 }
    172 
    173 /*
    174  * If the specified CTF container is writable and has been modified, reload
    175  * this container with the updated type definitions.  In order to make this
    176  * code and the rest of libctf as simple as possible, we perform updates by
    177  * taking the dynamic type definitions and creating an in-memory CTF file
    178  * containing the definitions, and then call ctf_bufopen() on it.  This not
    179  * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest
    180  * of the library code with different lookup paths for static and dynamic
    181  * type definitions.  We are therefore optimizing greatly for lookup over
    182  * update, which we assume will be an uncommon operation.  We perform one
    183  * extra trick here for the benefit of callers and to keep our code simple:
    184  * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
    185  * constant for the caller, so after ctf_bufopen() returns, we use bcopy to
    186  * swap the interior of the old and new ctf_file_t's, and then free the old.
    187  */
    188 int
    189 ctf_update(ctf_file_t *fp)
    190 {
    191 	ctf_file_t ofp, *nfp;
    192 	ctf_header_t hdr;
    193 	ctf_dtdef_t *dtd;
    194 	ctf_sect_t cts;
    195 
    196 	uchar_t *s, *s0, *t;
    197 	size_t size;
    198 	void *buf;
    199 	int err;
    200 
    201 	if (!(fp->ctf_flags & LCTF_RDWR))
    202 		return (ctf_set_errno(fp, ECTF_RDONLY));
    203 
    204 	if (!(fp->ctf_flags & LCTF_DIRTY))
    205 		return (0); /* no update required */
    206 
    207 	/*
    208 	 * Fill in an initial CTF header.  We will leave the label, object,
    209 	 * and function sections empty and only output a header, type section,
    210 	 * and string table.  The type section begins at a 4-byte aligned
    211 	 * boundary past the CTF header itself (at relative offset zero).
    212 	 */
    213 	bzero(&hdr, sizeof (hdr));
    214 	hdr.cth_magic = CTF_MAGIC;
    215 	hdr.cth_version = CTF_VERSION;
    216 
    217 	if (fp->ctf_flags & LCTF_CHILD)
    218 		hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */
    219 
    220 	/*
    221 	 * Iterate through the dynamic type definition list and compute the
    222 	 * size of the CTF type section we will need to generate.
    223 	 */
    224 	for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs);
    225 	    dtd != NULL; dtd = ctf_list_next(dtd)) {
    226 
    227 		uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
    228 		uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
    229 
    230 		if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
    231 			size += sizeof (ctf_stype_t);
    232 		else
    233 			size += sizeof (ctf_type_t);
    234 
    235 		switch (kind) {
    236 		case CTF_K_INTEGER:
    237 		case CTF_K_FLOAT:
    238 			size += sizeof (uint_t);
    239 			break;
    240 		case CTF_K_ARRAY:
    241 			size += sizeof (ctf_array_t);
    242 			break;
    243 		case CTF_K_FUNCTION:
    244 			size += sizeof (ushort_t) * (vlen + (vlen & 1));
    245 			break;
    246 		case CTF_K_STRUCT:
    247 		case CTF_K_UNION:
    248 			if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
    249 				size += sizeof (ctf_member_t) * vlen;
    250 			else
    251 				size += sizeof (ctf_lmember_t) * vlen;
    252 			break;
    253 		case CTF_K_ENUM:
    254 			size += sizeof (ctf_enum_t) * vlen;
    255 			break;
    256 		}
    257 	}
    258 
    259 	/*
    260 	 * Fill in the string table offset and size, compute the size of the
    261 	 * entire CTF buffer we need, and then allocate a new buffer and
    262 	 * bcopy the finished header to the start of the buffer.
    263 	 */
    264 	hdr.cth_stroff = hdr.cth_typeoff + size;
    265 	hdr.cth_strlen = fp->ctf_dtstrlen;
    266 	size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
    267 
    268 	if ((buf = ctf_data_alloc(size)) == MAP_FAILED)
    269 		return (ctf_set_errno(fp, EAGAIN));
    270 
    271 	bcopy(&hdr, buf, sizeof (ctf_header_t));
    272 	t = (uchar_t *)buf + sizeof (ctf_header_t);
    273 	s = s0 = (uchar_t *)buf + sizeof (ctf_header_t) + hdr.cth_stroff;
    274 
    275 	bcopy(_CTF_STRTAB_TEMPLATE, s, sizeof (_CTF_STRTAB_TEMPLATE));
    276 	s += sizeof (_CTF_STRTAB_TEMPLATE);
    277 
    278 	/*
    279 	 * We now take a final lap through the dynamic type definition list and
    280 	 * copy the appropriate type records and strings to the output buffer.
    281 	 */
    282 	for (dtd = ctf_list_next(&fp->ctf_dtdefs);
    283 	    dtd != NULL; dtd = ctf_list_next(dtd)) {
    284 
    285 		uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
    286 		uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
    287 
    288 		ctf_array_t cta;
    289 		uint_t encoding;
    290 		size_t len;
    291 
    292 		if (dtd->dtd_name != NULL) {
    293 			dtd->dtd_data.ctt_name = (uint_t)(s - s0);
    294 			len = strlen(dtd->dtd_name) + 1;
    295 			bcopy(dtd->dtd_name, s, len);
    296 			s += len;
    297 		} else
    298 			dtd->dtd_data.ctt_name = 0;
    299 
    300 		if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
    301 			len = sizeof (ctf_stype_t);
    302 		else
    303 			len = sizeof (ctf_type_t);
    304 
    305 		bcopy(&dtd->dtd_data, t, len);
    306 		t += len;
    307 
    308 		switch (kind) {
    309 		case CTF_K_INTEGER:
    310 		case CTF_K_FLOAT:
    311 			if (kind == CTF_K_INTEGER) {
    312 				encoding = CTF_INT_DATA(
    313 				    dtd->dtd_u.dtu_enc.cte_format,
    314 				    dtd->dtd_u.dtu_enc.cte_offset,
    315 				    dtd->dtd_u.dtu_enc.cte_bits);
    316 			} else {
    317 				encoding = CTF_FP_DATA(
    318 				    dtd->dtd_u.dtu_enc.cte_format,
    319 				    dtd->dtd_u.dtu_enc.cte_offset,
    320 				    dtd->dtd_u.dtu_enc.cte_bits);
    321 			}
    322 			bcopy(&encoding, t, sizeof (encoding));
    323 			t += sizeof (encoding);
    324 			break;
    325 
    326 		case CTF_K_ARRAY:
    327 			cta.cta_contents = (ushort_t)
    328 			    dtd->dtd_u.dtu_arr.ctr_contents;
    329 			cta.cta_index = (ushort_t)
    330 			    dtd->dtd_u.dtu_arr.ctr_index;
    331 			cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
    332 			bcopy(&cta, t, sizeof (cta));
    333 			t += sizeof (cta);
    334 			break;
    335 
    336 		case CTF_K_FUNCTION: {
    337 			ushort_t *argv = (ushort_t *)(uintptr_t)t;
    338 			uint_t argc;
    339 
    340 			for (argc = 0; argc < vlen; argc++)
    341 				*argv++ = (ushort_t)dtd->dtd_u.dtu_argv[argc];
    342 
    343 			if (vlen & 1)
    344 				*argv++ = 0; /* pad to 4-byte boundary */
    345 
    346 			t = (uchar_t *)argv;
    347 			break;
    348 		}
    349 
    350 		case CTF_K_STRUCT:
    351 		case CTF_K_UNION:
    352 			if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
    353 				t = ctf_copy_smembers(dtd, (uint_t)(s - s0), t);
    354 			else
    355 				t = ctf_copy_lmembers(dtd, (uint_t)(s - s0), t);
    356 			s = ctf_copy_membnames(dtd, s);
    357 			break;
    358 
    359 		case CTF_K_ENUM:
    360 			t = ctf_copy_emembers(dtd, (uint_t)(s - s0), t);
    361 			s = ctf_copy_membnames(dtd, s);
    362 			break;
    363 		}
    364 	}
    365 
    366 	/*
    367 	 * Finally, we are ready to ctf_bufopen() the new container.  If this
    368 	 * is successful, we then switch nfp and fp and free the old container.
    369 	 */
    370 	ctf_data_protect(buf, size);
    371 	cts.cts_name = __UNCONST(_CTF_SECTION);
    372 	cts.cts_type = SHT_PROGBITS;
    373 	cts.cts_flags = 0;
    374 	cts.cts_data = buf;
    375 	cts.cts_size = size;
    376 	cts.cts_entsize = 1;
    377 	cts.cts_offset = 0;
    378 
    379 	if ((nfp = ctf_bufopen(&cts, NULL, NULL, &err)) == NULL) {
    380 		ctf_data_free(buf, size);
    381 		return (ctf_set_errno(fp, err));
    382 	}
    383 
    384 	(void) ctf_setmodel(nfp, ctf_getmodel(fp));
    385 	(void) ctf_import(nfp, fp->ctf_parent);
    386 
    387 	nfp->ctf_refcnt = fp->ctf_refcnt;
    388 	nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
    389 	nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */
    390 	nfp->ctf_dthash = fp->ctf_dthash;
    391 	nfp->ctf_dthashlen = fp->ctf_dthashlen;
    392 	nfp->ctf_dtdefs = fp->ctf_dtdefs;
    393 	nfp->ctf_dtstrlen = fp->ctf_dtstrlen;
    394 	nfp->ctf_dtnextid = fp->ctf_dtnextid;
    395 	nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
    396 	nfp->ctf_specific = fp->ctf_specific;
    397 
    398 	fp->ctf_dthash = NULL;
    399 	fp->ctf_dthashlen = 0;
    400 	bzero(&fp->ctf_dtdefs, sizeof (ctf_list_t));
    401 
    402 	bcopy(fp, &ofp, sizeof (ctf_file_t));
    403 	bcopy(nfp, fp, sizeof (ctf_file_t));
    404 	bcopy(&ofp, nfp, sizeof (ctf_file_t));
    405 
    406 	/*
    407 	 * Initialize the ctf_lookup_by_name top-level dictionary.  We keep an
    408 	 * array of type name prefixes and the corresponding ctf_hash to use.
    409 	 * NOTE: This code must be kept in sync with the code in ctf_bufopen().
    410 	 */
    411 	fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
    412 	fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
    413 	fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
    414 	fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
    415 
    416 	nfp->ctf_refcnt = 1; /* force nfp to be freed */
    417 	ctf_close(nfp);
    418 
    419 	return (0);
    420 }
    421 
    422 void
    423 ctf_dtd_insert(ctf_file_t *fp, ctf_dtdef_t *dtd)
    424 {
    425 	ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
    426 
    427 	dtd->dtd_hash = fp->ctf_dthash[h];
    428 	fp->ctf_dthash[h] = dtd;
    429 	ctf_list_append(&fp->ctf_dtdefs, dtd);
    430 }
    431 
    432 void
    433 ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
    434 {
    435 	ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
    436 	ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
    437 	ctf_dmdef_t *dmd, *nmd;
    438 	size_t len;
    439 
    440 	for (p = *q; p != NULL; p = p->dtd_hash) {
    441 		if (p != dtd)
    442 			q = &p->dtd_hash;
    443 		else
    444 			break;
    445 	}
    446 
    447 	if (p != NULL)
    448 		*q = p->dtd_hash;
    449 
    450 	switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
    451 	case CTF_K_STRUCT:
    452 	case CTF_K_UNION:
    453 	case CTF_K_ENUM:
    454 		for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    455 		    dmd != NULL; dmd = nmd) {
    456 			if (dmd->dmd_name != NULL) {
    457 				len = strlen(dmd->dmd_name) + 1;
    458 				ctf_free(dmd->dmd_name, len);
    459 				fp->ctf_dtstrlen -= len;
    460 			}
    461 			nmd = ctf_list_next(dmd);
    462 			ctf_free(dmd, sizeof (ctf_dmdef_t));
    463 		}
    464 		break;
    465 	case CTF_K_FUNCTION:
    466 		ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
    467 		    CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
    468 		break;
    469 	}
    470 
    471 	if (dtd->dtd_name) {
    472 		len = strlen(dtd->dtd_name) + 1;
    473 		ctf_free(dtd->dtd_name, len);
    474 		fp->ctf_dtstrlen -= len;
    475 	}
    476 
    477 	ctf_list_delete(&fp->ctf_dtdefs, dtd);
    478 	ctf_free(dtd, sizeof (ctf_dtdef_t));
    479 }
    480 
    481 ctf_dtdef_t *
    482 ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
    483 {
    484 	ulong_t h = type & (fp->ctf_dthashlen - 1);
    485 	ctf_dtdef_t *dtd;
    486 
    487 	if (fp->ctf_dthash == NULL)
    488 		return (NULL);
    489 
    490 	for (dtd = fp->ctf_dthash[h]; dtd != NULL; dtd = dtd->dtd_hash) {
    491 		if (dtd->dtd_type == type)
    492 			break;
    493 	}
    494 
    495 	return (dtd);
    496 }
    497 
    498 /*
    499  * Discard all of the dynamic type definitions that have been added to the
    500  * container since the last call to ctf_update().  We locate such types by
    501  * scanning the list and deleting elements that have type IDs greater than
    502  * ctf_dtoldid, which is set by ctf_update(), above.
    503  */
    504 int
    505 ctf_discard(ctf_file_t *fp)
    506 {
    507 	ctf_dtdef_t *dtd, *ntd = NULL;
    508 
    509 	if (!(fp->ctf_flags & LCTF_RDWR))
    510 		return (ctf_set_errno(fp, ECTF_RDONLY));
    511 
    512 	if (!(fp->ctf_flags & LCTF_DIRTY))
    513 		return (0); /* no update required */
    514 
    515 	for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
    516 		if (dtd->dtd_type <= fp->ctf_dtoldid)
    517 			continue; /* skip types that have been committed */
    518 
    519 		ntd = ctf_list_next(dtd);
    520 		ctf_dtd_delete(fp, dtd);
    521 	}
    522 
    523 	fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
    524 	fp->ctf_flags &= ~LCTF_DIRTY;
    525 
    526 	return (0);
    527 }
    528 
    529 static ctf_id_t
    530 ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
    531 {
    532 	ctf_dtdef_t *dtd;
    533 	ctf_id_t type;
    534 	char *s = NULL;
    535 
    536 	if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
    537 		return (ctf_set_errno(fp, EINVAL));
    538 
    539 	if (!(fp->ctf_flags & LCTF_RDWR))
    540 		return (ctf_set_errno(fp, ECTF_RDONLY));
    541 
    542 	if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
    543 		return (ctf_set_errno(fp, ECTF_FULL));
    544 
    545 	if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL)
    546 		return (ctf_set_errno(fp, EAGAIN));
    547 
    548 	if (name != NULL && (s = ctf_strdup(name)) == NULL) {
    549 		ctf_free(dtd, sizeof (ctf_dtdef_t));
    550 		return (ctf_set_errno(fp, EAGAIN));
    551 	}
    552 
    553 	type = fp->ctf_dtnextid++;
    554 	type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD));
    555 
    556 	bzero(dtd, sizeof (ctf_dtdef_t));
    557 	dtd->dtd_name = s;
    558 	dtd->dtd_type = type;
    559 
    560 	if (s != NULL)
    561 		fp->ctf_dtstrlen += strlen(s) + 1;
    562 
    563 	ctf_dtd_insert(fp, dtd);
    564 	fp->ctf_flags |= LCTF_DIRTY;
    565 
    566 	*rp = dtd;
    567 	return (type);
    568 }
    569 
    570 /*
    571  * When encoding integer sizes, we want to convert a byte count in the range
    572  * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc).  The clp2() function
    573  * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
    574  */
    575 static size_t
    576 clp2(size_t x)
    577 {
    578 	x--;
    579 
    580 	x |= (x >> 1);
    581 	x |= (x >> 2);
    582 	x |= (x >> 4);
    583 	x |= (x >> 8);
    584 	x |= (x >> 16);
    585 
    586 	return (x + 1);
    587 }
    588 
    589 static ctf_id_t
    590 ctf_add_encoded(ctf_file_t *fp, uint_t flag,
    591     const char *name, const ctf_encoding_t *ep, uint_t kind)
    592 {
    593 	ctf_dtdef_t *dtd;
    594 	ctf_id_t type;
    595 
    596 	if (ep == NULL)
    597 		return (ctf_set_errno(fp, EINVAL));
    598 
    599 	if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    600 		return (CTF_ERR); /* errno is set for us */
    601 
    602 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
    603 	dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY);
    604 	dtd->dtd_u.dtu_enc = *ep;
    605 
    606 	return (type);
    607 }
    608 
    609 static ctf_id_t
    610 ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
    611 {
    612 	ctf_dtdef_t *dtd;
    613 	ctf_id_t type;
    614 
    615 	if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
    616 		return (ctf_set_errno(fp, EINVAL));
    617 
    618 	if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
    619 		return (CTF_ERR); /* errno is set for us */
    620 
    621 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
    622 	dtd->dtd_data.ctt_type = (ushort_t)ref;
    623 
    624 	return (type);
    625 }
    626 
    627 ctf_id_t
    628 ctf_add_integer(ctf_file_t *fp, uint_t flag,
    629     const char *name, const ctf_encoding_t *ep)
    630 {
    631 	return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER));
    632 }
    633 
    634 ctf_id_t
    635 ctf_add_float(ctf_file_t *fp, uint_t flag,
    636     const char *name, const ctf_encoding_t *ep)
    637 {
    638 	return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT));
    639 }
    640 
    641 ctf_id_t
    642 ctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
    643 {
    644 	return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));
    645 }
    646 
    647 ctf_id_t
    648 ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
    649 {
    650 	ctf_dtdef_t *dtd;
    651 	ctf_id_t type;
    652 
    653 	if (arp == NULL)
    654 		return (ctf_set_errno(fp, EINVAL));
    655 
    656 	if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
    657 		return (CTF_ERR); /* errno is set for us */
    658 
    659 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
    660 	dtd->dtd_data.ctt_size = 0;
    661 	dtd->dtd_u.dtu_arr = *arp;
    662 
    663 	return (type);
    664 }
    665 
    666 int
    667 ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
    668 {
    669 	ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
    670 
    671 	if (!(fp->ctf_flags & LCTF_RDWR))
    672 		return (ctf_set_errno(fp, ECTF_RDONLY));
    673 
    674 	if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
    675 		return (ctf_set_errno(fp, ECTF_BADID));
    676 
    677 	fp->ctf_flags |= LCTF_DIRTY;
    678 	dtd->dtd_u.dtu_arr = *arp;
    679 
    680 	return (0);
    681 }
    682 
    683 ctf_id_t
    684 ctf_add_function(ctf_file_t *fp, uint_t flag,
    685     const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
    686 {
    687 	ctf_dtdef_t *dtd;
    688 	ctf_id_t type;
    689 	uint_t vlen;
    690 	ctf_id_t *vdat = NULL;
    691 
    692 	if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
    693 	    (ctc->ctc_argc != 0 && argv == NULL))
    694 		return (ctf_set_errno(fp, EINVAL));
    695 
    696 	vlen = ctc->ctc_argc;
    697 	if (ctc->ctc_flags & CTF_FUNC_VARARG)
    698 		vlen++; /* add trailing zero to indicate varargs (see below) */
    699 
    700 	if (vlen > CTF_MAX_VLEN)
    701 		return (ctf_set_errno(fp, EOVERFLOW));
    702 
    703 	if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
    704 		return (ctf_set_errno(fp, EAGAIN));
    705 
    706 	if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) {
    707 		ctf_free(vdat, sizeof (ctf_id_t) * vlen);
    708 		return (CTF_ERR); /* errno is set for us */
    709 	}
    710 
    711 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
    712 	dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
    713 
    714 	bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
    715 	if (ctc->ctc_flags & CTF_FUNC_VARARG)
    716 		vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
    717 	dtd->dtd_u.dtu_argv = vdat;
    718 
    719 	return (type);
    720 }
    721 
    722 ctf_id_t
    723 ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name)
    724 {
    725 	ctf_hash_t *hp = &fp->ctf_structs;
    726 	ctf_helem_t *hep = NULL;
    727 	ctf_dtdef_t *dtd;
    728 	ctf_id_t type;
    729 
    730 	if (name != NULL)
    731 		hep = ctf_hash_lookup(hp, fp, name, strlen(name));
    732 
    733 	if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
    734 		dtd = ctf_dtd_lookup(fp, type = hep->h_type);
    735 	else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    736 		return (CTF_ERR); /* errno is set for us */
    737 
    738 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0);
    739 	dtd->dtd_data.ctt_size = 0;
    740 
    741 	return (type);
    742 }
    743 
    744 ctf_id_t
    745 ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name)
    746 {
    747 	ctf_hash_t *hp = &fp->ctf_unions;
    748 	ctf_helem_t *hep = NULL;
    749 	ctf_dtdef_t *dtd;
    750 	ctf_id_t type;
    751 
    752 	if (name != NULL)
    753 		hep = ctf_hash_lookup(hp, fp, name, strlen(name));
    754 
    755 	if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
    756 		dtd = ctf_dtd_lookup(fp, type = hep->h_type);
    757 	else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    758 		return (CTF_ERR); /* errno is set for us */
    759 
    760 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
    761 	dtd->dtd_data.ctt_size = 0;
    762 
    763 	return (type);
    764 }
    765 
    766 ctf_id_t
    767 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
    768 {
    769 	ctf_hash_t *hp = &fp->ctf_enums;
    770 	ctf_helem_t *hep = NULL;
    771 	ctf_dtdef_t *dtd;
    772 	ctf_id_t type;
    773 
    774 	if (name != NULL)
    775 		hep = ctf_hash_lookup(hp, fp, name, strlen(name));
    776 
    777 	if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
    778 		dtd = ctf_dtd_lookup(fp, type = hep->h_type);
    779 	else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    780 		return (CTF_ERR); /* errno is set for us */
    781 
    782 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
    783 	dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
    784 
    785 	return (type);
    786 }
    787 
    788 ctf_id_t
    789 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
    790 {
    791 	ctf_hash_t *hp;
    792 	ctf_helem_t *hep;
    793 	ctf_dtdef_t *dtd;
    794 	ctf_id_t type;
    795 
    796 	switch (kind) {
    797 	case CTF_K_STRUCT:
    798 		hp = &fp->ctf_structs;
    799 		break;
    800 	case CTF_K_UNION:
    801 		hp = &fp->ctf_unions;
    802 		break;
    803 	case CTF_K_ENUM:
    804 		hp = &fp->ctf_enums;
    805 		break;
    806 	default:
    807 		return (ctf_set_errno(fp, ECTF_NOTSUE));
    808 	}
    809 
    810 	/*
    811 	 * If the type is already defined or exists as a forward tag, just
    812 	 * return the ctf_id_t of the existing definition.
    813 	 */
    814 	if (name != NULL && (hep = ctf_hash_lookup(hp,
    815 	    fp, name, strlen(name))) != NULL)
    816 		return (hep->h_type);
    817 
    818 	if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    819 		return (CTF_ERR); /* errno is set for us */
    820 
    821 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0);
    822 	dtd->dtd_data.ctt_type = kind;
    823 
    824 	return (type);
    825 }
    826 
    827 ctf_id_t
    828 ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
    829 {
    830 	ctf_dtdef_t *dtd;
    831 	ctf_id_t type;
    832 
    833 	if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
    834 		return (ctf_set_errno(fp, EINVAL));
    835 
    836 	if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
    837 		return (CTF_ERR); /* errno is set for us */
    838 
    839 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
    840 	dtd->dtd_data.ctt_type = (ushort_t)ref;
    841 
    842 	return (type);
    843 }
    844 
    845 ctf_id_t
    846 ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
    847 {
    848 	return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));
    849 }
    850 
    851 ctf_id_t
    852 ctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
    853 {
    854 	return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST));
    855 }
    856 
    857 ctf_id_t
    858 ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
    859 {
    860 	return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT));
    861 }
    862 
    863 int
    864 ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
    865 {
    866 	ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, enid);
    867 	ctf_dmdef_t *dmd;
    868 
    869 	uint_t kind, vlen, root;
    870 	char *s;
    871 
    872 	if (name == NULL)
    873 		return (ctf_set_errno(fp, EINVAL));
    874 
    875 	if (!(fp->ctf_flags & LCTF_RDWR))
    876 		return (ctf_set_errno(fp, ECTF_RDONLY));
    877 
    878 	if (dtd == NULL)
    879 		return (ctf_set_errno(fp, ECTF_BADID));
    880 
    881 	kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
    882 	root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
    883 	vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
    884 
    885 	if (kind != CTF_K_ENUM)
    886 		return (ctf_set_errno(fp, ECTF_NOTENUM));
    887 
    888 	if (vlen == CTF_MAX_VLEN)
    889 		return (ctf_set_errno(fp, ECTF_DTFULL));
    890 
    891 	for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    892 	    dmd != NULL; dmd = ctf_list_next(dmd)) {
    893 		if (strcmp(dmd->dmd_name, name) == 0)
    894 			return (ctf_set_errno(fp, ECTF_DUPMEMBER));
    895 	}
    896 
    897 	if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
    898 		return (ctf_set_errno(fp, EAGAIN));
    899 
    900 	if ((s = ctf_strdup(name)) == NULL) {
    901 		ctf_free(dmd, sizeof (ctf_dmdef_t));
    902 		return (ctf_set_errno(fp, EAGAIN));
    903 	}
    904 
    905 	dmd->dmd_name = s;
    906 	dmd->dmd_type = CTF_ERR;
    907 	dmd->dmd_offset = 0;
    908 	dmd->dmd_value = value;
    909 
    910 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
    911 	ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
    912 
    913 	fp->ctf_dtstrlen += strlen(s) + 1;
    914 	fp->ctf_flags |= LCTF_DIRTY;
    915 
    916 	return (0);
    917 }
    918 
    919 int
    920 ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
    921 {
    922 	ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, souid);
    923 	ctf_dmdef_t *dmd;
    924 
    925 	ssize_t msize, malign, ssize;
    926 	uint_t kind, vlen, root;
    927 	char *s = NULL;
    928 
    929 	if (!(fp->ctf_flags & LCTF_RDWR))
    930 		return (ctf_set_errno(fp, ECTF_RDONLY));
    931 
    932 	if (dtd == NULL)
    933 		return (ctf_set_errno(fp, ECTF_BADID));
    934 
    935 	kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
    936 	root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
    937 	vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
    938 
    939 	if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
    940 		return (ctf_set_errno(fp, ECTF_NOTSOU));
    941 
    942 	if (vlen == CTF_MAX_VLEN)
    943 		return (ctf_set_errno(fp, ECTF_DTFULL));
    944 
    945 	if (name != NULL) {
    946 		for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
    947 		    dmd != NULL; dmd = ctf_list_next(dmd)) {
    948 			if (dmd->dmd_name != NULL &&
    949 			    strcmp(dmd->dmd_name, name) == 0)
    950 				return (ctf_set_errno(fp, ECTF_DUPMEMBER));
    951 		}
    952 	}
    953 
    954 	if ((msize = ctf_type_size(fp, type)) == CTF_ERR ||
    955 	    (malign = ctf_type_align(fp, type)) == CTF_ERR)
    956 		return (CTF_ERR); /* errno is set for us */
    957 
    958 	if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
    959 		return (ctf_set_errno(fp, EAGAIN));
    960 
    961 	if (name != NULL && (s = ctf_strdup(name)) == NULL) {
    962 		ctf_free(dmd, sizeof (ctf_dmdef_t));
    963 		return (ctf_set_errno(fp, EAGAIN));
    964 	}
    965 
    966 	dmd->dmd_name = s;
    967 	dmd->dmd_type = type;
    968 	dmd->dmd_value = -1;
    969 
    970 	if (kind == CTF_K_STRUCT && vlen != 0) {
    971 		ctf_dmdef_t *lmd = ctf_list_prev(&dtd->dtd_u.dtu_members);
    972 		ctf_id_t ltype = ctf_type_resolve(fp, lmd->dmd_type);
    973 		size_t off = lmd->dmd_offset;
    974 
    975 		ctf_encoding_t linfo;
    976 		ssize_t lsize;
    977 
    978 		if (ctf_type_encoding(fp, ltype, &linfo) != CTF_ERR)
    979 			off += linfo.cte_bits;
    980 		else if ((lsize = ctf_type_size(fp, ltype)) != CTF_ERR)
    981 			off += lsize * NBBY;
    982 
    983 		/*
    984 		 * Round up the offset of the end of the last member to the
    985 		 * next byte boundary, convert 'off' to bytes, and then round
    986 		 * it up again to the next multiple of the alignment required
    987 		 * by the new member.  Finally, convert back to bits and store
    988 		 * the result in dmd_offset.  Technically we could do more
    989 		 * efficient packing if the new member is a bit-field, but
    990 		 * we're the "compiler" and ANSI says we can do as we choose.
    991 		 */
    992 		off = roundup(off, NBBY) / NBBY;
    993 		off = roundup(off, MAX(malign, 1));
    994 		dmd->dmd_offset = off * NBBY;
    995 		ssize = off + msize;
    996 	} else {
    997 		dmd->dmd_offset = 0;
    998 		ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
    999 		ssize = MAX(ssize, msize);
   1000 	}
   1001 
   1002 	if (ssize > CTF_MAX_SIZE) {
   1003 		dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
   1004 		dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
   1005 		dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
   1006 	} else
   1007 		dtd->dtd_data.ctt_size = (ushort_t)ssize;
   1008 
   1009 	dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
   1010 	ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
   1011 
   1012 	if (s != NULL)
   1013 		fp->ctf_dtstrlen += strlen(s) + 1;
   1014 
   1015 	fp->ctf_flags |= LCTF_DIRTY;
   1016 	return (0);
   1017 }
   1018 
   1019 static int
   1020 enumcmp(const char *name, int value, void *arg)
   1021 {
   1022 	ctf_bundle_t *ctb = arg;
   1023 	int bvalue;
   1024 
   1025 	return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type,
   1026 	    name, &bvalue) == CTF_ERR || value != bvalue);
   1027 }
   1028 
   1029 static int
   1030 enumadd(const char *name, int value, void *arg)
   1031 {
   1032 	ctf_bundle_t *ctb = arg;
   1033 
   1034 	return (ctf_add_enumerator(ctb->ctb_file, ctb->ctb_type,
   1035 	    name, value) == CTF_ERR);
   1036 }
   1037 
   1038 /*ARGSUSED*/
   1039 static int
   1040 membcmp(const char *name, ctf_id_t type, ulong_t offset, void *arg)
   1041 {
   1042 	ctf_bundle_t *ctb = arg;
   1043 	ctf_membinfo_t ctm;
   1044 
   1045 	return (ctf_member_info(ctb->ctb_file, ctb->ctb_type,
   1046 	    name, &ctm) == CTF_ERR || ctm.ctm_offset != offset);
   1047 }
   1048 
   1049 static int
   1050 membadd(const char *name, ctf_id_t type, ulong_t offset, void *arg)
   1051 {
   1052 	ctf_bundle_t *ctb = arg;
   1053 	ctf_dmdef_t *dmd;
   1054 	char *s = NULL;
   1055 
   1056 	if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
   1057 		return (ctf_set_errno(ctb->ctb_file, EAGAIN));
   1058 
   1059 	if (name != NULL && (s = ctf_strdup(name)) == NULL) {
   1060 		ctf_free(dmd, sizeof (ctf_dmdef_t));
   1061 		return (ctf_set_errno(ctb->ctb_file, EAGAIN));
   1062 	}
   1063 
   1064 	/*
   1065 	 * For now, dmd_type is copied as the src_fp's type; it is reset to an
   1066 	 * equivalent dst_fp type by a final loop in ctf_add_type(), below.
   1067 	 */
   1068 	dmd->dmd_name = s;
   1069 	dmd->dmd_type = type;
   1070 	dmd->dmd_offset = offset;
   1071 	dmd->dmd_value = -1;
   1072 
   1073 	ctf_list_append(&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
   1074 
   1075 	if (s != NULL)
   1076 		ctb->ctb_file->ctf_dtstrlen += strlen(s) + 1;
   1077 
   1078 	ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
   1079 	return (0);
   1080 }
   1081 
   1082 /*
   1083  * The ctf_add_type routine is used to copy a type from a source CTF container
   1084  * to a dynamic destination container.  This routine operates recursively by
   1085  * following the source type's links and embedded member types.  If the
   1086  * destination container already contains a named type which has the same
   1087  * attributes, then we succeed and return this type but no changes occur.
   1088  */
   1089 ctf_id_t
   1090 ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
   1091 {
   1092 	ctf_id_t dst_type = CTF_ERR;
   1093 	uint_t dst_kind = CTF_K_UNKNOWN;
   1094 
   1095 	const ctf_type_t *tp;
   1096 	const char *name;
   1097 	uint_t kind, flag, vlen;
   1098 
   1099 	ctf_bundle_t src, dst;
   1100 	ctf_encoding_t src_en, dst_en;
   1101 	ctf_arinfo_t src_ar, dst_ar;
   1102 
   1103 	ctf_dtdef_t *dtd;
   1104 	ctf_funcinfo_t ctc;
   1105 	ssize_t size;
   1106 
   1107 	ctf_hash_t *hp;
   1108 	ctf_helem_t *hep;
   1109 
   1110 	if (!(dst_fp->ctf_flags & LCTF_RDWR))
   1111 		return (ctf_set_errno(dst_fp, ECTF_RDONLY));
   1112 
   1113 	if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
   1114 		return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
   1115 
   1116 	name = ctf_strptr(src_fp, tp->ctt_name);
   1117 	kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
   1118 	flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
   1119 	vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
   1120 
   1121 	switch (kind) {
   1122 	case CTF_K_STRUCT:
   1123 		hp = &dst_fp->ctf_structs;
   1124 		break;
   1125 	case CTF_K_UNION:
   1126 		hp = &dst_fp->ctf_unions;
   1127 		break;
   1128 	case CTF_K_ENUM:
   1129 		hp = &dst_fp->ctf_enums;
   1130 		break;
   1131 	default:
   1132 		hp = &dst_fp->ctf_names;
   1133 		break;
   1134 	}
   1135 
   1136 	/*
   1137 	 * If the source type has a name and is a root type (visible at the
   1138 	 * top-level scope), lookup the name in the destination container and
   1139 	 * verify that it is of the same kind before we do anything else.
   1140 	 */
   1141 	if ((flag & CTF_ADD_ROOT) && name[0] != '\0' &&
   1142 	    (hep = ctf_hash_lookup(hp, dst_fp, name, strlen(name))) != NULL) {
   1143 		dst_type = (ctf_id_t)hep->h_type;
   1144 		dst_kind = ctf_type_kind(dst_fp, dst_type);
   1145 	}
   1146 
   1147 	/*
   1148 	 * If an identically named dst_type exists, fail with ECTF_CONFLICT
   1149 	 * unless dst_type is a forward declaration and src_type is a struct,
   1150 	 * union, or enum (i.e. the definition of the previous forward decl).
   1151 	 */
   1152 	if (dst_type != CTF_ERR && dst_kind != kind && (
   1153 	    dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM &&
   1154 	    kind != CTF_K_STRUCT && kind != CTF_K_UNION)))
   1155 		return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1156 
   1157 	/*
   1158 	 * If the non-empty name was not found in the appropriate hash, search
   1159 	 * the list of pending dynamic definitions that are not yet committed.
   1160 	 * If a matching name and kind are found, assume this is the type that
   1161 	 * we are looking for.  This is necessary to permit ctf_add_type() to
   1162 	 * operate recursively on entities such as a struct that contains a
   1163 	 * pointer member that refers to the same struct type.
   1164 	 */
   1165 	if (dst_type == CTF_ERR && name[0] != '\0') {
   1166 		for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL &&
   1167 		    dtd->dtd_type > dst_fp->ctf_dtoldid;
   1168 		    dtd = ctf_list_prev(dtd)) {
   1169 			if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) == kind &&
   1170 			    dtd->dtd_name != NULL &&
   1171 			    strcmp(dtd->dtd_name, name) == 0)
   1172 				return (dtd->dtd_type);
   1173 		}
   1174 	}
   1175 
   1176 	src.ctb_file = src_fp;
   1177 	src.ctb_type = src_type;
   1178 	src.ctb_dtd = NULL;
   1179 
   1180 	dst.ctb_file = dst_fp;
   1181 	dst.ctb_type = dst_type;
   1182 	dst.ctb_dtd = NULL;
   1183 
   1184 	/*
   1185 	 * Now perform kind-specific processing.  If dst_type is CTF_ERR, then
   1186 	 * we add a new type with the same properties as src_type to dst_fp.
   1187 	 * If dst_type is not CTF_ERR, then we verify that dst_type has the
   1188 	 * same attributes as src_type.  We recurse for embedded references.
   1189 	 */
   1190 	switch (kind) {
   1191 	case CTF_K_INTEGER:
   1192 	case CTF_K_FLOAT:
   1193 		if (ctf_type_encoding(src_fp, src_type, &src_en) != 0)
   1194 			return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
   1195 
   1196 		if (dst_type != CTF_ERR) {
   1197 			if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0)
   1198 				return (CTF_ERR); /* errno is set for us */
   1199 
   1200 			if (bcmp(&src_en, &dst_en, sizeof (ctf_encoding_t)))
   1201 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1202 
   1203 		} else if (kind == CTF_K_INTEGER) {
   1204 			dst_type = ctf_add_integer(dst_fp, flag, name, &src_en);
   1205 		} else
   1206 			dst_type = ctf_add_float(dst_fp, flag, name, &src_en);
   1207 		break;
   1208 
   1209 	case CTF_K_POINTER:
   1210 	case CTF_K_VOLATILE:
   1211 	case CTF_K_CONST:
   1212 	case CTF_K_RESTRICT:
   1213 		src_type = ctf_type_reference(src_fp, src_type);
   1214 		src_type = ctf_add_type(dst_fp, src_fp, src_type);
   1215 
   1216 		if (src_type == CTF_ERR)
   1217 			return (CTF_ERR); /* errno is set for us */
   1218 
   1219 		dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind);
   1220 		break;
   1221 
   1222 	case CTF_K_ARRAY:
   1223 		if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR)
   1224 			return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
   1225 
   1226 		src_ar.ctr_contents =
   1227 		    ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents);
   1228 		src_ar.ctr_index =
   1229 		    ctf_add_type(dst_fp, src_fp, src_ar.ctr_index);
   1230 		src_ar.ctr_nelems = src_ar.ctr_nelems;
   1231 
   1232 		if (src_ar.ctr_contents == CTF_ERR ||
   1233 		    src_ar.ctr_index == CTF_ERR)
   1234 			return (CTF_ERR); /* errno is set for us */
   1235 
   1236 		if (dst_type != CTF_ERR) {
   1237 			if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0)
   1238 				return (CTF_ERR); /* errno is set for us */
   1239 
   1240 			if (bcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
   1241 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1242 		} else
   1243 			dst_type = ctf_add_array(dst_fp, flag, &src_ar);
   1244 		break;
   1245 
   1246 	case CTF_K_FUNCTION:
   1247 		ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type);
   1248 		ctc.ctc_argc = 0;
   1249 		ctc.ctc_flags = 0;
   1250 
   1251 		if (ctc.ctc_return == CTF_ERR)
   1252 			return (CTF_ERR); /* errno is set for us */
   1253 
   1254 		dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL);
   1255 		break;
   1256 
   1257 	case CTF_K_STRUCT:
   1258 	case CTF_K_UNION: {
   1259 		ctf_dmdef_t *dmd;
   1260 		int errs = 0;
   1261 
   1262 		/*
   1263 		 * Technically to match a struct or union we need to check both
   1264 		 * ways (src members vs. dst, dst members vs. src) but we make
   1265 		 * this more optimal by only checking src vs. dst and comparing
   1266 		 * the total size of the structure (which we must do anyway)
   1267 		 * which covers the possibility of dst members not in src.
   1268 		 * This optimization can be defeated for unions, but is so
   1269 		 * pathological as to render it irrelevant for our purposes.
   1270 		 */
   1271 		if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
   1272 			if (ctf_type_size(src_fp, src_type) !=
   1273 			    ctf_type_size(dst_fp, dst_type))
   1274 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1275 
   1276 			if (ctf_member_iter(src_fp, src_type, membcmp, &dst))
   1277 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1278 
   1279 			break;
   1280 		}
   1281 
   1282 		/*
   1283 		 * Unlike the other cases, copying structs and unions is done
   1284 		 * manually so as to avoid repeated lookups in ctf_add_member
   1285 		 * and to ensure the exact same member offsets as in src_type.
   1286 		 */
   1287 		dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
   1288 		if (dst_type == CTF_ERR)
   1289 			return (CTF_ERR); /* errno is set for us */
   1290 
   1291 		dst.ctb_type = dst_type;
   1292 		dst.ctb_dtd = dtd;
   1293 
   1294 		if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
   1295 			errs++; /* increment errs and fail at bottom of case */
   1296 
   1297 		if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
   1298 			dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
   1299 			dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
   1300 			dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
   1301 		} else
   1302 			dtd->dtd_data.ctt_size = (ushort_t)size;
   1303 
   1304 		dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
   1305 
   1306 		/*
   1307 		 * Make a final pass through the members changing each dmd_type
   1308 		 * (a src_fp type) to an equivalent type in dst_fp.  We pass
   1309 		 * through all members, leaving any that fail set to CTF_ERR.
   1310 		 */
   1311 		for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
   1312 		    dmd != NULL; dmd = ctf_list_next(dmd)) {
   1313 			if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
   1314 			    dmd->dmd_type)) == CTF_ERR)
   1315 				errs++;
   1316 		}
   1317 
   1318 		if (errs)
   1319 			return (CTF_ERR); /* errno is set for us */
   1320 		break;
   1321 	}
   1322 
   1323 	case CTF_K_ENUM:
   1324 		if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
   1325 			if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
   1326 			    ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
   1327 				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
   1328 		} else {
   1329 			dst_type = ctf_add_enum(dst_fp, flag, name);
   1330 			if ((dst.ctb_type = dst_type) == CTF_ERR ||
   1331 			    ctf_enum_iter(src_fp, src_type, enumadd, &dst))
   1332 				return (CTF_ERR); /* errno is set for us */
   1333 		}
   1334 		break;
   1335 
   1336 	case CTF_K_FORWARD:
   1337 		if (dst_type == CTF_ERR) {
   1338 			dst_type = ctf_add_forward(dst_fp,
   1339 			    flag, name, CTF_K_STRUCT); /* assume STRUCT */
   1340 		}
   1341 		break;
   1342 
   1343 	case CTF_K_TYPEDEF:
   1344 		src_type = ctf_type_reference(src_fp, src_type);
   1345 		src_type = ctf_add_type(dst_fp, src_fp, src_type);
   1346 
   1347 		if (src_type == CTF_ERR)
   1348 			return (CTF_ERR); /* errno is set for us */
   1349 
   1350 		/*
   1351 		 * If dst_type is not CTF_ERR at this point, we should check if
   1352 		 * ctf_type_reference(dst_fp, dst_type) != src_type and if so
   1353 		 * fail with ECTF_CONFLICT.  However, this causes problems with
   1354 		 * <sys/types.h> typedefs that vary based on things like if
   1355 		 * _ILP32x then pid_t is int otherwise long.  We therefore omit
   1356 		 * this check and assume that if the identically named typedef
   1357 		 * already exists in dst_fp, it is correct or equivalent.
   1358 		 */
   1359 		if (dst_type == CTF_ERR) {
   1360 			dst_type = ctf_add_typedef(dst_fp, flag,
   1361 			    name, src_type);
   1362 		}
   1363 		break;
   1364 
   1365 	default:
   1366 		return (ctf_set_errno(dst_fp, ECTF_CORRUPT));
   1367 	}
   1368 
   1369 	return (dst_type);
   1370 }
   1371