2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include <sys/param.h>
27 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
30 /* To create an empty CTF container, we just declare a zeroed header and call
31 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
32 and initialize the dynamic members. We set dtvstrlen to 1 to reserve the
33 first byte of the string table for a \0 byte, and we start assigning type
34 IDs at 1 because type ID 0 is used as a sentinel and a not-found
38 ctf_create (int *errp)
40 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
42 ctf_dynhash_t *dthash;
43 ctf_dynhash_t *dvhash;
44 ctf_dynhash_t *dtbyname;
49 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
53 ctf_set_open_errno (errp, EAGAIN);
57 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
61 ctf_set_open_errno (errp, EAGAIN);
65 dtbyname = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
69 ctf_set_open_errno (errp, EAGAIN);
73 cts.cts_name = _CTF_SECTION;
75 cts.cts_size = sizeof (hdr);
78 if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
81 fp->ctf_flags |= LCTF_RDWR;
82 fp->ctf_dtbyname = dtbyname;
83 fp->ctf_dthash = dthash;
84 fp->ctf_dvhash = dvhash;
85 fp->ctf_dtvstrlen = 1;
88 fp->ctf_snapshots = 0;
89 fp->ctf_snapshot_lu = 0;
94 ctf_dynhash_destroy (dtbyname);
96 ctf_dynhash_destroy (dvhash);
98 ctf_dynhash_destroy (dthash);
103 static unsigned char *
104 ctf_copy_smembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
106 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
109 for (; dmd != NULL; dmd = ctf_list_next (dmd))
114 soff += strlen (dmd->dmd_name) + 1;
119 ctm.ctm_type = (uint32_t) dmd->dmd_type;
120 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
122 memcpy (t, &ctm, sizeof (ctm));
129 static unsigned char *
130 ctf_copy_lmembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
132 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
135 for (; dmd != NULL; dmd = ctf_list_next (dmd))
139 ctlm.ctlm_name = soff;
140 soff += strlen (dmd->dmd_name) + 1;
145 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
146 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
147 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
149 memcpy (t, &ctlm, sizeof (ctlm));
156 static unsigned char *
157 ctf_copy_emembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
159 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
162 for (; dmd != NULL; dmd = ctf_list_next (dmd))
165 cte.cte_value = dmd->dmd_value;
166 soff += strlen (dmd->dmd_name) + 1;
167 memcpy (t, &cte, sizeof (cte));
174 static unsigned char *
175 ctf_copy_membnames (ctf_dtdef_t *dtd, unsigned char *s)
177 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
180 for (; dmd != NULL; dmd = ctf_list_next (dmd))
182 if (dmd->dmd_name == NULL)
183 continue; /* Skip anonymous members. */
184 len = strlen (dmd->dmd_name) + 1;
185 memcpy (s, dmd->dmd_name, len);
192 /* Sort a newly-constructed static variable array. */
195 ctf_sort_var (const void *one_, const void *two_, void *strtab_)
197 const ctf_varent_t *one = one_;
198 const ctf_varent_t *two = two_;
199 const char *strtab = strtab_;
200 const char *n1 = strtab + CTF_NAME_OFFSET (one->ctv_name);
201 const char *n2 = strtab + CTF_NAME_OFFSET (two->ctv_name);
203 return (strcmp (n1, n2));
206 /* If the specified CTF container is writable and has been modified, reload this
207 container with the updated type definitions. In order to make this code and
208 the rest of libctf as simple as possible, we perform updates by taking the
209 dynamic type definitions and creating an in-memory CTF file containing the
210 definitions, and then call ctf_simple_open() on it. This not only leverages
211 ctf_simple_open(), but also avoids having to bifurcate the rest of the library
212 code with different lookup paths for static and dynamic type definitions. We
213 are therefore optimizing greatly for lookup over update, which we assume will
214 be an uncommon operation. We perform one extra trick here for the benefit of
215 callers and to keep our code simple: ctf_simple_open() will return a new
216 ctf_file_t, but we want to keep the fp constant for the caller, so after
217 ctf_simple_open() returns, we use memcpy to swap the interior of the old and
218 new ctf_file_t's, and then free the old. */
220 ctf_update (ctf_file_t *fp)
222 ctf_file_t ofp, *nfp;
226 ctf_varent_t *dvarents;
228 unsigned char *s, *s0, *t;
230 size_t buf_size, type_size, nvars;
234 if (!(fp->ctf_flags & LCTF_RDWR))
235 return (ctf_set_errno (fp, ECTF_RDONLY));
237 /* Update required? */
238 if (!(fp->ctf_flags & LCTF_DIRTY))
241 /* Fill in an initial CTF header. We will leave the label, object,
242 and function sections empty and only output a header, type section,
243 and string table. The type section begins at a 4-byte aligned
244 boundary past the CTF header itself (at relative offset zero). */
246 memset (&hdr, 0, sizeof (hdr));
247 hdr.cth_magic = CTF_MAGIC;
248 hdr.cth_version = CTF_VERSION;
250 if (fp->ctf_flags & LCTF_CHILD)
251 hdr.cth_parname = 1; /* parname added just below. */
253 /* Iterate through the dynamic type definition list and compute the
254 size of the CTF type section we will need to generate. */
256 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
257 dtd != NULL; dtd = ctf_list_next (dtd))
259 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
260 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
262 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
263 type_size += sizeof (ctf_stype_t);
265 type_size += sizeof (ctf_type_t);
271 type_size += sizeof (uint32_t);
274 type_size += sizeof (ctf_array_t);
277 type_size += sizeof (ctf_slice_t);
280 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
284 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
285 type_size += sizeof (ctf_member_t) * vlen;
287 type_size += sizeof (ctf_lmember_t) * vlen;
290 type_size += sizeof (ctf_enum_t) * vlen;
295 /* Computing the number of entries in the CTF variable section is much
298 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
299 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
301 /* Fill in the string table and type offset and size, compute the size
302 of the entire CTF buffer we need, and then allocate a new buffer and
303 memcpy the finished header to the start of the buffer. */
305 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
306 hdr.cth_stroff = hdr.cth_typeoff + type_size;
307 hdr.cth_strlen = fp->ctf_dtvstrlen;
308 if (fp->ctf_parname != NULL)
309 hdr.cth_strlen += strlen (fp->ctf_parname) + 1;
311 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
313 if ((buf = ctf_data_alloc (buf_size)) == NULL)
314 return (ctf_set_errno (fp, EAGAIN));
316 memcpy (buf, &hdr, sizeof (ctf_header_t));
317 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff;
318 s = s0 = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff;
323 if (fp->ctf_parname != NULL)
325 memcpy (s, fp->ctf_parname, strlen (fp->ctf_parname) + 1);
326 s += strlen (fp->ctf_parname) + 1;
329 /* Work over the variable list, translating everything into
330 ctf_varent_t's and filling out the string table, then sort the buffer
331 of ctf_varent_t's. */
333 dvarents = (ctf_varent_t *) t;
334 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
335 dvd = ctf_list_next (dvd), i++)
337 ctf_varent_t *var = &dvarents[i];
338 size_t len = strlen (dvd->dvd_name) + 1;
340 var->ctv_name = (uint32_t) (s - s0);
341 var->ctv_type = dvd->dvd_type;
342 memcpy (s, dvd->dvd_name, len);
347 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
348 t += sizeof (ctf_varent_t) * nvars;
350 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
352 /* We now take a final lap through the dynamic type definition list and
353 copy the appropriate type records and strings to the output buffer. */
355 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
356 dtd != NULL; dtd = ctf_list_next (dtd))
359 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
360 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
366 if (dtd->dtd_name != NULL)
368 dtd->dtd_data.ctt_name = (uint32_t) (s - s0);
369 len = strlen (dtd->dtd_name) + 1;
370 memcpy (s, dtd->dtd_name, len);
374 dtd->dtd_data.ctt_name = 0;
376 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
377 len = sizeof (ctf_stype_t);
379 len = sizeof (ctf_type_t);
381 memcpy (t, &dtd->dtd_data, len);
388 if (kind == CTF_K_INTEGER)
390 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
391 dtd->dtd_u.dtu_enc.cte_offset,
392 dtd->dtd_u.dtu_enc.cte_bits);
396 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
397 dtd->dtd_u.dtu_enc.cte_offset,
398 dtd->dtd_u.dtu_enc.cte_bits);
400 memcpy (t, &encoding, sizeof (encoding));
401 t += sizeof (encoding);
405 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
406 t += sizeof (struct ctf_slice);
410 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
411 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
412 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
413 memcpy (t, &cta, sizeof (cta));
419 uint32_t *argv = (uint32_t *) (uintptr_t) t;
422 for (argc = 0; argc < vlen; argc++)
423 *argv++ = (uint32_t) dtd->dtd_u.dtu_argv[argc];
426 *argv++ = 0; /* Pad to 4-byte boundary. */
428 t = (unsigned char *) argv;
434 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
435 t = ctf_copy_smembers (dtd, (uint32_t) (s - s0), t);
437 t = ctf_copy_lmembers (dtd, (uint32_t) (s - s0), t);
438 s = ctf_copy_membnames (dtd, s);
442 t = ctf_copy_emembers (dtd, (uint32_t) (s - s0), t);
443 s = ctf_copy_membnames (dtd, s);
447 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
449 /* Finally, we are ready to ctf_simple_open() the new container. If this
450 is successful, we then switch nfp and fp and free the old container. */
452 ctf_data_protect (buf, buf_size);
454 if ((nfp = ctf_simple_open (buf, buf_size, NULL, 0, 0, NULL, 0, &err)) == NULL)
456 ctf_data_free (buf, buf_size);
457 return (ctf_set_errno (fp, err));
460 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
461 (void) ctf_import (nfp, fp->ctf_parent);
463 nfp->ctf_refcnt = fp->ctf_refcnt;
464 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
465 nfp->ctf_data.cts_data = NULL; /* Force ctf_data_free() on close. */
466 nfp->ctf_dthash = fp->ctf_dthash;
467 nfp->ctf_dtdefs = fp->ctf_dtdefs;
468 nfp->ctf_dtbyname = fp->ctf_dtbyname;
469 nfp->ctf_dvhash = fp->ctf_dvhash;
470 nfp->ctf_dvdefs = fp->ctf_dvdefs;
471 nfp->ctf_dtvstrlen = fp->ctf_dtvstrlen;
472 nfp->ctf_dtnextid = fp->ctf_dtnextid;
473 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
474 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
475 nfp->ctf_specific = fp->ctf_specific;
477 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
479 fp->ctf_dtbyname = NULL;
480 fp->ctf_dthash = NULL;
481 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
483 fp->ctf_dvhash = NULL;
484 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
486 memcpy (&ofp, fp, sizeof (ctf_file_t));
487 memcpy (fp, nfp, sizeof (ctf_file_t));
488 memcpy (nfp, &ofp, sizeof (ctf_file_t));
490 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
491 array of type name prefixes and the corresponding ctf_dynhash to use.
492 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
494 fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
495 fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
496 fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
497 fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
499 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
500 ctf_file_close (nfp);
506 ctf_prefixed_name (int kind, const char *name)
513 prefixed = ctf_strdup ("struct ");
516 prefixed = ctf_strdup ("union ");
519 prefixed = ctf_strdup ("enum ");
522 prefixed = ctf_strdup ("");
525 prefixed = ctf_str_append (prefixed, name);
530 ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
532 ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd);
533 ctf_list_append (&fp->ctf_dtdefs, dtd);
536 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
537 ctf_dynhash_insert (fp->ctf_dtbyname, ctf_prefixed_name (kind,
544 ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
546 ctf_dmdef_t *dmd, *nmd;
547 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
549 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
556 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
557 dmd != NULL; dmd = nmd)
559 if (dmd->dmd_name != NULL)
561 fp->ctf_dtvstrlen -= strlen (dmd->dmd_name) + 1;
562 ctf_free (dmd->dmd_name);
564 nmd = ctf_list_next (dmd);
569 ctf_free (dtd->dtd_u.dtu_argv);
577 name = ctf_prefixed_name (kind, dtd->dtd_name);
578 ctf_dynhash_remove (fp->ctf_dtbyname, name);
581 fp->ctf_dtvstrlen -= strlen (dtd->dtd_name) + 1;
582 ctf_free (dtd->dtd_name);
585 ctf_list_delete (&fp->ctf_dtdefs, dtd);
590 ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
592 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
596 ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
599 char *decorated = ctf_prefixed_name (kind, name);
601 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
605 return dtd->dtd_type;
611 ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
615 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
618 idx = LCTF_TYPE_TO_INDEX(fp, id);
620 if (((unsigned long) idx > fp->ctf_typemax) &&
621 ((unsigned long) idx < fp->ctf_dtnextid))
622 return ctf_dtd_lookup (fp, id);
627 ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
629 ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd);
630 ctf_list_append (&fp->ctf_dvdefs, dvd);
634 ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
636 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
638 fp->ctf_dtvstrlen -= strlen (dvd->dvd_name) + 1;
639 ctf_free (dvd->dvd_name);
641 ctf_list_delete (&fp->ctf_dvdefs, dvd);
646 ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
648 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
651 /* Discard all of the dynamic type definitions and variable definitions that
652 have been added to the container since the last call to ctf_update(). We
653 locate such types by scanning the dtd list and deleting elements that have
654 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
655 by scanning the variable list and deleting elements that have update IDs
656 equal to the current value of the last-update snapshot count (indicating that
657 they were added after the most recent call to ctf_update()). */
659 ctf_discard (ctf_file_t *fp)
661 ctf_snapshot_id_t last_update =
663 fp->ctf_snapshot_lu + 1 };
665 /* Update required? */
666 if (!(fp->ctf_flags & LCTF_DIRTY))
669 return (ctf_rollback (fp, last_update));
673 ctf_snapshot (ctf_file_t *fp)
675 ctf_snapshot_id_t snapid;
676 snapid.dtd_id = fp->ctf_dtnextid - 1;
677 snapid.snapshot_id = fp->ctf_snapshots++;
681 /* Like ctf_discard(), only discards everything after a particular ID. */
683 ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
685 ctf_dtdef_t *dtd, *ntd;
686 ctf_dvdef_t *dvd, *nvd;
688 if (!(fp->ctf_flags & LCTF_RDWR))
689 return (ctf_set_errno (fp, ECTF_RDONLY));
691 if (fp->ctf_dtoldid > id.dtd_id)
692 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
694 if (fp->ctf_snapshot_lu >= id.snapshot_id)
695 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
697 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
699 ntd = ctf_list_next (dtd);
701 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
704 ctf_dtd_delete (fp, dtd);
707 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
709 nvd = ctf_list_next (dvd);
711 if (dvd->dvd_snapshots <= id.snapshot_id)
714 ctf_dvd_delete (fp, dvd);
717 fp->ctf_dtnextid = id.dtd_id + 1;
718 fp->ctf_snapshots = id.snapshot_id;
720 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
721 fp->ctf_flags &= ~LCTF_DIRTY;
727 ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
734 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
735 return (ctf_set_errno (fp, EINVAL));
737 if (!(fp->ctf_flags & LCTF_RDWR))
738 return (ctf_set_errno (fp, ECTF_RDONLY));
740 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
741 return (ctf_set_errno (fp, ECTF_FULL));
743 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
744 return (ctf_set_errno (fp, ECTF_FULL));
746 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
747 return (ctf_set_errno (fp, EAGAIN));
749 if (name != NULL && (s = ctf_strdup (name)) == NULL)
752 return (ctf_set_errno (fp, EAGAIN));
755 type = fp->ctf_dtnextid++;
756 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
758 memset (dtd, 0, sizeof (ctf_dtdef_t));
760 dtd->dtd_type = type;
763 fp->ctf_dtvstrlen += strlen (s) + 1;
765 ctf_dtd_insert (fp, dtd);
766 fp->ctf_flags |= LCTF_DIRTY;
772 /* When encoding integer sizes, we want to convert a byte count in the range
773 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
774 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
790 ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
791 const char *name, const ctf_encoding_t *ep, uint32_t kind)
797 return (ctf_set_errno (fp, EINVAL));
799 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
800 return CTF_ERR; /* errno is set for us. */
802 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
803 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
805 dtd->dtd_u.dtu_enc = *ep;
811 ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
815 ctf_file_t *tmp = fp;
817 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
818 return (ctf_set_errno (fp, EINVAL));
820 if (ctf_lookup_by_id (&tmp, ref) == NULL)
821 return CTF_ERR; /* errno is set for us. */
823 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
824 return CTF_ERR; /* errno is set for us. */
826 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
827 dtd->dtd_data.ctt_type = (uint32_t) ref;
833 ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
834 const ctf_encoding_t *ep)
839 const ctf_type_t *tp;
840 ctf_file_t *tmp = fp;
843 return (ctf_set_errno (fp, EINVAL));
845 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
846 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
848 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
849 return (ctf_set_errno (fp, EINVAL));
851 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
852 return CTF_ERR; /* errno is set for us. */
854 kind = ctf_type_kind_unsliced (tmp, ref);
855 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
856 (kind != CTF_K_ENUM))
857 return (ctf_set_errno (fp, ECTF_NOTINTFP));
859 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
860 return CTF_ERR; /* errno is set for us. */
862 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
863 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
865 dtd->dtd_u.dtu_slice.cts_type = ref;
866 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
867 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
873 ctf_add_integer (ctf_file_t *fp, uint32_t flag,
874 const char *name, const ctf_encoding_t *ep)
876 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
880 ctf_add_float (ctf_file_t *fp, uint32_t flag,
881 const char *name, const ctf_encoding_t *ep)
883 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
887 ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
889 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
893 ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
897 ctf_file_t *tmp = fp;
900 return (ctf_set_errno (fp, EINVAL));
902 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
903 return CTF_ERR; /* errno is set for us. */
906 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
907 return CTF_ERR; /* errno is set for us. */
909 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
910 return CTF_ERR; /* errno is set for us. */
912 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
913 dtd->dtd_data.ctt_size = 0;
914 dtd->dtd_u.dtu_arr = *arp;
920 ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
922 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
924 if (!(fp->ctf_flags & LCTF_RDWR))
925 return (ctf_set_errno (fp, ECTF_RDONLY));
928 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
929 return (ctf_set_errno (fp, ECTF_BADID));
931 fp->ctf_flags |= LCTF_DIRTY;
932 dtd->dtd_u.dtu_arr = *arp;
938 ctf_add_function (ctf_file_t *fp, uint32_t flag,
939 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
944 ctf_id_t *vdat = NULL;
945 ctf_file_t *tmp = fp;
948 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
949 || (ctc->ctc_argc != 0 && argv == NULL))
950 return (ctf_set_errno (fp, EINVAL));
952 vlen = ctc->ctc_argc;
953 if (ctc->ctc_flags & CTF_FUNC_VARARG)
954 vlen++; /* Add trailing zero to indicate varargs (see below). */
956 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
957 return CTF_ERR; /* errno is set for us. */
959 for (i = 0; i < ctc->ctc_argc; i++)
962 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
963 return CTF_ERR; /* errno is set for us. */
966 if (vlen > CTF_MAX_VLEN)
967 return (ctf_set_errno (fp, EOVERFLOW));
969 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
970 return (ctf_set_errno (fp, EAGAIN));
972 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
975 return CTF_ERR; /* errno is set for us. */
978 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
979 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
981 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
982 if (ctc->ctc_flags & CTF_FUNC_VARARG)
983 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
984 dtd->dtd_u.dtu_argv = vdat;
990 ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
993 ctf_hash_t *hp = fp->ctf_structs;
997 /* Promote forwards to structs. */
1001 type = ctf_hash_lookup_type (hp, fp, name);
1003 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
1006 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1007 dtd = ctf_dtd_lookup (fp, type);
1008 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1009 return CTF_ERR; /* errno is set for us. */
1011 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1013 if (size > CTF_MAX_SIZE)
1015 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1016 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1017 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1020 dtd->dtd_data.ctt_size = (uint32_t) size;
1026 ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1028 return (ctf_add_struct_sized (fp, flag, name, 0));
1032 ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1035 ctf_hash_t *hp = fp->ctf_unions;
1039 /* Promote forwards to unions. */
1042 type = ctf_hash_lookup_type (hp, fp, name);
1044 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1047 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1048 dtd = ctf_dtd_lookup (fp, type);
1049 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1050 return CTF_ERR; /* errno is set for us */
1052 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1054 if (size > CTF_MAX_SIZE)
1056 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1057 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1058 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1061 dtd->dtd_data.ctt_size = (uint32_t) size;
1067 ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1069 return (ctf_add_union_sized (fp, flag, name, 0));
1073 ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1075 ctf_hash_t *hp = fp->ctf_enums;
1079 /* Promote forwards to enums. */
1082 type = ctf_hash_lookup_type (hp, fp, name);
1084 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1087 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1088 dtd = ctf_dtd_lookup (fp, type);
1089 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1090 return CTF_ERR; /* errno is set for us. */
1092 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1093 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1099 ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1100 const ctf_encoding_t *ep)
1102 ctf_hash_t *hp = fp->ctf_enums;
1105 /* First, create the enum if need be, using most of the same machinery as
1106 ctf_add_enum(), to ensure that we do not allow things past that are not
1107 enums or forwards to them. (This includes other slices: you cannot slice a
1108 slice, which would be a useless thing to do anyway.) */
1112 type = ctf_hash_lookup_type (hp, fp, name);
1114 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1119 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1120 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1121 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1123 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1124 return CTF_ERR; /* errno is set for us. */
1126 /* Now attach a suitable slice to it. */
1128 return ctf_add_slice (fp, flag, type, ep);
1132 ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1142 hp = fp->ctf_structs;
1145 hp = fp->ctf_unions;
1151 return (ctf_set_errno (fp, ECTF_NOTSUE));
1154 /* If the type is already defined or exists as a forward tag, just
1155 return the ctf_id_t of the existing definition. */
1159 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1160 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1164 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1165 return CTF_ERR; /* errno is set for us. */
1167 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1168 dtd->dtd_data.ctt_type = kind;
1174 ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1179 ctf_file_t *tmp = fp;
1181 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1182 return (ctf_set_errno (fp, EINVAL));
1184 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1185 return CTF_ERR; /* errno is set for us. */
1187 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1188 return CTF_ERR; /* errno is set for us. */
1190 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1191 dtd->dtd_data.ctt_type = (uint32_t) ref;
1197 ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1199 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1203 ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1205 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1209 ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1211 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1215 ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1218 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1221 uint32_t kind, vlen, root;
1225 return (ctf_set_errno (fp, EINVAL));
1227 if (!(fp->ctf_flags & LCTF_RDWR))
1228 return (ctf_set_errno (fp, ECTF_RDONLY));
1231 return (ctf_set_errno (fp, ECTF_BADID));
1233 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1234 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1235 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1237 if (kind != CTF_K_ENUM)
1238 return (ctf_set_errno (fp, ECTF_NOTENUM));
1240 if (vlen == CTF_MAX_VLEN)
1241 return (ctf_set_errno (fp, ECTF_DTFULL));
1243 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1244 dmd != NULL; dmd = ctf_list_next (dmd))
1246 if (strcmp (dmd->dmd_name, name) == 0)
1247 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1250 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1251 return (ctf_set_errno (fp, EAGAIN));
1253 if ((s = ctf_strdup (name)) == NULL)
1256 return (ctf_set_errno (fp, EAGAIN));
1260 dmd->dmd_type = CTF_ERR;
1261 dmd->dmd_offset = 0;
1262 dmd->dmd_value = value;
1264 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1265 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1267 fp->ctf_dtvstrlen += strlen (s) + 1;
1268 fp->ctf_flags |= LCTF_DIRTY;
1274 ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1275 ctf_id_t type, unsigned long bit_offset)
1277 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1280 ssize_t msize, malign, ssize;
1281 uint32_t kind, vlen, root;
1284 if (!(fp->ctf_flags & LCTF_RDWR))
1285 return (ctf_set_errno (fp, ECTF_RDONLY));
1288 return (ctf_set_errno (fp, ECTF_BADID));
1290 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1291 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1292 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1294 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1295 return (ctf_set_errno (fp, ECTF_NOTSOU));
1297 if (vlen == CTF_MAX_VLEN)
1298 return (ctf_set_errno (fp, ECTF_DTFULL));
1302 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1303 dmd != NULL; dmd = ctf_list_next (dmd))
1305 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1306 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1310 if ((msize = ctf_type_size (fp, type)) < 0 ||
1311 (malign = ctf_type_align (fp, type)) < 0)
1312 return -1; /* errno is set for us. */
1314 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1315 return (ctf_set_errno (fp, EAGAIN));
1317 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1320 return (ctf_set_errno (fp, EAGAIN));
1324 dmd->dmd_type = type;
1325 dmd->dmd_value = -1;
1327 if (kind == CTF_K_STRUCT && vlen != 0)
1329 if (bit_offset == (unsigned long) - 1)
1331 /* Natural alignment. */
1333 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1334 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1335 size_t off = lmd->dmd_offset;
1337 ctf_encoding_t linfo;
1340 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1341 off += linfo.cte_bits;
1342 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1343 off += lsize * CHAR_BIT;
1345 /* Round up the offset of the end of the last member to
1346 the next byte boundary, convert 'off' to bytes, and
1347 then round it up again to the next multiple of the
1348 alignment required by the new member. Finally,
1349 convert back to bits and store the result in
1350 dmd_offset. Technically we could do more efficient
1351 packing if the new member is a bit-field, but we're
1352 the "compiler" and ANSI says we can do as we choose. */
1354 off = roundup (off, CHAR_BIT) / CHAR_BIT;
1355 off = roundup (off, MAX (malign, 1));
1356 dmd->dmd_offset = off * CHAR_BIT;
1357 ssize = off + msize;
1361 /* Specified offset in bits. */
1363 dmd->dmd_offset = bit_offset;
1364 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1365 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1370 dmd->dmd_offset = 0;
1371 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1372 ssize = MAX (ssize, msize);
1375 if ((size_t) ssize > CTF_MAX_SIZE)
1377 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1378 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1379 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1382 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1384 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1385 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1388 fp->ctf_dtvstrlen += strlen (s) + 1;
1390 fp->ctf_flags |= LCTF_DIRTY;
1395 ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1396 ctf_id_t type, unsigned long bit_offset,
1397 const ctf_encoding_t encoding)
1399 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1400 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1403 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1404 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1406 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1407 return -1; /* errno is set for us. */
1409 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1413 ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1416 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1420 ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1423 ctf_file_t *tmp = fp;
1425 if (!(fp->ctf_flags & LCTF_RDWR))
1426 return (ctf_set_errno (fp, ECTF_RDONLY));
1428 if (ctf_dvd_lookup (fp, name) != NULL)
1429 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1431 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1432 return -1; /* errno is set for us. */
1434 if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL)
1435 return (ctf_set_errno (fp, EAGAIN));
1437 if (name != NULL && (dvd->dvd_name = ctf_strdup (name)) == NULL)
1440 return (ctf_set_errno (fp, EAGAIN));
1442 dvd->dvd_type = ref;
1443 dvd->dvd_snapshots = fp->ctf_snapshots;
1445 ctf_dvd_insert (fp, dvd);
1447 fp->ctf_dtvstrlen += strlen (name) + 1;
1448 fp->ctf_flags |= LCTF_DIRTY;
1453 enumcmp (const char *name, int value, void *arg)
1455 ctf_bundle_t *ctb = arg;
1458 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
1460 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1463 if (value != bvalue)
1465 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1473 enumadd (const char *name, int value, void *arg)
1475 ctf_bundle_t *ctb = arg;
1477 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
1482 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1485 ctf_bundle_t *ctb = arg;
1488 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
1490 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1493 if (ctm.ctm_offset != offset)
1495 ctf_dprintf ("Conflict due to member %s offset change: "
1496 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1503 membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1505 ctf_bundle_t *ctb = arg;
1509 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1510 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1512 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1515 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1518 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1519 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1521 dmd->dmd_type = type;
1522 dmd->dmd_offset = offset;
1523 dmd->dmd_value = -1;
1525 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1528 ctb->ctb_file->ctf_dtvstrlen += strlen (s) + 1;
1530 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1534 /* The ctf_add_type routine is used to copy a type from a source CTF container
1535 to a dynamic destination container. This routine operates recursively by
1536 following the source type's links and embedded member types. If the
1537 destination container already contains a named type which has the same
1538 attributes, then we succeed and return this type but no changes occur. */
1540 ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1542 ctf_id_t dst_type = CTF_ERR;
1543 uint32_t dst_kind = CTF_K_UNKNOWN;
1547 uint32_t kind, flag, vlen;
1549 const ctf_type_t *src_tp, *dst_tp;
1550 ctf_bundle_t src, dst;
1551 ctf_encoding_t src_en, dst_en;
1552 ctf_arinfo_t src_ar, dst_ar;
1559 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1560 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1562 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1563 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1565 name = ctf_strptr (src_fp, src_tp->ctt_name);
1566 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1567 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1568 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1573 hp = dst_fp->ctf_structs;
1576 hp = dst_fp->ctf_unions;
1579 hp = dst_fp->ctf_enums;
1582 hp = dst_fp->ctf_names;
1586 /* If the source type has a name and is a root type (visible at the
1587 top-level scope), lookup the name in the destination container and
1588 verify that it is of the same kind before we do anything else. */
1590 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1591 && (tmp = ctf_hash_lookup_type (hp, dst_fp, name)) != 0)
1594 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1597 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1598 unless dst_type is a forward declaration and src_type is a struct,
1599 union, or enum (i.e. the definition of the previous forward decl). */
1601 if (dst_type != CTF_ERR && dst_kind != kind
1602 && (dst_kind != CTF_K_FORWARD
1603 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1604 && kind != CTF_K_UNION)))
1606 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1607 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1608 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1611 /* We take special action for an integer, float, or slice since it is
1612 described not only by its name but also its encoding. For integers,
1613 bit-fields exploit this degeneracy. */
1615 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1617 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1618 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1620 if (dst_type != CTF_ERR)
1622 ctf_file_t *fp = dst_fp;
1624 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1627 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1629 /* The type that we found in the hash is also root-visible. If
1630 the two types match then use the existing one; otherwise,
1631 declare a conflict. Note: slices are not certain to match
1632 even if there is no conflict: we must check the contained type
1635 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1636 return CTF_ERR; /* errno set for us. */
1638 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1640 if (kind != CTF_K_SLICE)
1645 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1650 /* We found a non-root-visible type in the hash. We reset
1651 dst_type to ensure that we continue to look for a possible
1652 conflict in the pending list. */
1659 /* If the non-empty name was not found in the appropriate hash, search
1660 the list of pending dynamic definitions that are not yet committed.
1661 If a matching name and kind are found, assume this is the type that
1662 we are looking for. This is necessary to permit ctf_add_type() to
1663 operate recursively on entities such as a struct that contains a
1664 pointer member that refers to the same struct type. */
1666 if (dst_type == CTF_ERR && name[0] != '\0')
1668 for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1669 && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1670 dtd = ctf_list_prev (dtd))
1672 if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1673 && dtd->dtd_name != NULL && strcmp (dtd->dtd_name, name) == 0)
1675 int sroot; /* Is the src root-visible? */
1676 int droot; /* Is the dst root-visible? */
1677 int match; /* Do the encodings match? */
1679 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1680 return dtd->dtd_type;
1682 sroot = (flag & CTF_ADD_ROOT);
1683 droot = (LCTF_INFO_ISROOT (dst_fp,
1685 ctt_info) & CTF_ADD_ROOT);
1687 match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1688 sizeof (ctf_encoding_t)) == 0);
1690 /* If the types share the same encoding then return the id of the
1691 first unless one type is root-visible and the other is not; in
1692 that case the new type must get a new id if a match is never
1693 found. Note: slices are not certain to match even if there is
1694 no conflict: we must check the contained type too. */
1696 if (match && sroot == droot)
1698 if (kind != CTF_K_SLICE)
1699 return dtd->dtd_type;
1701 else if (!match && sroot && droot)
1703 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1709 src.ctb_file = src_fp;
1710 src.ctb_type = src_type;
1713 dst.ctb_file = dst_fp;
1714 dst.ctb_type = dst_type;
1717 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1718 we add a new type with the same properties as src_type to dst_fp.
1719 If dst_type is not CTF_ERR, then we verify that dst_type has the
1720 same attributes as src_type. We recurse for embedded references. */
1724 /* If we found a match we will have either returned it or declared a
1726 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1730 /* If we found a match we will have either returned it or declared a
1732 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1736 /* We have checked for conflicting encodings: now try to add the
1738 src_type = ctf_type_reference (src_fp, src_type);
1739 dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1741 if (src_type == CTF_ERR)
1742 return CTF_ERR; /* errno is set for us. */
1744 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1748 case CTF_K_VOLATILE:
1750 case CTF_K_RESTRICT:
1751 src_type = ctf_type_reference (src_fp, src_type);
1752 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1754 if (src_type == CTF_ERR)
1755 return CTF_ERR; /* errno is set for us. */
1757 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1761 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1762 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1764 src_ar.ctr_contents =
1765 ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1766 src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1767 src_ar.ctr_nelems = src_ar.ctr_nelems;
1769 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1770 return CTF_ERR; /* errno is set for us. */
1772 if (dst_type != CTF_ERR)
1774 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1775 return CTF_ERR; /* errno is set for us. */
1777 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1779 ctf_dprintf ("Conflict for type %s against ID %lx: "
1780 "array info differs, old %lx/%lx/%x; "
1781 "new: %lx/%lx/%x\n", name, dst_type,
1782 src_ar.ctr_contents, src_ar.ctr_index,
1783 src_ar.ctr_nelems, dst_ar.ctr_contents,
1784 dst_ar.ctr_index, dst_ar.ctr_nelems);
1785 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1789 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1792 case CTF_K_FUNCTION:
1793 ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1797 if (ctc.ctc_return == CTF_ERR)
1798 return CTF_ERR; /* errno is set for us. */
1800 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1811 /* Technically to match a struct or union we need to check both
1812 ways (src members vs. dst, dst members vs. src) but we make
1813 this more optimal by only checking src vs. dst and comparing
1814 the total size of the structure (which we must do anyway)
1815 which covers the possibility of dst members not in src.
1816 This optimization can be defeated for unions, but is so
1817 pathological as to render it irrelevant for our purposes. */
1819 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1821 if (ctf_type_size (src_fp, src_type) !=
1822 ctf_type_size (dst_fp, dst_type))
1824 ctf_dprintf ("Conflict for type %s against ID %lx: "
1825 "union size differs, old %li, new %li\n",
1827 (long) ctf_type_size (src_fp, src_type),
1828 (long) ctf_type_size (dst_fp, dst_type));
1829 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1832 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1834 ctf_dprintf ("Conflict for type %s against ID %lx: "
1835 "members differ, see above\n", name, dst_type);
1836 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1842 /* Unlike the other cases, copying structs and unions is done
1843 manually so as to avoid repeated lookups in ctf_add_member
1844 and to ensure the exact same member offsets as in src_type. */
1846 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1847 if (dst_type == CTF_ERR)
1848 return CTF_ERR; /* errno is set for us. */
1850 dst.ctb_type = dst_type;
1853 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1854 errs++; /* Increment errs and fail at bottom of case. */
1856 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1857 return CTF_ERR; /* errno is set for us. */
1859 size = (size_t) ssize;
1860 if (size > CTF_MAX_SIZE)
1862 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1863 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1864 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1867 dtd->dtd_data.ctt_size = (uint32_t) size;
1869 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1871 /* Make a final pass through the members changing each dmd_type (a
1872 src_fp type) to an equivalent type in dst_fp. We pass through all
1873 members, leaving any that fail set to CTF_ERR. */
1874 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1875 dmd != NULL; dmd = ctf_list_next (dmd))
1877 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1878 dmd->dmd_type)) == CTF_ERR)
1883 return CTF_ERR; /* errno is set for us. */
1888 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1890 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1891 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1893 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1894 "members differ, see above\n", name, dst_type);
1895 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1900 dst_type = ctf_add_enum (dst_fp, flag, name);
1901 if ((dst.ctb_type = dst_type) == CTF_ERR
1902 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1903 return CTF_ERR; /* errno is set for us */
1908 if (dst_type == CTF_ERR)
1910 dst_type = ctf_add_forward (dst_fp, flag,
1911 name, CTF_K_STRUCT); /* Assume STRUCT. */
1916 src_type = ctf_type_reference (src_fp, src_type);
1917 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1919 if (src_type == CTF_ERR)
1920 return CTF_ERR; /* errno is set for us. */
1922 /* If dst_type is not CTF_ERR at this point, we should check if
1923 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1924 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1925 that vary based on things like if 32-bit then pid_t is int otherwise
1926 long. We therefore omit this check and assume that if the identically
1927 named typedef already exists in dst_fp, it is correct or
1930 if (dst_type == CTF_ERR)
1932 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1937 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1943 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1944 This is useful for saving the results of dynamic CTF containers. */
1946 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1948 const unsigned char *buf = fp->ctf_base;
1949 ssize_t resid = fp->ctf_size;
1954 if ((len = gzwrite (fd, buf, resid)) <= 0)
1955 return (ctf_set_errno (fp, errno));
1963 /* Compress the specified CTF data stream and write it to the specified file
1966 ctf_compress_write (ctf_file_t *fp, int fd)
1971 ctf_header_t *hp = &h;
1972 ssize_t header_len = sizeof (ctf_header_t);
1973 ssize_t compress_len;
1974 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1979 memcpy (hp, fp->ctf_base, header_len);
1980 hp->cth_flags |= CTF_F_COMPRESS;
1982 if ((buf = ctf_data_alloc (max_compress_len)) == NULL)
1983 return (ctf_set_errno (fp, ECTF_ZALLOC));
1985 compress_len = max_compress_len;
1986 if ((rc = compress (buf, (uLongf *) & compress_len,
1987 fp->ctf_base + header_len,
1988 fp->ctf_size - header_len)) != Z_OK)
1990 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
1991 err = ctf_set_errno (fp, ECTF_COMPRESS);
1995 while (header_len > 0)
1997 if ((len = write (fd, hp, header_len)) < 0)
1999 err = ctf_set_errno (fp, errno);
2007 while (compress_len > 0)
2009 if ((len = write (fd, bp, compress_len)) < 0)
2011 err = ctf_set_errno (fp, errno);
2014 compress_len -= len;
2019 ctf_data_free (buf, max_compress_len);
2023 /* Write the uncompressed CTF data stream to the specified file descriptor.
2024 This is useful for saving the results of dynamic CTF containers. */
2026 ctf_write (ctf_file_t *fp, int fd)
2028 const unsigned char *buf = fp->ctf_base;
2029 ssize_t resid = fp->ctf_size;
2034 if ((len = write (fd, buf, resid)) < 0)
2035 return (ctf_set_errno (fp, errno));