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