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