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