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 start assigning type IDs at 1 because
33 type ID 0 is used as a sentinel and a not-found indicator. */
36 ctf_create (int *errp)
38 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
40 ctf_dynhash_t *dthash;
41 ctf_dynhash_t *dvhash;
42 ctf_dynhash_t *dtbyname;
47 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
51 ctf_set_open_errno (errp, EAGAIN);
55 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
59 ctf_set_open_errno (errp, EAGAIN);
63 dtbyname = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
67 ctf_set_open_errno (errp, EAGAIN);
71 cts.cts_name = _CTF_SECTION;
73 cts.cts_size = sizeof (hdr);
76 if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
79 fp->ctf_flags |= LCTF_RDWR;
80 fp->ctf_dtbyname = dtbyname;
81 fp->ctf_dthash = dthash;
82 fp->ctf_dvhash = dvhash;
85 fp->ctf_snapshots = 1;
86 fp->ctf_snapshot_lu = 0;
91 ctf_dynhash_destroy (dtbyname);
93 ctf_dynhash_destroy (dvhash);
95 ctf_dynhash_destroy (dthash);
100 static unsigned char *
101 ctf_copy_smembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
103 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
106 for (; dmd != NULL; dmd = ctf_list_next (dmd))
108 ctf_member_t *copied;
111 ctm.ctm_type = (uint32_t) dmd->dmd_type;
112 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
114 memcpy (t, &ctm, sizeof (ctm));
115 copied = (ctf_member_t *) t;
117 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctm_name);
125 static unsigned char *
126 ctf_copy_lmembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
128 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
131 for (; dmd != NULL; dmd = ctf_list_next (dmd))
133 ctf_lmember_t *copied;
136 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
137 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
138 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
140 memcpy (t, &ctlm, sizeof (ctlm));
141 copied = (ctf_lmember_t *) t;
143 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctlm_name);
151 static unsigned char *
152 ctf_copy_emembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
154 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
157 for (; dmd != NULL; dmd = ctf_list_next (dmd))
161 cte.cte_value = dmd->dmd_value;
162 memcpy (t, &cte, sizeof (cte));
163 copied = (ctf_enum_t *) t;
164 ctf_str_add_ref (fp, dmd->dmd_name, &copied->cte_name);
171 /* Sort a newly-constructed static variable array. */
174 ctf_sort_var (const void *one_, const void *two_, void *strtab_)
176 const ctf_varent_t *one = one_;
177 const ctf_varent_t *two = two_;
178 const char *strtab = strtab_;
179 const char *n1 = strtab + CTF_NAME_OFFSET (one->ctv_name);
180 const char *n2 = strtab + CTF_NAME_OFFSET (two->ctv_name);
182 return (strcmp (n1, n2));
185 /* If the specified CTF container is writable and has been modified, reload this
186 container with the updated type definitions. In order to make this code and
187 the rest of libctf as simple as possible, we perform updates by taking the
188 dynamic type definitions and creating an in-memory CTF file containing the
189 definitions, and then call ctf_simple_open() on it. This not only leverages
190 ctf_simple_open(), but also avoids having to bifurcate the rest of the library
191 code with different lookup paths for static and dynamic type definitions. We
192 are therefore optimizing greatly for lookup over update, which we assume will
193 be an uncommon operation. We perform one extra trick here for the benefit of
194 callers and to keep our code simple: ctf_simple_open() will return a new
195 ctf_file_t, but we want to keep the fp constant for the caller, so after
196 ctf_simple_open() returns, we use memcpy to swap the interior of the old and
197 new ctf_file_t's, and then free the old. */
199 ctf_update (ctf_file_t *fp)
201 ctf_file_t ofp, *nfp;
202 ctf_header_t hdr, *hdrp;
205 ctf_varent_t *dvarents;
206 ctf_strs_writable_t strtab;
210 size_t buf_size, type_size, nvars;
211 unsigned char *buf, *newbuf;
214 if (!(fp->ctf_flags & LCTF_RDWR))
215 return (ctf_set_errno (fp, ECTF_RDONLY));
217 /* Update required? */
218 if (!(fp->ctf_flags & LCTF_DIRTY))
221 /* Fill in an initial CTF header. We will leave the label, object,
222 and function sections empty and only output a header, type section,
223 and string table. The type section begins at a 4-byte aligned
224 boundary past the CTF header itself (at relative offset zero). */
226 memset (&hdr, 0, sizeof (hdr));
227 hdr.cth_magic = CTF_MAGIC;
228 hdr.cth_version = CTF_VERSION;
230 /* Iterate through the dynamic type definition list and compute the
231 size of the CTF type section we will need to generate. */
233 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
234 dtd != NULL; dtd = ctf_list_next (dtd))
236 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
237 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
239 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
240 type_size += sizeof (ctf_stype_t);
242 type_size += sizeof (ctf_type_t);
248 type_size += sizeof (uint32_t);
251 type_size += sizeof (ctf_array_t);
254 type_size += sizeof (ctf_slice_t);
257 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
261 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
262 type_size += sizeof (ctf_member_t) * vlen;
264 type_size += sizeof (ctf_lmember_t) * vlen;
267 type_size += sizeof (ctf_enum_t) * vlen;
272 /* Computing the number of entries in the CTF variable section is much
275 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
276 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
278 /* Compute the size of the CTF buffer we need, sans only the string table,
279 then allocate a new buffer and memcpy the finished header to the start of
280 the buffer. (We will adjust this later with strtab length info.) */
282 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
283 hdr.cth_stroff = hdr.cth_typeoff + type_size;
286 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
288 if ((buf = malloc (buf_size)) == NULL)
289 return (ctf_set_errno (fp, EAGAIN));
291 memcpy (buf, &hdr, sizeof (ctf_header_t));
292 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff;
294 hdrp = (ctf_header_t *) buf;
295 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
296 ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
298 /* Work over the variable list, translating everything into ctf_varent_t's and
299 prepping the string table. */
301 dvarents = (ctf_varent_t *) t;
302 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
303 dvd = ctf_list_next (dvd), i++)
305 ctf_varent_t *var = &dvarents[i];
307 ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
308 var->ctv_type = dvd->dvd_type;
312 t += sizeof (ctf_varent_t) * nvars;
314 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
316 /* We now take a final lap through the dynamic type definition list and copy
317 the appropriate type records to the output buffer, noting down the
320 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
321 dtd != NULL; dtd = ctf_list_next (dtd))
323 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
324 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
331 dtd->dtd_data.ctt_name = 0;
333 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
334 len = sizeof (ctf_stype_t);
336 len = sizeof (ctf_type_t);
338 memcpy (t, &dtd->dtd_data, len);
339 copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */
341 ctf_str_add_ref (fp, dtd->dtd_name, &copied->ctt_name);
348 if (kind == CTF_K_INTEGER)
350 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
351 dtd->dtd_u.dtu_enc.cte_offset,
352 dtd->dtd_u.dtu_enc.cte_bits);
356 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
357 dtd->dtd_u.dtu_enc.cte_offset,
358 dtd->dtd_u.dtu_enc.cte_bits);
360 memcpy (t, &encoding, sizeof (encoding));
361 t += sizeof (encoding);
365 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
366 t += sizeof (struct ctf_slice);
370 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
371 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
372 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
373 memcpy (t, &cta, sizeof (cta));
379 uint32_t *argv = (uint32_t *) (uintptr_t) t;
382 for (argc = 0; argc < vlen; argc++)
383 *argv++ = (uint32_t) dtd->dtd_u.dtu_argv[argc];
386 *argv++ = 0; /* Pad to 4-byte boundary. */
388 t = (unsigned char *) argv;
394 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
395 t = ctf_copy_smembers (fp, dtd, t);
397 t = ctf_copy_lmembers (fp, dtd, t);
401 t = ctf_copy_emembers (fp, dtd, t);
405 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
407 /* Construct the final string table and fill out all the string refs with the
408 final offsets. Then purge the refs list, because we're about to move this
409 strtab onto the end of the buf, invalidating all the offsets. */
410 strtab = ctf_str_write_strtab (fp);
411 ctf_str_purge_refs (fp);
413 /* Now the string table is constructed, we can sort the buffer of
415 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
418 if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
421 ctf_free (strtab.cts_strs);
422 return (ctf_set_errno (fp, EAGAIN));
425 memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
426 hdrp = (ctf_header_t *) buf;
427 hdrp->cth_strlen = strtab.cts_len;
428 buf_size += hdrp->cth_strlen;
429 ctf_free (strtab.cts_strs);
431 /* Finally, we are ready to ctf_simple_open() the new container. If this
432 is successful, we then switch nfp and fp and free the old container. */
434 if ((nfp = ctf_simple_open ((char *) buf, buf_size, NULL, 0, 0, NULL,
438 return (ctf_set_errno (fp, err));
441 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
442 (void) ctf_import (nfp, fp->ctf_parent);
444 nfp->ctf_refcnt = fp->ctf_refcnt;
445 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
446 nfp->ctf_data.cts_data = NULL; /* Force ctf_free() on close. */
447 nfp->ctf_dthash = fp->ctf_dthash;
448 nfp->ctf_dtdefs = fp->ctf_dtdefs;
449 nfp->ctf_dtbyname = fp->ctf_dtbyname;
450 nfp->ctf_dvhash = fp->ctf_dvhash;
451 nfp->ctf_dvdefs = fp->ctf_dvdefs;
452 nfp->ctf_dtnextid = fp->ctf_dtnextid;
453 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
454 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
455 nfp->ctf_specific = fp->ctf_specific;
457 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
459 fp->ctf_dtbyname = NULL;
460 fp->ctf_dthash = NULL;
461 ctf_str_free_atoms (nfp);
462 nfp->ctf_str_atoms = fp->ctf_str_atoms;
463 fp->ctf_str_atoms = NULL;
464 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
466 fp->ctf_dvhash = NULL;
467 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
469 memcpy (&ofp, fp, sizeof (ctf_file_t));
470 memcpy (fp, nfp, sizeof (ctf_file_t));
471 memcpy (nfp, &ofp, sizeof (ctf_file_t));
473 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
474 array of type name prefixes and the corresponding ctf_dynhash to use.
475 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
477 fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
478 fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
479 fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
480 fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
482 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
483 ctf_file_close (nfp);
489 ctf_prefixed_name (int kind, const char *name)
496 prefixed = ctf_strdup ("struct ");
499 prefixed = ctf_strdup ("union ");
502 prefixed = ctf_strdup ("enum ");
505 prefixed = ctf_strdup ("");
508 prefixed = ctf_str_append (prefixed, name);
513 ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
515 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0)
520 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
521 if (ctf_dynhash_insert (fp->ctf_dtbyname,
522 ctf_prefixed_name (kind, dtd->dtd_name),
526 ctf_list_append (&fp->ctf_dtdefs, dtd);
531 ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
533 ctf_dmdef_t *dmd, *nmd;
534 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
536 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
543 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
544 dmd != NULL; dmd = nmd)
546 if (dmd->dmd_name != NULL)
547 ctf_free (dmd->dmd_name);
548 nmd = ctf_list_next (dmd);
553 ctf_free (dtd->dtd_u.dtu_argv);
561 name = ctf_prefixed_name (kind, dtd->dtd_name);
562 ctf_dynhash_remove (fp->ctf_dtbyname, name);
564 ctf_free (dtd->dtd_name);
567 ctf_list_delete (&fp->ctf_dtdefs, dtd);
572 ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
574 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
578 ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
581 char *decorated = ctf_prefixed_name (kind, name);
583 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
587 return dtd->dtd_type;
593 ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
597 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
600 idx = LCTF_TYPE_TO_INDEX(fp, id);
602 if (((unsigned long) idx > fp->ctf_typemax) &&
603 ((unsigned long) idx < fp->ctf_dtnextid))
604 return ctf_dtd_lookup (fp, id);
609 ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
611 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
613 ctf_list_append (&fp->ctf_dvdefs, dvd);
618 ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
620 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
621 ctf_free (dvd->dvd_name);
623 ctf_list_delete (&fp->ctf_dvdefs, dvd);
628 ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
630 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
633 /* Discard all of the dynamic type definitions and variable definitions that
634 have been added to the container since the last call to ctf_update(). We
635 locate such types by scanning the dtd list and deleting elements that have
636 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
637 by scanning the variable list and deleting elements that have update IDs
638 equal to the current value of the last-update snapshot count (indicating that
639 they were added after the most recent call to ctf_update()). */
641 ctf_discard (ctf_file_t *fp)
643 ctf_snapshot_id_t last_update =
645 fp->ctf_snapshot_lu + 1 };
647 /* Update required? */
648 if (!(fp->ctf_flags & LCTF_DIRTY))
651 return (ctf_rollback (fp, last_update));
655 ctf_snapshot (ctf_file_t *fp)
657 ctf_snapshot_id_t snapid;
658 snapid.dtd_id = fp->ctf_dtnextid - 1;
659 snapid.snapshot_id = fp->ctf_snapshots++;
663 /* Like ctf_discard(), only discards everything after a particular ID. */
665 ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
667 ctf_dtdef_t *dtd, *ntd;
668 ctf_dvdef_t *dvd, *nvd;
670 if (!(fp->ctf_flags & LCTF_RDWR))
671 return (ctf_set_errno (fp, ECTF_RDONLY));
673 if (fp->ctf_dtoldid > id.dtd_id)
674 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
676 if (fp->ctf_snapshot_lu >= id.snapshot_id)
677 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
679 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
681 ntd = ctf_list_next (dtd);
683 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
686 ctf_dtd_delete (fp, dtd);
689 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
691 nvd = ctf_list_next (dvd);
693 if (dvd->dvd_snapshots <= id.snapshot_id)
696 ctf_dvd_delete (fp, dvd);
699 fp->ctf_dtnextid = id.dtd_id + 1;
700 fp->ctf_snapshots = id.snapshot_id;
702 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
703 fp->ctf_flags &= ~LCTF_DIRTY;
709 ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
716 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
717 return (ctf_set_errno (fp, EINVAL));
719 if (!(fp->ctf_flags & LCTF_RDWR))
720 return (ctf_set_errno (fp, ECTF_RDONLY));
722 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
723 return (ctf_set_errno (fp, ECTF_FULL));
725 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
726 return (ctf_set_errno (fp, ECTF_FULL));
728 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
729 return (ctf_set_errno (fp, EAGAIN));
731 if (name != NULL && (s = ctf_strdup (name)) == NULL)
734 return (ctf_set_errno (fp, EAGAIN));
737 type = fp->ctf_dtnextid++;
738 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
740 memset (dtd, 0, sizeof (ctf_dtdef_t));
742 dtd->dtd_type = type;
744 if (ctf_dtd_insert (fp, dtd) < 0)
747 return CTF_ERR; /* errno is set for us. */
749 fp->ctf_flags |= LCTF_DIRTY;
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. */
773 ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
774 const char *name, const ctf_encoding_t *ep, uint32_t kind)
780 return (ctf_set_errno (fp, EINVAL));
782 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
783 return CTF_ERR; /* errno is set for us. */
785 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
786 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
788 dtd->dtd_u.dtu_enc = *ep;
794 ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
798 ctf_file_t *tmp = fp;
800 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
801 return (ctf_set_errno (fp, EINVAL));
803 if (ctf_lookup_by_id (&tmp, ref) == NULL)
804 return CTF_ERR; /* errno is set for us. */
806 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
807 return CTF_ERR; /* errno is set for us. */
809 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
810 dtd->dtd_data.ctt_type = (uint32_t) ref;
816 ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
817 const ctf_encoding_t *ep)
822 const ctf_type_t *tp;
823 ctf_file_t *tmp = fp;
826 return (ctf_set_errno (fp, EINVAL));
828 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
829 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
831 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
832 return (ctf_set_errno (fp, EINVAL));
834 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
835 return CTF_ERR; /* errno is set for us. */
837 kind = ctf_type_kind_unsliced (tmp, ref);
838 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
839 (kind != CTF_K_ENUM))
840 return (ctf_set_errno (fp, ECTF_NOTINTFP));
842 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
843 return CTF_ERR; /* errno is set for us. */
845 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
846 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
848 dtd->dtd_u.dtu_slice.cts_type = ref;
849 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
850 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
856 ctf_add_integer (ctf_file_t *fp, uint32_t flag,
857 const char *name, const ctf_encoding_t *ep)
859 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
863 ctf_add_float (ctf_file_t *fp, uint32_t flag,
864 const char *name, const ctf_encoding_t *ep)
866 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
870 ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
872 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
876 ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
880 ctf_file_t *tmp = fp;
883 return (ctf_set_errno (fp, EINVAL));
885 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
886 return CTF_ERR; /* errno is set for us. */
889 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
890 return CTF_ERR; /* errno is set for us. */
892 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
893 return CTF_ERR; /* errno is set for us. */
895 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
896 dtd->dtd_data.ctt_size = 0;
897 dtd->dtd_u.dtu_arr = *arp;
903 ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
905 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
907 if (!(fp->ctf_flags & LCTF_RDWR))
908 return (ctf_set_errno (fp, ECTF_RDONLY));
911 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
912 return (ctf_set_errno (fp, ECTF_BADID));
914 fp->ctf_flags |= LCTF_DIRTY;
915 dtd->dtd_u.dtu_arr = *arp;
921 ctf_add_function (ctf_file_t *fp, uint32_t flag,
922 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
927 ctf_id_t *vdat = NULL;
928 ctf_file_t *tmp = fp;
931 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
932 || (ctc->ctc_argc != 0 && argv == NULL))
933 return (ctf_set_errno (fp, EINVAL));
935 vlen = ctc->ctc_argc;
936 if (ctc->ctc_flags & CTF_FUNC_VARARG)
937 vlen++; /* Add trailing zero to indicate varargs (see below). */
939 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
940 return CTF_ERR; /* errno is set for us. */
942 for (i = 0; i < ctc->ctc_argc; i++)
945 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
946 return CTF_ERR; /* errno is set for us. */
949 if (vlen > CTF_MAX_VLEN)
950 return (ctf_set_errno (fp, EOVERFLOW));
952 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
953 return (ctf_set_errno (fp, EAGAIN));
955 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
958 return CTF_ERR; /* errno is set for us. */
961 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
962 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
964 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
965 if (ctc->ctc_flags & CTF_FUNC_VARARG)
966 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
967 dtd->dtd_u.dtu_argv = vdat;
973 ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
976 ctf_hash_t *hp = fp->ctf_structs;
980 /* Promote forwards to structs. */
984 type = ctf_hash_lookup_type (hp, fp, name);
986 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
989 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
990 dtd = ctf_dtd_lookup (fp, type);
991 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
992 return CTF_ERR; /* errno is set for us. */
994 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
996 if (size > CTF_MAX_SIZE)
998 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
999 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1000 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1003 dtd->dtd_data.ctt_size = (uint32_t) size;
1009 ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1011 return (ctf_add_struct_sized (fp, flag, name, 0));
1015 ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1018 ctf_hash_t *hp = fp->ctf_unions;
1022 /* Promote forwards to unions. */
1025 type = ctf_hash_lookup_type (hp, fp, name);
1027 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1030 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1031 dtd = ctf_dtd_lookup (fp, type);
1032 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1033 return CTF_ERR; /* errno is set for us */
1035 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1037 if (size > CTF_MAX_SIZE)
1039 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1040 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1041 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1044 dtd->dtd_data.ctt_size = (uint32_t) size;
1050 ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1052 return (ctf_add_union_sized (fp, flag, name, 0));
1056 ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1058 ctf_hash_t *hp = fp->ctf_enums;
1062 /* Promote forwards to enums. */
1065 type = ctf_hash_lookup_type (hp, fp, name);
1067 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1070 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1071 dtd = ctf_dtd_lookup (fp, type);
1072 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1073 return CTF_ERR; /* errno is set for us. */
1075 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1076 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1082 ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1083 const ctf_encoding_t *ep)
1085 ctf_hash_t *hp = fp->ctf_enums;
1088 /* First, create the enum if need be, using most of the same machinery as
1089 ctf_add_enum(), to ensure that we do not allow things past that are not
1090 enums or forwards to them. (This includes other slices: you cannot slice a
1091 slice, which would be a useless thing to do anyway.) */
1095 type = ctf_hash_lookup_type (hp, fp, name);
1097 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1102 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1103 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1104 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1106 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1107 return CTF_ERR; /* errno is set for us. */
1109 /* Now attach a suitable slice to it. */
1111 return ctf_add_slice (fp, flag, type, ep);
1115 ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1125 hp = fp->ctf_structs;
1128 hp = fp->ctf_unions;
1134 return (ctf_set_errno (fp, ECTF_NOTSUE));
1137 /* If the type is already defined or exists as a forward tag, just
1138 return the ctf_id_t of the existing definition. */
1142 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1143 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1147 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1148 return CTF_ERR; /* errno is set for us. */
1150 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1151 dtd->dtd_data.ctt_type = kind;
1157 ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1162 ctf_file_t *tmp = fp;
1164 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1165 return (ctf_set_errno (fp, EINVAL));
1167 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1168 return CTF_ERR; /* errno is set for us. */
1170 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1171 return CTF_ERR; /* errno is set for us. */
1173 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1174 dtd->dtd_data.ctt_type = (uint32_t) ref;
1180 ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1182 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1186 ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1188 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1192 ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1194 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1198 ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1201 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1204 uint32_t kind, vlen, root;
1208 return (ctf_set_errno (fp, EINVAL));
1210 if (!(fp->ctf_flags & LCTF_RDWR))
1211 return (ctf_set_errno (fp, ECTF_RDONLY));
1214 return (ctf_set_errno (fp, ECTF_BADID));
1216 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1217 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1218 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1220 if (kind != CTF_K_ENUM)
1221 return (ctf_set_errno (fp, ECTF_NOTENUM));
1223 if (vlen == CTF_MAX_VLEN)
1224 return (ctf_set_errno (fp, ECTF_DTFULL));
1226 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1227 dmd != NULL; dmd = ctf_list_next (dmd))
1229 if (strcmp (dmd->dmd_name, name) == 0)
1230 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1233 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1234 return (ctf_set_errno (fp, EAGAIN));
1236 if ((s = ctf_strdup (name)) == NULL)
1239 return (ctf_set_errno (fp, EAGAIN));
1243 dmd->dmd_type = CTF_ERR;
1244 dmd->dmd_offset = 0;
1245 dmd->dmd_value = value;
1247 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1248 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1250 fp->ctf_flags |= LCTF_DIRTY;
1256 ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1257 ctf_id_t type, unsigned long bit_offset)
1259 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1262 ssize_t msize, malign, ssize;
1263 uint32_t kind, vlen, root;
1266 if (!(fp->ctf_flags & LCTF_RDWR))
1267 return (ctf_set_errno (fp, ECTF_RDONLY));
1270 return (ctf_set_errno (fp, ECTF_BADID));
1272 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1273 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1274 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1276 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1277 return (ctf_set_errno (fp, ECTF_NOTSOU));
1279 if (vlen == CTF_MAX_VLEN)
1280 return (ctf_set_errno (fp, ECTF_DTFULL));
1284 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1285 dmd != NULL; dmd = ctf_list_next (dmd))
1287 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1288 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1292 if ((msize = ctf_type_size (fp, type)) < 0 ||
1293 (malign = ctf_type_align (fp, type)) < 0)
1294 return -1; /* errno is set for us. */
1296 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1297 return (ctf_set_errno (fp, EAGAIN));
1299 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1302 return (ctf_set_errno (fp, EAGAIN));
1306 dmd->dmd_type = type;
1307 dmd->dmd_value = -1;
1309 if (kind == CTF_K_STRUCT && vlen != 0)
1311 if (bit_offset == (unsigned long) - 1)
1313 /* Natural alignment. */
1315 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1316 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1317 size_t off = lmd->dmd_offset;
1319 ctf_encoding_t linfo;
1322 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1323 off += linfo.cte_bits;
1324 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1325 off += lsize * CHAR_BIT;
1327 /* Round up the offset of the end of the last member to
1328 the next byte boundary, convert 'off' to bytes, and
1329 then round it up again to the next multiple of the
1330 alignment required by the new member. Finally,
1331 convert back to bits and store the result in
1332 dmd_offset. Technically we could do more efficient
1333 packing if the new member is a bit-field, but we're
1334 the "compiler" and ANSI says we can do as we choose. */
1336 off = roundup (off, CHAR_BIT) / CHAR_BIT;
1337 off = roundup (off, MAX (malign, 1));
1338 dmd->dmd_offset = off * CHAR_BIT;
1339 ssize = off + msize;
1343 /* Specified offset in bits. */
1345 dmd->dmd_offset = bit_offset;
1346 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1347 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1352 dmd->dmd_offset = 0;
1353 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1354 ssize = MAX (ssize, msize);
1357 if ((size_t) ssize > CTF_MAX_SIZE)
1359 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1360 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1361 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1364 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1366 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1367 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1369 fp->ctf_flags |= LCTF_DIRTY;
1374 ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1375 ctf_id_t type, unsigned long bit_offset,
1376 const ctf_encoding_t encoding)
1378 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1379 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1382 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1383 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1385 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1386 return -1; /* errno is set for us. */
1388 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1392 ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1395 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1399 ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1402 ctf_file_t *tmp = fp;
1404 if (!(fp->ctf_flags & LCTF_RDWR))
1405 return (ctf_set_errno (fp, ECTF_RDONLY));
1407 if (ctf_dvd_lookup (fp, name) != NULL)
1408 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1410 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1411 return -1; /* errno is set for us. */
1413 if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL)
1414 return (ctf_set_errno (fp, EAGAIN));
1416 if (name != NULL && (dvd->dvd_name = ctf_strdup (name)) == NULL)
1419 return (ctf_set_errno (fp, EAGAIN));
1421 dvd->dvd_type = ref;
1422 dvd->dvd_snapshots = fp->ctf_snapshots;
1424 if (ctf_dvd_insert (fp, dvd) < 0)
1427 return -1; /* errno is set for us. */
1430 fp->ctf_flags |= LCTF_DIRTY;
1435 enumcmp (const char *name, int value, void *arg)
1437 ctf_bundle_t *ctb = arg;
1440 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
1442 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1445 if (value != bvalue)
1447 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1455 enumadd (const char *name, int value, void *arg)
1457 ctf_bundle_t *ctb = arg;
1459 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
1464 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1467 ctf_bundle_t *ctb = arg;
1470 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
1472 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1475 if (ctm.ctm_offset != offset)
1477 ctf_dprintf ("Conflict due to member %s offset change: "
1478 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1485 membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1487 ctf_bundle_t *ctb = arg;
1491 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1492 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1494 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1497 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1500 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1501 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1503 dmd->dmd_type = type;
1504 dmd->dmd_offset = offset;
1505 dmd->dmd_value = -1;
1507 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1509 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1513 /* The ctf_add_type routine is used to copy a type from a source CTF container
1514 to a dynamic destination container. This routine operates recursively by
1515 following the source type's links and embedded member types. If the
1516 destination container already contains a named type which has the same
1517 attributes, then we succeed and return this type but no changes occur. */
1519 ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1521 ctf_id_t dst_type = CTF_ERR;
1522 uint32_t dst_kind = CTF_K_UNKNOWN;
1526 uint32_t kind, flag, vlen;
1528 const ctf_type_t *src_tp, *dst_tp;
1529 ctf_bundle_t src, dst;
1530 ctf_encoding_t src_en, dst_en;
1531 ctf_arinfo_t src_ar, dst_ar;
1538 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1539 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1541 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1542 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1544 name = ctf_strptr (src_fp, src_tp->ctt_name);
1545 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1546 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1547 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1552 hp = dst_fp->ctf_structs;
1555 hp = dst_fp->ctf_unions;
1558 hp = dst_fp->ctf_enums;
1561 hp = dst_fp->ctf_names;
1565 /* If the source type has a name and is a root type (visible at the
1566 top-level scope), lookup the name in the destination container and
1567 verify that it is of the same kind before we do anything else. */
1569 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1570 && (tmp = ctf_hash_lookup_type (hp, dst_fp, name)) != 0)
1573 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1576 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1577 unless dst_type is a forward declaration and src_type is a struct,
1578 union, or enum (i.e. the definition of the previous forward decl). */
1580 if (dst_type != CTF_ERR && dst_kind != kind
1581 && (dst_kind != CTF_K_FORWARD
1582 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1583 && kind != CTF_K_UNION)))
1585 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1586 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1587 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1590 /* We take special action for an integer, float, or slice since it is
1591 described not only by its name but also its encoding. For integers,
1592 bit-fields exploit this degeneracy. */
1594 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1596 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1597 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1599 if (dst_type != CTF_ERR)
1601 ctf_file_t *fp = dst_fp;
1603 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1606 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1608 /* The type that we found in the hash is also root-visible. If
1609 the two types match then use the existing one; otherwise,
1610 declare a conflict. Note: slices are not certain to match
1611 even if there is no conflict: we must check the contained type
1614 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1615 return CTF_ERR; /* errno set for us. */
1617 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1619 if (kind != CTF_K_SLICE)
1624 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1629 /* We found a non-root-visible type in the hash. We reset
1630 dst_type to ensure that we continue to look for a possible
1631 conflict in the pending list. */
1638 /* If the non-empty name was not found in the appropriate hash, search
1639 the list of pending dynamic definitions that are not yet committed.
1640 If a matching name and kind are found, assume this is the type that
1641 we are looking for. This is necessary to permit ctf_add_type() to
1642 operate recursively on entities such as a struct that contains a
1643 pointer member that refers to the same struct type. */
1645 if (dst_type == CTF_ERR && name[0] != '\0')
1647 for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1648 && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1649 dtd = ctf_list_prev (dtd))
1651 if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1652 && dtd->dtd_name != NULL && strcmp (dtd->dtd_name, name) == 0)
1654 int sroot; /* Is the src root-visible? */
1655 int droot; /* Is the dst root-visible? */
1656 int match; /* Do the encodings match? */
1658 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1659 return dtd->dtd_type;
1661 sroot = (flag & CTF_ADD_ROOT);
1662 droot = (LCTF_INFO_ISROOT (dst_fp,
1664 ctt_info) & CTF_ADD_ROOT);
1666 match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1667 sizeof (ctf_encoding_t)) == 0);
1669 /* If the types share the same encoding then return the id of the
1670 first unless one type is root-visible and the other is not; in
1671 that case the new type must get a new id if a match is never
1672 found. Note: slices are not certain to match even if there is
1673 no conflict: we must check the contained type too. */
1675 if (match && sroot == droot)
1677 if (kind != CTF_K_SLICE)
1678 return dtd->dtd_type;
1680 else if (!match && sroot && droot)
1682 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1688 src.ctb_file = src_fp;
1689 src.ctb_type = src_type;
1692 dst.ctb_file = dst_fp;
1693 dst.ctb_type = dst_type;
1696 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1697 we add a new type with the same properties as src_type to dst_fp.
1698 If dst_type is not CTF_ERR, then we verify that dst_type has the
1699 same attributes as src_type. We recurse for embedded references. */
1703 /* If we found a match we will have either returned it or declared a
1705 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1709 /* If we found a match we will have either returned it or declared a
1711 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1715 /* We have checked for conflicting encodings: now try to add the
1717 src_type = ctf_type_reference (src_fp, src_type);
1718 dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1720 if (src_type == CTF_ERR)
1721 return CTF_ERR; /* errno is set for us. */
1723 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1727 case CTF_K_VOLATILE:
1729 case CTF_K_RESTRICT:
1730 src_type = ctf_type_reference (src_fp, src_type);
1731 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1733 if (src_type == CTF_ERR)
1734 return CTF_ERR; /* errno is set for us. */
1736 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1740 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1741 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1743 src_ar.ctr_contents =
1744 ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1745 src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1746 src_ar.ctr_nelems = src_ar.ctr_nelems;
1748 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1749 return CTF_ERR; /* errno is set for us. */
1751 if (dst_type != CTF_ERR)
1753 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1754 return CTF_ERR; /* errno is set for us. */
1756 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1758 ctf_dprintf ("Conflict for type %s against ID %lx: "
1759 "array info differs, old %lx/%lx/%x; "
1760 "new: %lx/%lx/%x\n", name, dst_type,
1761 src_ar.ctr_contents, src_ar.ctr_index,
1762 src_ar.ctr_nelems, dst_ar.ctr_contents,
1763 dst_ar.ctr_index, dst_ar.ctr_nelems);
1764 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1768 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1771 case CTF_K_FUNCTION:
1772 ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1776 if (ctc.ctc_return == CTF_ERR)
1777 return CTF_ERR; /* errno is set for us. */
1779 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1790 /* Technically to match a struct or union we need to check both
1791 ways (src members vs. dst, dst members vs. src) but we make
1792 this more optimal by only checking src vs. dst and comparing
1793 the total size of the structure (which we must do anyway)
1794 which covers the possibility of dst members not in src.
1795 This optimization can be defeated for unions, but is so
1796 pathological as to render it irrelevant for our purposes. */
1798 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1800 if (ctf_type_size (src_fp, src_type) !=
1801 ctf_type_size (dst_fp, dst_type))
1803 ctf_dprintf ("Conflict for type %s against ID %lx: "
1804 "union size differs, old %li, new %li\n",
1806 (long) ctf_type_size (src_fp, src_type),
1807 (long) ctf_type_size (dst_fp, dst_type));
1808 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1811 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1813 ctf_dprintf ("Conflict for type %s against ID %lx: "
1814 "members differ, see above\n", name, dst_type);
1815 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1821 /* Unlike the other cases, copying structs and unions is done
1822 manually so as to avoid repeated lookups in ctf_add_member
1823 and to ensure the exact same member offsets as in src_type. */
1825 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1826 if (dst_type == CTF_ERR)
1827 return CTF_ERR; /* errno is set for us. */
1829 dst.ctb_type = dst_type;
1832 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1833 errs++; /* Increment errs and fail at bottom of case. */
1835 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1836 return CTF_ERR; /* errno is set for us. */
1838 size = (size_t) ssize;
1839 if (size > CTF_MAX_SIZE)
1841 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1842 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1843 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1846 dtd->dtd_data.ctt_size = (uint32_t) size;
1848 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1850 /* Make a final pass through the members changing each dmd_type (a
1851 src_fp type) to an equivalent type in dst_fp. We pass through all
1852 members, leaving any that fail set to CTF_ERR. */
1853 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1854 dmd != NULL; dmd = ctf_list_next (dmd))
1856 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1857 dmd->dmd_type)) == CTF_ERR)
1862 return CTF_ERR; /* errno is set for us. */
1867 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1869 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1870 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1872 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1873 "members differ, see above\n", name, dst_type);
1874 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1879 dst_type = ctf_add_enum (dst_fp, flag, name);
1880 if ((dst.ctb_type = dst_type) == CTF_ERR
1881 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1882 return CTF_ERR; /* errno is set for us */
1887 if (dst_type == CTF_ERR)
1889 dst_type = ctf_add_forward (dst_fp, flag,
1890 name, CTF_K_STRUCT); /* Assume STRUCT. */
1895 src_type = ctf_type_reference (src_fp, src_type);
1896 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1898 if (src_type == CTF_ERR)
1899 return CTF_ERR; /* errno is set for us. */
1901 /* If dst_type is not CTF_ERR at this point, we should check if
1902 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1903 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1904 that vary based on things like if 32-bit then pid_t is int otherwise
1905 long. We therefore omit this check and assume that if the identically
1906 named typedef already exists in dst_fp, it is correct or
1909 if (dst_type == CTF_ERR)
1911 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1916 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1922 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1923 This is useful for saving the results of dynamic CTF containers. */
1925 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1927 const unsigned char *buf = fp->ctf_base;
1928 ssize_t resid = fp->ctf_size;
1933 if ((len = gzwrite (fd, buf, resid)) <= 0)
1934 return (ctf_set_errno (fp, errno));
1942 /* Compress the specified CTF data stream and write it to the specified file
1945 ctf_compress_write (ctf_file_t *fp, int fd)
1950 ctf_header_t *hp = &h;
1951 ssize_t header_len = sizeof (ctf_header_t);
1952 ssize_t compress_len;
1953 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1958 memcpy (hp, fp->ctf_base, header_len);
1959 hp->cth_flags |= CTF_F_COMPRESS;
1961 if ((buf = ctf_alloc (max_compress_len)) == NULL)
1962 return (ctf_set_errno (fp, ECTF_ZALLOC));
1964 compress_len = max_compress_len;
1965 if ((rc = compress (buf, (uLongf *) &compress_len,
1966 fp->ctf_base + header_len,
1967 fp->ctf_size - header_len)) != Z_OK)
1969 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
1970 err = ctf_set_errno (fp, ECTF_COMPRESS);
1975 while (header_len > 0)
1977 if ((len = write (fd, hp, header_len)) < 0)
1979 err = ctf_set_errno (fp, errno);
1987 while (compress_len > 0)
1989 if ((len = write (fd, bp, compress_len)) < 0)
1991 err = ctf_set_errno (fp, errno);
1994 compress_len -= len;
2003 /* Write the uncompressed CTF data stream to the specified file descriptor.
2004 This is useful for saving the results of dynamic CTF containers. */
2006 ctf_write (ctf_file_t *fp, int fd)
2008 const unsigned char *buf = fp->ctf_base;
2009 ssize_t resid = fp->ctf_size;
2014 if ((len = write (fd, buf, resid)) < 0)
2015 return (ctf_set_errno (fp, errno));