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 */
43static 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 */
52ctf_file_t *
53ctf_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 = (void *)&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
89static uchar_t *
90ctf_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
112static uchar_t *
113ctf_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
137static uchar_t *
138ctf_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
154static uchar_t *
155ctf_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 */
183static void
184ctf_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 */
201static void
202ctf_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 */
235int
236ctf_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
469void
470ctf_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
479void
480ctf_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
549ctf_dtdef_t *
550ctf_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 */
574int
575ctf_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		ntd = ctf_list_prev(dtd);
587		if (CTF_TYPE_TO_INDEX(dtd->dtd_type) <= fp->ctf_dtoldid)
588			continue; /* skip types that have been committed */
589
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
599static ctf_id_t
600ctf_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 */
645static size_t
646clp2(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
659static ctf_id_t
660ctf_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
679static ctf_id_t
680ctf_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
699ctf_id_t
700ctf_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
706ctf_id_t
707ctf_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
713ctf_id_t
714ctf_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
719ctf_id_t
720ctf_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
751int
752ctf_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
783ctf_id_t
784ctf_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
840ctf_id_t
841ctf_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
862ctf_id_t
863ctf_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
884ctf_id_t
885ctf_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
906ctf_id_t
907ctf_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
945ctf_id_t
946ctf_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
967ctf_id_t
968ctf_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
973ctf_id_t
974ctf_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
979ctf_id_t
980ctf_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
985int
986ctf_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
1041int
1042ctf_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 */
1150int
1151ctf_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
1180static int
1181enumcmp(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
1190static int
1191enumadd(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*/
1200static int
1201membcmp(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
1210static int
1211membadd(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 */
1250ctf_id_t
1251ctf_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		if (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		else
1321			dst_type = CTF_ERR;
1322	}
1323
1324	/*
1325	 * If the non-empty name was not found in the appropriate hash, search
1326	 * the list of pending dynamic definitions that are not yet committed.
1327	 * If a matching name and kind are found, assume this is the type that
1328	 * we are looking for.  This is necessary to permit ctf_add_type() to
1329	 * operate recursively on entities such as a struct that contains a
1330	 * pointer member that refers to the same struct type.
1331	 *
1332	 * In the case of integer and floating point types, we match using the
1333	 * type encoding as well - else we may incorrectly return a bitfield
1334	 * type, for instance.
1335	 */
1336	if (dst_type == CTF_ERR && name[0] != '\0') {
1337		for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL &&
1338		    CTF_TYPE_TO_INDEX(dtd->dtd_type) > dst_fp->ctf_dtoldid;
1339		    dtd = ctf_list_prev(dtd)) {
1340			if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != kind ||
1341			    dtd->dtd_name == NULL ||
1342			    strcmp(dtd->dtd_name, name) != 0)
1343				continue;
1344			if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT) {
1345				if (ctf_type_encoding(src_fp, src_type,
1346				    &src_en) != 0)
1347					continue;
1348				if (bcmp(&src_en, &dtd->dtd_u.dtu_enc,
1349				    sizeof (ctf_encoding_t)) != 0)
1350					continue;
1351			}
1352			return (dtd->dtd_type);
1353		}
1354	}
1355
1356	src.ctb_file = src_fp;
1357	src.ctb_type = src_type;
1358	src.ctb_dtd = NULL;
1359
1360	dst.ctb_file = dst_fp;
1361	dst.ctb_type = dst_type;
1362	dst.ctb_dtd = NULL;
1363
1364	/*
1365	 * Now perform kind-specific processing.  If dst_type is CTF_ERR, then
1366	 * we add a new type with the same properties as src_type to dst_fp.
1367	 * If dst_type is not CTF_ERR, then we verify that dst_type has the
1368	 * same attributes as src_type.  We recurse for embedded references.
1369	 */
1370	switch (kind) {
1371	case CTF_K_INTEGER:
1372	case CTF_K_FLOAT:
1373		if (ctf_type_encoding(src_fp, src_type, &src_en) != 0)
1374			return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1375
1376		if (dst_type != CTF_ERR) {
1377			if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0)
1378				return (CTF_ERR); /* errno is set for us */
1379
1380			if (bcmp(&src_en, &dst_en, sizeof (ctf_encoding_t)))
1381				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1382
1383		} else if (kind == CTF_K_INTEGER) {
1384			dst_type = ctf_add_integer(dst_fp, flag, name, &src_en);
1385		} else
1386			dst_type = ctf_add_float(dst_fp, flag, name, &src_en);
1387		break;
1388
1389	case CTF_K_POINTER:
1390	case CTF_K_VOLATILE:
1391	case CTF_K_CONST:
1392	case CTF_K_RESTRICT:
1393		src_type = ctf_type_reference(src_fp, src_type);
1394		src_type = ctf_add_type(dst_fp, src_fp, src_type);
1395
1396		if (src_type == CTF_ERR)
1397			return (CTF_ERR); /* errno is set for us */
1398
1399		dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind);
1400		break;
1401
1402	case CTF_K_ARRAY:
1403		if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR)
1404			return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1405
1406		src_ar.ctr_contents =
1407		    ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents);
1408		src_ar.ctr_index =
1409		    ctf_add_type(dst_fp, src_fp, src_ar.ctr_index);
1410		src_ar.ctr_nelems = src_ar.ctr_nelems;
1411
1412		if (src_ar.ctr_contents == CTF_ERR ||
1413		    src_ar.ctr_index == CTF_ERR)
1414			return (CTF_ERR); /* errno is set for us */
1415
1416		if (dst_type != CTF_ERR) {
1417			if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0)
1418				return (CTF_ERR); /* errno is set for us */
1419
1420			if (bcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1421				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1422		} else
1423			dst_type = ctf_add_array(dst_fp, flag, &src_ar);
1424		break;
1425
1426	case CTF_K_FUNCTION:
1427		ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type);
1428		ctc.ctc_argc = 0;
1429		ctc.ctc_flags = 0;
1430
1431		if (ctc.ctc_return == CTF_ERR)
1432			return (CTF_ERR); /* errno is set for us */
1433
1434		dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL);
1435		break;
1436
1437	case CTF_K_STRUCT:
1438	case CTF_K_UNION: {
1439		ctf_dmdef_t *dmd;
1440		int errs = 0;
1441
1442		/*
1443		 * Technically to match a struct or union we need to check both
1444		 * ways (src members vs. dst, dst members vs. src) but we make
1445		 * this more optimal by only checking src vs. dst and comparing
1446		 * the total size of the structure (which we must do anyway)
1447		 * which covers the possibility of dst members not in src.
1448		 * This optimization can be defeated for unions, but is so
1449		 * pathological as to render it irrelevant for our purposes.
1450		 */
1451		if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1452			if (ctf_type_size(src_fp, src_type) !=
1453			    ctf_type_size(dst_fp, dst_type))
1454				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1455
1456			if (ctf_member_iter(src_fp, src_type, membcmp, &dst))
1457				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1458
1459			break;
1460		}
1461
1462		/*
1463		 * Unlike the other cases, copying structs and unions is done
1464		 * manually so as to avoid repeated lookups in ctf_add_member
1465		 * and to ensure the exact same member offsets as in src_type.
1466		 */
1467		dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1468		if (dst_type == CTF_ERR)
1469			return (CTF_ERR); /* errno is set for us */
1470
1471		dst.ctb_type = dst_type;
1472		dst.ctb_dtd = dtd;
1473
1474		if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1475			errs++; /* increment errs and fail at bottom of case */
1476
1477		if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
1478			dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1479			dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1480			dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1481		} else
1482			dtd->dtd_data.ctt_size = (ushort_t)size;
1483
1484		dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
1485
1486		/*
1487		 * Make a final pass through the members changing each dmd_type
1488		 * (a src_fp type) to an equivalent type in dst_fp.  We pass
1489		 * through all members, leaving any that fail set to CTF_ERR.
1490		 */
1491		for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1492		    dmd != NULL; dmd = ctf_list_next(dmd)) {
1493			if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1494			    dmd->dmd_type)) == CTF_ERR)
1495				errs++;
1496		}
1497
1498		if (errs)
1499			return (CTF_ERR); /* errno is set for us */
1500
1501		/*
1502		 * Now that we know that we can't fail, we go through and bump
1503		 * all the reference counts on the member types.
1504		 */
1505		for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1506		    dmd != NULL; dmd = ctf_list_next(dmd))
1507			ctf_ref_inc(dst_fp, dmd->dmd_type);
1508		break;
1509	}
1510
1511	case CTF_K_ENUM:
1512		if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1513			if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1514			    ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1515				return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1516		} else {
1517			dst_type = ctf_add_enum(dst_fp, flag, name);
1518			if ((dst.ctb_type = dst_type) == CTF_ERR ||
1519			    ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1520				return (CTF_ERR); /* errno is set for us */
1521		}
1522		break;
1523
1524	case CTF_K_FORWARD:
1525		if (dst_type == CTF_ERR) {
1526			dst_type = ctf_add_forward(dst_fp,
1527			    flag, name, CTF_K_STRUCT); /* assume STRUCT */
1528		}
1529		break;
1530
1531	case CTF_K_TYPEDEF:
1532		src_type = ctf_type_reference(src_fp, src_type);
1533		src_type = ctf_add_type(dst_fp, src_fp, src_type);
1534
1535		if (src_type == CTF_ERR)
1536			return (CTF_ERR); /* errno is set for us */
1537
1538		/*
1539		 * If dst_type is not CTF_ERR at this point, we should check if
1540		 * ctf_type_reference(dst_fp, dst_type) != src_type and if so
1541		 * fail with ECTF_CONFLICT.  However, this causes problems with
1542		 * <sys/types.h> typedefs that vary based on things like if
1543		 * _ILP32x then pid_t is int otherwise long.  We therefore omit
1544		 * this check and assume that if the identically named typedef
1545		 * already exists in dst_fp, it is correct or equivalent.
1546		 */
1547		if (dst_type == CTF_ERR) {
1548			dst_type = ctf_add_typedef(dst_fp, flag,
1549			    name, src_type);
1550		}
1551		break;
1552
1553	default:
1554		return (ctf_set_errno(dst_fp, ECTF_CORRUPT));
1555	}
1556
1557	return (dst_type);
1558}
1559