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