]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - cddl/contrib/opensolaris/common/ctf/ctf_create.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / cddl / contrib / opensolaris / common / ctf / ctf_create.c
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 }