xref: /netbsd-src/external/cddl/osnet/dist/common/ctf/ctf_create.c (revision f89f6560d453f5e37386cc7938c072d2f528b9fa)
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