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