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