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