[gdb/testsuite] Fix gdb.arch/arm-pseudo-unwind.exp with unix/mthumb
[binutils-gdb.git] / libctf / ctf-create.c
blobd67460309185ceaaffb9bd0d610a81dca2c26ef7
1 /* CTF dict creation.
2 Copyright (C) 2019-2024 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
9 version.
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/>. */
20 #include <ctf-impl.h>
21 #include <sys/param.h>
22 #include <string.h>
23 #include <unistd.h>
25 #ifndef EOVERFLOW
26 #define EOVERFLOW ERANGE
27 #endif
29 #ifndef roundup
30 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
31 #endif
33 /* The initial size of a dynamic type's vlen in members. Arbitrary: the bigger
34 this is, the less allocation needs to be done for small structure
35 initialization, and the more memory is wasted for small structures during CTF
36 construction. No effect on generated CTF or ctf_open()ed CTF. */
37 #define INITIAL_VLEN 16
39 /* Make sure the ptrtab has enough space for at least one more type.
41 We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
42 at a time. */
44 static int
45 ctf_grow_ptrtab (ctf_dict_t *fp)
47 size_t new_ptrtab_len = fp->ctf_ptrtab_len;
49 /* We allocate one more ptrtab entry than we need, for the initial zero,
50 plus one because the caller will probably allocate a new type.
52 Equally, if the ptrtab is small -- perhaps due to ctf_open of a small
53 dict -- boost it by quite a lot at first, so we don't need to keep
54 realloc()ing. */
56 if (fp->ctf_ptrtab == NULL || fp->ctf_ptrtab_len < 1024)
57 new_ptrtab_len = 1024;
58 else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
59 new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
61 if (new_ptrtab_len != fp->ctf_ptrtab_len)
63 uint32_t *new_ptrtab;
65 if ((new_ptrtab = realloc (fp->ctf_ptrtab,
66 new_ptrtab_len * sizeof (uint32_t))) == NULL)
67 return (ctf_set_errno (fp, ENOMEM));
69 fp->ctf_ptrtab = new_ptrtab;
70 memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
71 (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
72 fp->ctf_ptrtab_len = new_ptrtab_len;
74 return 0;
77 /* Make sure a vlen has enough space: expand it otherwise. Unlike the ptrtab,
78 which grows quite slowly, the vlen grows in big jumps because it is quite
79 expensive to expand: the caller has to scan the old vlen for string refs
80 first and remove them, then re-add them afterwards. The initial size is
81 more or less arbitrary. */
82 static int
83 ctf_grow_vlen (ctf_dict_t *fp, ctf_dtdef_t *dtd, size_t vlen)
85 unsigned char *old = dtd->dtd_vlen;
87 if (dtd->dtd_vlen_alloc > vlen)
88 return 0;
90 if ((dtd->dtd_vlen = realloc (dtd->dtd_vlen,
91 dtd->dtd_vlen_alloc * 2)) == NULL)
93 dtd->dtd_vlen = old;
94 return (ctf_set_errno (fp, ENOMEM));
96 memset (dtd->dtd_vlen + dtd->dtd_vlen_alloc, 0, dtd->dtd_vlen_alloc);
97 dtd->dtd_vlen_alloc *= 2;
98 return 0;
101 /* To create an empty CTF dict, we just declare a zeroed header and call
102 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new dict r/w and
103 initialize the dynamic members. We start assigning type IDs at 1 because
104 type ID 0 is used as a sentinel and a not-found indicator. */
106 ctf_dict_t *
107 ctf_create (int *errp)
109 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
111 ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
112 ctf_sect_t cts;
113 ctf_dict_t *fp;
115 libctf_init_debug();
117 structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
118 NULL, NULL);
119 unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
120 NULL, NULL);
121 enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
122 NULL, NULL);
123 names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
124 NULL, NULL);
125 if (!structs || !unions || !enums || !names)
127 ctf_set_open_errno (errp, EAGAIN);
128 goto err;
131 cts.cts_name = _CTF_SECTION;
132 cts.cts_data = &hdr;
133 cts.cts_size = sizeof (hdr);
134 cts.cts_entsize = 1;
136 if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
137 goto err;
139 /* These hashes will have been initialized with a starting size of zero,
140 which is surely wrong. Use ones with slightly larger sizes. */
141 ctf_dynhash_destroy (fp->ctf_structs);
142 ctf_dynhash_destroy (fp->ctf_unions);
143 ctf_dynhash_destroy (fp->ctf_enums);
144 ctf_dynhash_destroy (fp->ctf_names);
145 fp->ctf_structs = structs;
146 fp->ctf_unions = unions;
147 fp->ctf_enums = enums;
148 fp->ctf_names = names;
149 fp->ctf_dtoldid = 0;
150 fp->ctf_snapshot_lu = 0;
152 /* Make sure the ptrtab starts out at a reasonable size. */
154 ctf_set_ctl_hashes (fp);
155 if (ctf_grow_ptrtab (fp) < 0)
157 ctf_set_open_errno (errp, ctf_errno (fp));
158 ctf_dict_close (fp);
159 return NULL;
162 return fp;
164 err:
165 ctf_dynhash_destroy (structs);
166 ctf_dynhash_destroy (unions);
167 ctf_dynhash_destroy (enums);
168 ctf_dynhash_destroy (names);
169 return NULL;
172 /* Compatibility: just update the threshold for ctf_discard. */
174 ctf_update (ctf_dict_t *fp)
176 fp->ctf_dtoldid = fp->ctf_typemax;
177 return 0;
180 ctf_dynhash_t *
181 ctf_name_table (ctf_dict_t *fp, int kind)
183 switch (kind)
185 case CTF_K_STRUCT:
186 return fp->ctf_structs;
187 case CTF_K_UNION:
188 return fp->ctf_unions;
189 case CTF_K_ENUM:
190 return fp->ctf_enums;
191 default:
192 return fp->ctf_names;
197 ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
199 const char *name;
200 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
201 dtd) < 0)
202 return ctf_set_errno (fp, ENOMEM);
204 if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
205 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
207 if (ctf_dynhash_insert (ctf_name_table (fp, kind),
208 (char *) name, (void *) (uintptr_t)
209 dtd->dtd_type) < 0)
211 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
212 dtd->dtd_type);
213 return ctf_set_errno (fp, ENOMEM);
216 ctf_list_append (&fp->ctf_dtdefs, dtd);
217 return 0;
220 void
221 ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
223 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
224 size_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
225 int name_kind = kind;
226 const char *name;
228 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
230 switch (kind)
232 case CTF_K_STRUCT:
233 case CTF_K_UNION:
235 ctf_lmember_t *memb = (ctf_lmember_t *) dtd->dtd_vlen;
236 size_t i;
238 for (i = 0; i < vlen; i++)
239 ctf_str_remove_ref (fp, ctf_strraw (fp, memb[i].ctlm_name),
240 &memb[i].ctlm_name);
242 break;
243 case CTF_K_ENUM:
245 ctf_enum_t *en = (ctf_enum_t *) dtd->dtd_vlen;
246 size_t i;
248 for (i = 0; i < vlen; i++)
249 ctf_str_remove_ref (fp, ctf_strraw (fp, en[i].cte_name),
250 &en[i].cte_name);
252 break;
253 case CTF_K_FORWARD:
254 name_kind = dtd->dtd_data.ctt_type;
255 break;
257 free (dtd->dtd_vlen);
258 dtd->dtd_vlen_alloc = 0;
260 if (dtd->dtd_data.ctt_name
261 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
262 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
264 ctf_dynhash_remove (ctf_name_table (fp, name_kind), name);
265 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
268 ctf_list_delete (&fp->ctf_dtdefs, dtd);
269 free (dtd);
272 ctf_dtdef_t *
273 ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
275 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
276 fp = fp->ctf_parent;
278 return (ctf_dtdef_t *)
279 ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
282 ctf_dtdef_t *
283 ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
285 ctf_id_t idx;
287 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
288 fp = fp->ctf_parent;
290 idx = LCTF_TYPE_TO_INDEX(fp, id);
292 if ((unsigned long) idx <= fp->ctf_typemax)
293 return ctf_dtd_lookup (fp, id);
294 return NULL;
297 static int
298 ctf_static_type (const ctf_dict_t *fp, ctf_id_t id)
300 ctf_id_t idx;
302 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
303 fp = fp->ctf_parent;
305 idx = LCTF_TYPE_TO_INDEX(fp, id);
307 return ((unsigned long) idx <= fp->ctf_stypes);
311 ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
313 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
314 return ctf_set_errno (fp, ENOMEM);
315 ctf_list_append (&fp->ctf_dvdefs, dvd);
316 return 0;
319 void
320 ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
322 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
323 free (dvd->dvd_name);
325 ctf_list_delete (&fp->ctf_dvdefs, dvd);
326 free (dvd);
329 ctf_dvdef_t *
330 ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
332 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
335 /* Discard all of the dynamic type definitions and variable definitions that
336 have been added to the dict since the last call to ctf_update(). We locate
337 such types by scanning the dtd list and deleting elements that have type IDs
338 greater than ctf_dtoldid, which is set by ctf_update(), above, and by
339 scanning the variable list and deleting elements that have update IDs equal
340 to the current value of the last-update snapshot count (indicating that they
341 were added after the most recent call to ctf_update()). */
343 ctf_discard (ctf_dict_t *fp)
345 ctf_snapshot_id_t last_update =
346 { fp->ctf_dtoldid,
347 fp->ctf_snapshot_lu + 1 };
349 return (ctf_rollback (fp, last_update));
352 ctf_snapshot_id_t
353 ctf_snapshot (ctf_dict_t *fp)
355 ctf_snapshot_id_t snapid;
356 snapid.dtd_id = fp->ctf_typemax;
357 snapid.snapshot_id = fp->ctf_snapshots++;
358 return snapid;
361 /* Like ctf_discard(), only discards everything after a particular ID. */
363 ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
365 ctf_dtdef_t *dtd, *ntd;
366 ctf_dvdef_t *dvd, *nvd;
368 if (id.snapshot_id < fp->ctf_stypes)
369 return (ctf_set_errno (fp, ECTF_RDONLY));
371 if (fp->ctf_snapshot_lu >= id.snapshot_id)
372 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
374 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
376 int kind;
377 const char *name;
379 ntd = ctf_list_next (dtd);
381 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
382 continue;
384 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
385 if (kind == CTF_K_FORWARD)
386 kind = dtd->dtd_data.ctt_type;
388 if (dtd->dtd_data.ctt_name
389 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
390 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
392 ctf_dynhash_remove (ctf_name_table (fp, kind), name);
393 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
396 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
397 ctf_dtd_delete (fp, dtd);
400 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
402 nvd = ctf_list_next (dvd);
404 if (dvd->dvd_snapshots <= id.snapshot_id)
405 continue;
407 ctf_dvd_delete (fp, dvd);
410 fp->ctf_typemax = id.dtd_id;
411 fp->ctf_snapshots = id.snapshot_id;
413 return 0;
416 /* Note: vlen is the amount of space *allocated* for the vlen. It may well not
417 be the amount of space used (yet): the space used is declared in per-kind
418 fashion in the dtd_data's info word. */
419 static ctf_id_t
420 ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
421 size_t vlen, ctf_dtdef_t **rp)
423 ctf_dtdef_t *dtd;
424 ctf_id_t type;
426 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
427 return (ctf_set_typed_errno (fp, EINVAL));
429 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
430 return (ctf_set_typed_errno (fp, ECTF_FULL));
432 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
433 return (ctf_set_typed_errno (fp, ECTF_FULL));
435 /* Prohibit addition of a root-visible type that is already present
436 in the non-dynamic portion. */
438 if (flag == CTF_ADD_ROOT && name != NULL && name[0] != '\0')
440 ctf_id_t existing;
442 if (((existing = ctf_dynhash_lookup_type (ctf_name_table (fp, kind),
443 name)) > 0)
444 && ctf_static_type (fp, existing))
445 return (ctf_set_typed_errno (fp, ECTF_RDONLY));
448 /* Make sure ptrtab always grows to be big enough for all types. */
449 if (ctf_grow_ptrtab (fp) < 0)
450 return CTF_ERR; /* errno is set for us. */
452 if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
453 return (ctf_set_typed_errno (fp, EAGAIN));
455 dtd->dtd_vlen_alloc = vlen;
456 if (vlen > 0)
458 if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
459 goto oom;
461 else
462 dtd->dtd_vlen = NULL;
464 type = ++fp->ctf_typemax;
465 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
467 dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
468 dtd->dtd_type = type;
470 if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
471 goto oom;
473 if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
474 goto err; /* errno is set for us. */
476 *rp = dtd;
477 return type;
479 oom:
480 ctf_set_errno (fp, EAGAIN);
481 err:
482 free (dtd->dtd_vlen);
483 free (dtd);
484 return CTF_ERR;
487 /* When encoding integer sizes, we want to convert a byte count in the range
488 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
489 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
490 static size_t
491 clp2 (size_t x)
493 x--;
495 x |= (x >> 1);
496 x |= (x >> 2);
497 x |= (x >> 4);
498 x |= (x >> 8);
499 x |= (x >> 16);
501 return (x + 1);
504 ctf_id_t
505 ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
506 const char *name, const ctf_encoding_t *ep, uint32_t kind)
508 ctf_dtdef_t *dtd;
509 ctf_id_t type;
510 uint32_t encoding;
512 if (ep == NULL)
513 return (ctf_set_typed_errno (fp, EINVAL));
515 if (name == NULL || name[0] == '\0')
516 return (ctf_set_typed_errno (fp, ECTF_NONAME));
518 if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
519 return CTF_ERR; /* errno is set for us. */
521 if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
522 &dtd)) == CTF_ERR)
523 return CTF_ERR; /* errno is set for us. */
525 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
526 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
527 / CHAR_BIT);
528 switch (kind)
530 case CTF_K_INTEGER:
531 encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
532 break;
533 case CTF_K_FLOAT:
534 encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
535 break;
536 default:
537 /* ctf_assert is opaque with -fno-inline. This dead code avoids
538 a warning about "encoding" being used uninitialized. */
539 return CTF_ERR;
541 memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
543 return type;
546 ctf_id_t
547 ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
549 ctf_dtdef_t *dtd;
550 ctf_id_t type;
551 ctf_dict_t *tmp = fp;
552 int child = fp->ctf_flags & LCTF_CHILD;
554 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
555 return (ctf_set_typed_errno (fp, EINVAL));
557 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
558 return CTF_ERR; /* errno is set for us. */
560 if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
561 return CTF_ERR; /* errno is set for us. */
563 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
564 dtd->dtd_data.ctt_type = (uint32_t) ref;
566 if (kind != CTF_K_POINTER)
567 return type;
569 /* If we are adding a pointer, update the ptrtab, pointing at this type from
570 the type it points to. Note that ctf_typemax is at this point one higher
571 than we want to check against, because it's just been incremented for the
572 addition of this type. The pptrtab is lazily-updated as needed, so is not
573 touched here. */
575 uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
576 uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
578 if (LCTF_TYPE_ISCHILD (fp, ref) == child
579 && ref_idx < fp->ctf_typemax)
580 fp->ctf_ptrtab[ref_idx] = type_idx;
582 return type;
585 ctf_id_t
586 ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
587 const ctf_encoding_t *ep)
589 ctf_dtdef_t *dtd;
590 ctf_slice_t slice;
591 ctf_id_t resolved_ref = ref;
592 ctf_id_t type;
593 int kind;
594 const ctf_type_t *tp;
595 ctf_dict_t *tmp = fp;
597 if (ep == NULL)
598 return (ctf_set_typed_errno (fp, EINVAL));
600 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
601 return (ctf_set_typed_errno (fp, ECTF_SLICEOVERFLOW));
603 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
604 return (ctf_set_typed_errno (fp, EINVAL));
606 if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
607 return CTF_ERR; /* errno is set for us. */
609 /* Make sure we ultimately point to an integral type. We also allow slices to
610 point to the unimplemented type, for now, because the compiler can emit
611 such slices, though they're not very much use. */
613 resolved_ref = ctf_type_resolve_unsliced (fp, ref);
614 kind = ctf_type_kind_unsliced (fp, resolved_ref);
616 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
617 (kind != CTF_K_ENUM)
618 && (ref != 0))
619 return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
621 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
622 sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
623 return CTF_ERR; /* errno is set for us. */
625 memset (&slice, 0, sizeof (ctf_slice_t));
627 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
628 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
629 / CHAR_BIT);
630 slice.cts_type = (uint32_t) ref;
631 slice.cts_bits = ep->cte_bits;
632 slice.cts_offset = ep->cte_offset;
633 memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
635 return type;
638 ctf_id_t
639 ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
640 const char *name, const ctf_encoding_t *ep)
642 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
645 ctf_id_t
646 ctf_add_float (ctf_dict_t *fp, uint32_t flag,
647 const char *name, const ctf_encoding_t *ep)
649 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
652 ctf_id_t
653 ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
655 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
658 ctf_id_t
659 ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
661 ctf_dtdef_t *dtd;
662 ctf_array_t cta;
663 ctf_id_t type;
664 ctf_dict_t *tmp = fp;
666 if (arp == NULL)
667 return (ctf_set_typed_errno (fp, EINVAL));
669 if (arp->ctr_contents != 0
670 && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
671 return CTF_ERR; /* errno is set for us. */
673 tmp = fp;
674 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
675 return CTF_ERR; /* errno is set for us. */
677 if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
679 ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
680 _("ctf_add_array: index type %lx is incomplete"),
681 arp->ctr_contents);
682 return (ctf_set_typed_errno (fp, ECTF_INCOMPLETE));
685 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
686 sizeof (ctf_array_t), &dtd)) == CTF_ERR)
687 return CTF_ERR; /* errno is set for us. */
689 memset (&cta, 0, sizeof (ctf_array_t));
691 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
692 dtd->dtd_data.ctt_size = 0;
693 cta.cta_contents = (uint32_t) arp->ctr_contents;
694 cta.cta_index = (uint32_t) arp->ctr_index;
695 cta.cta_nelems = arp->ctr_nelems;
696 memcpy (dtd->dtd_vlen, &cta, sizeof (ctf_array_t));
698 return type;
702 ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
704 ctf_dict_t *ofp = fp;
705 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
706 ctf_array_t *vlen;
708 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
709 fp = fp->ctf_parent;
711 /* You can only call ctf_set_array on a type you have added, not a
712 type that was read in via ctf_open(). */
713 if (type < fp->ctf_stypes)
714 return (ctf_set_errno (ofp, ECTF_RDONLY));
716 if (dtd == NULL
717 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
718 return (ctf_set_errno (ofp, ECTF_BADID));
720 vlen = (ctf_array_t *) dtd->dtd_vlen;
721 vlen->cta_contents = (uint32_t) arp->ctr_contents;
722 vlen->cta_index = (uint32_t) arp->ctr_index;
723 vlen->cta_nelems = arp->ctr_nelems;
725 return 0;
728 ctf_id_t
729 ctf_add_function (ctf_dict_t *fp, uint32_t flag,
730 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
732 ctf_dtdef_t *dtd;
733 ctf_id_t type;
734 uint32_t vlen;
735 uint32_t *vdat;
736 ctf_dict_t *tmp = fp;
737 size_t initial_vlen;
738 size_t i;
740 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
741 || (ctc->ctc_argc != 0 && argv == NULL))
742 return (ctf_set_typed_errno (fp, EINVAL));
744 vlen = ctc->ctc_argc;
745 if (ctc->ctc_flags & CTF_FUNC_VARARG)
746 vlen++; /* Add trailing zero to indicate varargs (see below). */
748 if (ctc->ctc_return != 0
749 && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
750 return CTF_ERR; /* errno is set for us. */
752 if (vlen > CTF_MAX_VLEN)
753 return (ctf_set_typed_errno (fp, EOVERFLOW));
755 /* One word extra allocated for padding for 4-byte alignment if need be.
756 Not reflected in vlen: we don't want to copy anything into it, and
757 it's in addition to (e.g.) the trailing 0 indicating varargs. */
759 initial_vlen = (sizeof (uint32_t) * (vlen + (vlen & 1)));
760 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
761 initial_vlen, &dtd)) == CTF_ERR)
762 return CTF_ERR; /* errno is set for us. */
764 vdat = (uint32_t *) dtd->dtd_vlen;
766 for (i = 0; i < ctc->ctc_argc; i++)
768 tmp = fp;
769 if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
770 return CTF_ERR; /* errno is set for us. */
771 vdat[i] = (uint32_t) argv[i];
774 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
775 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
777 if (ctc->ctc_flags & CTF_FUNC_VARARG)
778 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
780 return type;
783 ctf_id_t
784 ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
785 size_t size)
787 ctf_dtdef_t *dtd;
788 ctf_id_t type = 0;
789 size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
791 /* Promote root-visible forwards to structs. */
792 if (name != NULL)
793 type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
795 /* Prohibit promotion if this type was ctf_open()ed. */
796 if (type > 0 && type < fp->ctf_stypes)
797 return (ctf_set_errno (fp, ECTF_RDONLY));
799 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
800 dtd = ctf_dtd_lookup (fp, type);
801 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
802 initial_vlen, &dtd)) == CTF_ERR)
803 return CTF_ERR; /* errno is set for us. */
805 /* Forwards won't have any vlen yet. */
806 if (dtd->dtd_vlen_alloc == 0)
808 if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
809 return (ctf_set_typed_errno (fp, ENOMEM));
810 dtd->dtd_vlen_alloc = initial_vlen;
813 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
814 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
815 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
816 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
818 return type;
821 ctf_id_t
822 ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
824 return (ctf_add_struct_sized (fp, flag, name, 0));
827 ctf_id_t
828 ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
829 size_t size)
831 ctf_dtdef_t *dtd;
832 ctf_id_t type = 0;
833 size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
835 /* Promote root-visible forwards to unions. */
836 if (name != NULL)
837 type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
839 /* Prohibit promotion if this type was ctf_open()ed. */
840 if (type > 0 && type < fp->ctf_stypes)
841 return (ctf_set_errno (fp, ECTF_RDONLY));
843 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
844 dtd = ctf_dtd_lookup (fp, type);
845 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
846 initial_vlen, &dtd)) == CTF_ERR)
847 return CTF_ERR; /* errno is set for us. */
849 /* Forwards won't have any vlen yet. */
850 if (dtd->dtd_vlen_alloc == 0)
852 if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
853 return (ctf_set_typed_errno (fp, ENOMEM));
854 dtd->dtd_vlen_alloc = initial_vlen;
857 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
858 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
859 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
860 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
862 return type;
865 ctf_id_t
866 ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
868 return (ctf_add_union_sized (fp, flag, name, 0));
871 ctf_id_t
872 ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
874 ctf_dtdef_t *dtd;
875 ctf_id_t type = 0;
876 size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN;
878 /* Promote root-visible forwards to enums. */
879 if (name != NULL)
880 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
882 /* Prohibit promotion if this type was ctf_open()ed. */
883 if (type > 0 && type < fp->ctf_stypes)
884 return (ctf_set_errno (fp, ECTF_RDONLY));
886 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
887 dtd = ctf_dtd_lookup (fp, type);
888 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
889 initial_vlen, &dtd)) == CTF_ERR)
890 return CTF_ERR; /* errno is set for us. */
892 /* Forwards won't have any vlen yet. */
893 if (dtd->dtd_vlen_alloc == 0)
895 if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
896 return (ctf_set_typed_errno (fp, ENOMEM));
897 dtd->dtd_vlen_alloc = initial_vlen;
900 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
901 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
903 return type;
906 ctf_id_t
907 ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
908 const ctf_encoding_t *ep)
910 ctf_id_t type = 0;
912 /* First, create the enum if need be, using most of the same machinery as
913 ctf_add_enum(), to ensure that we do not allow things past that are not
914 enums or forwards to them. (This includes other slices: you cannot slice a
915 slice, which would be a useless thing to do anyway.) */
917 if (name != NULL)
918 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
920 if (type != 0)
922 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
923 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
924 return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
926 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
927 return CTF_ERR; /* errno is set for us. */
929 /* Now attach a suitable slice to it. */
931 return ctf_add_slice (fp, flag, type, ep);
934 ctf_id_t
935 ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
936 uint32_t kind)
938 ctf_dtdef_t *dtd;
939 ctf_id_t type = 0;
941 if (!ctf_forwardable_kind (kind))
942 return (ctf_set_typed_errno (fp, ECTF_NOTSUE));
944 if (name == NULL || name[0] == '\0')
945 return (ctf_set_typed_errno (fp, ECTF_NONAME));
947 /* If the type is already defined or exists as a forward tag, just return
948 the ctf_id_t of the existing definition. Since this changes nothing,
949 it's safe to do even on the read-only portion of the dict. */
951 type = ctf_lookup_by_rawname (fp, kind, name);
953 if (type)
954 return type;
956 if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
957 return CTF_ERR; /* errno is set for us. */
959 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
960 dtd->dtd_data.ctt_type = kind;
962 return type;
965 ctf_id_t
966 ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name)
968 ctf_dtdef_t *dtd;
969 ctf_id_t type = 0;
971 /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN)
972 or just return it. */
974 if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT
975 && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name)))
977 if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN)
978 return type;
979 else
981 ctf_err_warn (fp, 1, ECTF_CONFLICT,
982 _("ctf_add_unknown: cannot add unknown type "
983 "named %s: type of this name already defined"),
984 name ? name : _("(unnamed type)"));
985 return (ctf_set_typed_errno (fp, ECTF_CONFLICT));
989 if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR)
990 return CTF_ERR; /* errno is set for us. */
992 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0);
993 dtd->dtd_data.ctt_type = 0;
995 return type;
998 ctf_id_t
999 ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
1000 ctf_id_t ref)
1002 ctf_dtdef_t *dtd;
1003 ctf_id_t type;
1004 ctf_dict_t *tmp = fp;
1006 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1007 return (ctf_set_typed_errno (fp, EINVAL));
1009 if (name == NULL || name[0] == '\0')
1010 return (ctf_set_typed_errno (fp, ECTF_NONAME));
1012 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
1013 return CTF_ERR; /* errno is set for us. */
1015 if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
1016 &dtd)) == CTF_ERR)
1017 return CTF_ERR; /* errno is set for us. */
1019 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1020 dtd->dtd_data.ctt_type = (uint32_t) ref;
1022 return type;
1025 ctf_id_t
1026 ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1028 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1031 ctf_id_t
1032 ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1034 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1037 ctf_id_t
1038 ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1040 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1044 ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
1045 int value)
1047 ctf_dict_t *ofp = fp;
1048 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1049 unsigned char *old_vlen;
1050 ctf_enum_t *en;
1052 uint32_t kind, vlen, root;
1054 if (name == NULL)
1055 return (ctf_set_errno (fp, EINVAL));
1057 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, enid))
1058 fp = fp->ctf_parent;
1060 if (enid < fp->ctf_stypes)
1061 return (ctf_set_errno (ofp, ECTF_RDONLY));
1063 if (dtd == NULL)
1064 return (ctf_set_errno (ofp, ECTF_BADID));
1066 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1067 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1068 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1070 /* Enumeration constant names are only added, and only checked for duplicates,
1071 if the enum they are part of is a root-visible type. */
1073 if (root == CTF_ADD_ROOT && ctf_dynhash_lookup (fp->ctf_names, name))
1074 return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1076 if (kind != CTF_K_ENUM)
1077 return (ctf_set_errno (ofp, ECTF_NOTENUM));
1079 if (vlen == CTF_MAX_VLEN)
1080 return (ctf_set_errno (ofp, ECTF_DTFULL));
1082 old_vlen = dtd->dtd_vlen;
1084 if (ctf_grow_vlen (fp, dtd, sizeof (ctf_enum_t) * (vlen + 1)) < 0)
1085 return -1; /* errno is set for us. */
1087 en = (ctf_enum_t *) dtd->dtd_vlen;
1089 /* Remove refs in the old vlen region and reapply them. */
1091 ctf_str_move_refs (fp, old_vlen, sizeof (ctf_enum_t) * vlen, dtd->dtd_vlen);
1093 /* Check for constant duplication within any given enum: only needed for
1094 non-root-visible types, since the duplicate detection above does the job
1095 for root-visible types just fine. */
1097 if (root == CTF_ADD_NONROOT)
1099 size_t i;
1101 for (i = 0; i < vlen; i++)
1102 if (strcmp (ctf_strptr (fp, en[i].cte_name), name) == 0)
1103 return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1106 en[vlen].cte_name = ctf_str_add_movable_ref (fp, name, &en[vlen].cte_name);
1107 en[vlen].cte_value = value;
1109 if (en[vlen].cte_name == 0 && name != NULL && name[0] != '\0')
1110 return (ctf_set_errno (ofp, ctf_errno (fp)));
1112 /* Put the newly-added enumerator name into the name table if this type is
1113 root-visible. */
1115 if (root == CTF_ADD_ROOT)
1117 if (ctf_dynhash_insert (fp->ctf_names,
1118 (char *) ctf_strptr (fp, en[vlen].cte_name),
1119 (void *) (uintptr_t) enid) < 0)
1120 return ctf_set_errno (fp, ENOMEM);
1123 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1125 return 0;
1129 ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1130 ctf_id_t type, unsigned long bit_offset)
1132 ctf_dict_t *ofp = fp;
1133 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1135 ssize_t msize, malign, ssize;
1136 uint32_t kind, vlen, root;
1137 size_t i;
1138 int is_incomplete = 0;
1139 unsigned char *old_vlen;
1140 ctf_lmember_t *memb;
1142 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, souid))
1144 /* Adding a child type to a parent, even via the child, is prohibited.
1145 Otherwise, climb to the parent and do all work there. */
1147 if (LCTF_TYPE_ISCHILD (fp, type))
1148 return (ctf_set_errno (ofp, ECTF_BADID));
1150 fp = fp->ctf_parent;
1153 if (souid < fp->ctf_stypes)
1154 return (ctf_set_errno (ofp, ECTF_RDONLY));
1156 if (dtd == NULL)
1157 return (ctf_set_errno (ofp, ECTF_BADID));
1159 if (name != NULL && name[0] == '\0')
1160 name = NULL;
1162 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1163 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1164 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1166 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1167 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1169 if (vlen == CTF_MAX_VLEN)
1170 return (ctf_set_errno (ofp, ECTF_DTFULL));
1172 old_vlen = dtd->dtd_vlen;
1173 if (ctf_grow_vlen (fp, dtd, sizeof (ctf_lmember_t) * (vlen + 1)) < 0)
1174 return (ctf_set_errno (ofp, ctf_errno (fp)));
1175 memb = (ctf_lmember_t *) dtd->dtd_vlen;
1177 /* Remove pending refs in the old vlen region and reapply them. */
1179 ctf_str_move_refs (fp, old_vlen, sizeof (ctf_lmember_t) * vlen, dtd->dtd_vlen);
1181 if (name != NULL)
1183 for (i = 0; i < vlen; i++)
1184 if (strcmp (ctf_strptr (fp, memb[i].ctlm_name), name) == 0)
1185 return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1188 if ((msize = ctf_type_size (fp, type)) < 0 ||
1189 (malign = ctf_type_align (fp, type)) < 0)
1191 /* The unimplemented type, and any type that resolves to it, has no size
1192 and no alignment: it can correspond to any number of compiler-inserted
1193 types. We allow incomplete types through since they are routinely
1194 added to the ends of structures, and can even be added elsewhere in
1195 structures by the deduplicator. They are assumed to be zero-size with
1196 no alignment: this is often wrong, but problems can be avoided in this
1197 case by explicitly specifying the size of the structure via the _sized
1198 functions. The deduplicator always does this. */
1200 msize = 0;
1201 malign = 0;
1202 if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
1203 ctf_set_errno (fp, 0);
1204 else if (ctf_errno (fp) == ECTF_INCOMPLETE)
1205 is_incomplete = 1;
1206 else
1207 return -1; /* errno is set for us. */
1210 memb[vlen].ctlm_name = ctf_str_add_movable_ref (fp, name, &memb[vlen].ctlm_name);
1211 memb[vlen].ctlm_type = type;
1212 if (memb[vlen].ctlm_name == 0 && name != NULL && name[0] != '\0')
1213 return -1; /* errno is set for us. */
1215 if (kind == CTF_K_STRUCT && vlen != 0)
1217 if (bit_offset == (unsigned long) - 1)
1219 /* Natural alignment. */
1221 ctf_id_t ltype = ctf_type_resolve (fp, memb[vlen - 1].ctlm_type);
1222 size_t off = CTF_LMEM_OFFSET(&memb[vlen - 1]);
1224 ctf_encoding_t linfo;
1225 ssize_t lsize;
1227 /* Propagate any error from ctf_type_resolve. If the last member was
1228 of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
1229 cannot insert right after such a member without explicit offset
1230 specification, because its alignment and size is not known. */
1231 if (ltype == CTF_ERR)
1232 return -1; /* errno is set for us. */
1234 if (is_incomplete)
1236 ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
1237 _("ctf_add_member_offset: cannot add member %s of "
1238 "incomplete type %lx to struct %lx without "
1239 "specifying explicit offset\n"),
1240 name ? name : _("(unnamed member)"), type, souid);
1241 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1244 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1245 off += linfo.cte_bits;
1246 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1247 off += lsize * CHAR_BIT;
1248 else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
1250 const char *lname = ctf_strraw (fp, memb[vlen - 1].ctlm_name);
1252 ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
1253 _("ctf_add_member_offset: cannot add member %s of "
1254 "type %lx to struct %lx without specifying "
1255 "explicit offset after member %s of type %lx, "
1256 "which is an incomplete type\n"),
1257 name ? name : _("(unnamed member)"), type, souid,
1258 lname ? lname : _("(unnamed member)"), ltype);
1259 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1262 /* Round up the offset of the end of the last member to
1263 the next byte boundary, convert 'off' to bytes, and
1264 then round it up again to the next multiple of the
1265 alignment required by the new member. Finally,
1266 convert back to bits and store the result in
1267 dmd_offset. Technically we could do more efficient
1268 packing if the new member is a bit-field, but we're
1269 the "compiler" and ANSI says we can do as we choose. */
1271 off = roundup (off, CHAR_BIT) / CHAR_BIT;
1272 off = roundup (off, MAX (malign, 1));
1273 memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (off * CHAR_BIT);
1274 memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (off * CHAR_BIT);
1275 ssize = off + msize;
1277 else
1279 /* Specified offset in bits. */
1281 memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (bit_offset);
1282 memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (bit_offset);
1283 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1284 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1287 else
1289 memb[vlen].ctlm_offsethi = 0;
1290 memb[vlen].ctlm_offsetlo = 0;
1291 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1292 ssize = MAX (ssize, msize);
1295 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1296 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1297 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1298 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1300 return 0;
1304 ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1305 ctf_id_t type, unsigned long bit_offset,
1306 const ctf_encoding_t encoding)
1308 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1309 int kind;
1310 int otype = type;
1312 if (dtd == NULL)
1313 return (ctf_set_errno (fp, ECTF_BADID));
1315 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1317 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1318 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1320 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1321 return -1; /* errno is set for us. */
1323 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1327 ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1328 ctf_id_t type)
1330 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1333 /* Add a variable regardless of whether or not it is already present.
1335 Internal use only. */
1337 ctf_add_variable_forced (ctf_dict_t *fp, const char *name, ctf_id_t ref)
1339 ctf_dvdef_t *dvd;
1340 ctf_dict_t *tmp = fp;
1342 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1343 return -1; /* errno is set for us. */
1345 /* Make sure this type is representable. */
1346 if ((ctf_type_resolve (fp, ref) == CTF_ERR)
1347 && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
1348 return -1;
1350 if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
1351 return (ctf_set_errno (fp, EAGAIN));
1353 if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
1355 free (dvd);
1356 return (ctf_set_errno (fp, EAGAIN));
1358 dvd->dvd_type = ref;
1359 dvd->dvd_snapshots = fp->ctf_snapshots;
1361 if (ctf_dvd_insert (fp, dvd) < 0)
1363 free (dvd->dvd_name);
1364 free (dvd);
1365 return -1; /* errno is set for us. */
1368 return 0;
1372 ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
1374 if (ctf_lookup_variable_here (fp, name) != CTF_ERR)
1375 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1377 if (ctf_errno (fp) != ECTF_NOTYPEDAT)
1378 return -1; /* errno is set for us. */
1380 return ctf_add_variable_forced (fp, name, ref);
1383 /* Add a function or object symbol regardless of whether or not it is already
1384 present (already existing symbols are silently overwritten).
1386 Internal use only. */
1388 ctf_add_funcobjt_sym_forced (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
1390 ctf_dict_t *tmp = fp;
1391 char *dupname;
1392 ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
1394 if (ctf_lookup_by_id (&tmp, id) == NULL)
1395 return -1; /* errno is set for us. */
1397 if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
1398 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1400 if ((dupname = strdup (name)) == NULL)
1401 return (ctf_set_errno (fp, ENOMEM));
1403 if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
1405 free (dupname);
1406 return (ctf_set_errno (fp, ENOMEM));
1408 return 0;
1412 ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
1414 if (ctf_lookup_by_sym_or_name (fp, 0, name, 0, is_function) != CTF_ERR)
1415 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1417 return ctf_add_funcobjt_sym_forced (fp, is_function, name, id);
1421 ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1423 return (ctf_add_funcobjt_sym (fp, 0, name, id));
1427 ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1429 return (ctf_add_funcobjt_sym (fp, 1, name, id));
1432 typedef struct ctf_bundle
1434 ctf_dict_t *ctb_dict; /* CTF dict handle. */
1435 ctf_id_t ctb_type; /* CTF type identifier. */
1436 ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
1437 } ctf_bundle_t;
1439 static int
1440 enumcmp (const char *name, int value, void *arg)
1442 ctf_bundle_t *ctb = arg;
1443 int bvalue;
1445 if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
1447 ctf_err_warn (ctb->ctb_dict, 0, 0,
1448 _("conflict due to enum %s iteration error"), name);
1449 return 1;
1451 if (value != bvalue)
1453 ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1454 _("conflict due to enum value change: %i versus %i"),
1455 value, bvalue);
1456 return 1;
1458 return 0;
1461 static int
1462 enumadd (const char *name, int value, void *arg)
1464 ctf_bundle_t *ctb = arg;
1466 return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
1467 name, value) < 0);
1470 static int
1471 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1472 void *arg)
1474 ctf_bundle_t *ctb = arg;
1475 ctf_membinfo_t ctm;
1477 /* Don't check nameless members (e.g. anonymous structs/unions) against each
1478 other. */
1479 if (name[0] == 0)
1480 return 0;
1482 if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
1484 ctf_err_warn (ctb->ctb_dict, 0, 0,
1485 _("conflict due to struct member %s iteration error"),
1486 name);
1487 return 1;
1489 if (ctm.ctm_offset != offset)
1491 ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1492 _("conflict due to struct member %s offset change: "
1493 "%lx versus %lx"),
1494 name, ctm.ctm_offset, offset);
1495 return 1;
1497 return 0;
1500 /* Record the correspondence between a source and ctf_add_type()-added
1501 destination type: both types are translated into parent type IDs if need be,
1502 so they relate to the actual dictionary they are in. Outside controlled
1503 circumstances (like linking) it is probably not useful to do more than
1504 compare these pointers, since there is nothing stopping the user closing the
1505 source dict whenever they want to.
1507 Our OOM handling here is just to not do anything, because this is called deep
1508 enough in the call stack that doing anything useful is painfully difficult:
1509 the worst consequence if we do OOM is a bit of type duplication anyway. */
1511 static void
1512 ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
1513 ctf_dict_t *dst_fp, ctf_id_t dst_type)
1515 if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1516 src_fp = src_fp->ctf_parent;
1518 src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1520 if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
1521 dst_fp = dst_fp->ctf_parent;
1523 dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
1525 if (dst_fp->ctf_link_type_mapping == NULL)
1527 ctf_hash_fun f = ctf_hash_type_key;
1528 ctf_hash_eq_fun e = ctf_hash_eq_type_key;
1530 if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
1531 NULL)) == NULL)
1532 return;
1535 ctf_link_type_key_t *key;
1536 key = calloc (1, sizeof (struct ctf_link_type_key));
1537 if (!key)
1538 return;
1540 key->cltk_fp = src_fp;
1541 key->cltk_idx = src_type;
1543 /* No OOM checking needed, because if this doesn't work the worst we'll do is
1544 add a few more duplicate types (which will probably run out of memory
1545 anyway). */
1546 ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
1547 (void *) (uintptr_t) dst_type);
1550 /* Look up a type mapping: return 0 if none. The DST_FP is modified to point to
1551 the parent if need be. The ID returned is from the dst_fp's perspective. */
1552 static ctf_id_t
1553 ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
1555 ctf_link_type_key_t key;
1556 ctf_dict_t *target_fp = *dst_fp;
1557 ctf_id_t dst_type = 0;
1559 if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1560 src_fp = src_fp->ctf_parent;
1562 src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1563 key.cltk_fp = src_fp;
1564 key.cltk_idx = src_type;
1566 if (target_fp->ctf_link_type_mapping)
1567 dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1568 &key);
1570 if (dst_type != 0)
1572 dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1573 target_fp->ctf_parent != NULL);
1574 *dst_fp = target_fp;
1575 return dst_type;
1578 if (target_fp->ctf_parent)
1579 target_fp = target_fp->ctf_parent;
1580 else
1581 return 0;
1583 if (target_fp->ctf_link_type_mapping)
1584 dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1585 &key);
1587 if (dst_type)
1588 dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1589 target_fp->ctf_parent != NULL);
1591 *dst_fp = target_fp;
1592 return dst_type;
1595 /* The ctf_add_type routine is used to copy a type from a source CTF dictionary
1596 to a dynamic destination dictionary. This routine operates recursively by
1597 following the source type's links and embedded member types. If the
1598 destination dict already contains a named type which has the same attributes,
1599 then we succeed and return this type but no changes occur. */
1600 static ctf_id_t
1601 ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
1602 ctf_dict_t *proc_tracking_fp)
1604 ctf_id_t dst_type = CTF_ERR;
1605 uint32_t dst_kind = CTF_K_UNKNOWN;
1606 ctf_dict_t *tmp_fp = dst_fp;
1607 ctf_id_t tmp;
1609 const char *name;
1610 uint32_t kind, forward_kind, flag, vlen;
1612 const ctf_type_t *src_tp, *dst_tp;
1613 ctf_bundle_t src, dst;
1614 ctf_encoding_t src_en, dst_en;
1615 ctf_arinfo_t src_ar, dst_ar;
1617 ctf_funcinfo_t ctc;
1619 ctf_id_t orig_src_type = src_type;
1621 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1622 return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1624 if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
1625 && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
1626 return (ctf_set_typed_errno (dst_fp, ECTF_NONREPRESENTABLE));
1628 name = ctf_strptr (src_fp, src_tp->ctt_name);
1629 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1630 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1631 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1633 /* If this is a type we are currently in the middle of adding, hand it
1634 straight back. (This lets us handle self-referential structures without
1635 considering forwards and empty structures the same as their completed
1636 forms.) */
1638 tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1640 if (tmp != 0)
1642 if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1643 (void *) (uintptr_t) src_type))
1644 return tmp;
1646 /* If this type has already been added from this dictionary, and is the
1647 same kind and (if a struct or union) has the same number of members,
1648 hand it straight back. */
1650 if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
1652 if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1653 || kind == CTF_K_ENUM)
1655 if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1656 if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1657 return tmp;
1659 else
1660 return tmp;
1664 forward_kind = kind;
1665 if (kind == CTF_K_FORWARD)
1666 forward_kind = src_tp->ctt_type;
1668 /* If the source type has a name and is a root type (visible at the top-level
1669 scope), lookup the name in the destination dictionary and verify that it is
1670 of the same kind before we do anything else. */
1672 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1673 && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
1675 dst_type = tmp;
1676 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1679 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1680 unless dst_type is a forward declaration and src_type is a struct,
1681 union, or enum (i.e. the definition of the previous forward decl).
1683 We also allow addition in the opposite order (addition of a forward when a
1684 struct, union, or enum already exists), which is a NOP and returns the
1685 already-present struct, union, or enum. */
1687 if (dst_type != CTF_ERR && dst_kind != kind)
1689 if (kind == CTF_K_FORWARD
1690 && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1691 || dst_kind == CTF_K_UNION))
1693 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1694 return dst_type;
1697 if (dst_kind != CTF_K_FORWARD
1698 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1699 && kind != CTF_K_UNION))
1701 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1702 _("ctf_add_type: conflict for type %s: "
1703 "kinds differ, new: %i; old (ID %lx): %i"),
1704 name, kind, dst_type, dst_kind);
1705 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1709 /* We take special action for an integer, float, or slice since it is
1710 described not only by its name but also its encoding. For integers,
1711 bit-fields exploit this degeneracy. */
1713 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1715 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1716 return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1718 if (dst_type != CTF_ERR)
1720 ctf_dict_t *fp = dst_fp;
1722 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1723 return CTF_ERR;
1725 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1726 return CTF_ERR; /* errno set for us. */
1728 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1730 /* The type that we found in the hash is also root-visible. If
1731 the two types match then use the existing one; otherwise,
1732 declare a conflict. Note: slices are not certain to match
1733 even if there is no conflict: we must check the contained type
1734 too. */
1736 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1738 if (kind != CTF_K_SLICE)
1740 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1741 return dst_type;
1744 else
1746 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1749 else
1751 /* We found a non-root-visible type in the hash. If its encoding
1752 is the same, we can reuse it, unless it is a slice. */
1754 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1756 if (kind != CTF_K_SLICE)
1758 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1759 return dst_type;
1766 src.ctb_dict = src_fp;
1767 src.ctb_type = src_type;
1768 src.ctb_dtd = NULL;
1770 dst.ctb_dict = dst_fp;
1771 dst.ctb_type = dst_type;
1772 dst.ctb_dtd = NULL;
1774 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
1775 a new type with the same properties as src_type to dst_fp. If dst_type is
1776 not CTF_ERR, then we verify that dst_type has the same attributes as
1777 src_type. We recurse for embedded references. Before we start, we note
1778 that we are processing this type, to prevent infinite recursion: we do not
1779 re-process any type that appears in this list. The list is emptied
1780 wholesale at the end of processing everything in this recursive stack. */
1782 if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1783 (void *) (uintptr_t) src_type, (void *) 1) < 0)
1784 return ctf_set_typed_errno (dst_fp, ENOMEM);
1786 switch (kind)
1788 case CTF_K_INTEGER:
1789 /* If we found a match we will have either returned it or declared a
1790 conflict. */
1791 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1792 break;
1794 case CTF_K_FLOAT:
1795 /* If we found a match we will have either returned it or declared a
1796 conflict. */
1797 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1798 break;
1800 case CTF_K_SLICE:
1801 /* We have checked for conflicting encodings: now try to add the
1802 contained type. */
1803 src_type = ctf_type_reference (src_fp, src_type);
1804 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1805 proc_tracking_fp);
1807 if (src_type == CTF_ERR)
1808 return CTF_ERR; /* errno is set for us. */
1810 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1811 break;
1813 case CTF_K_POINTER:
1814 case CTF_K_VOLATILE:
1815 case CTF_K_CONST:
1816 case CTF_K_RESTRICT:
1817 src_type = ctf_type_reference (src_fp, src_type);
1818 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1819 proc_tracking_fp);
1821 if (src_type == CTF_ERR)
1822 return CTF_ERR; /* errno is set for us. */
1824 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1825 break;
1827 case CTF_K_ARRAY:
1828 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1829 return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1831 src_ar.ctr_contents =
1832 ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1833 proc_tracking_fp);
1834 src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1835 src_ar.ctr_index,
1836 proc_tracking_fp);
1837 src_ar.ctr_nelems = src_ar.ctr_nelems;
1839 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1840 return CTF_ERR; /* errno is set for us. */
1842 if (dst_type != CTF_ERR)
1844 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1845 return CTF_ERR; /* errno is set for us. */
1847 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1849 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1850 _("conflict for type %s against ID %lx: array info "
1851 "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
1852 name, dst_type, src_ar.ctr_contents,
1853 src_ar.ctr_index, src_ar.ctr_nelems,
1854 dst_ar.ctr_contents, dst_ar.ctr_index,
1855 dst_ar.ctr_nelems);
1856 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1859 else
1860 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1861 break;
1863 case CTF_K_FUNCTION:
1864 ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1865 src_tp->ctt_type,
1866 proc_tracking_fp);
1867 ctc.ctc_argc = 0;
1868 ctc.ctc_flags = 0;
1870 if (ctc.ctc_return == CTF_ERR)
1871 return CTF_ERR; /* errno is set for us. */
1873 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1874 break;
1876 case CTF_K_STRUCT:
1877 case CTF_K_UNION:
1879 ctf_next_t *i = NULL;
1880 ssize_t offset;
1881 const char *membname;
1882 ctf_id_t src_membtype;
1884 /* Technically to match a struct or union we need to check both
1885 ways (src members vs. dst, dst members vs. src) but we make
1886 this more optimal by only checking src vs. dst and comparing
1887 the total size of the structure (which we must do anyway)
1888 which covers the possibility of dst members not in src.
1889 This optimization can be defeated for unions, but is so
1890 pathological as to render it irrelevant for our purposes. */
1892 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1893 && dst_kind != CTF_K_FORWARD)
1895 if (ctf_type_size (src_fp, src_type) !=
1896 ctf_type_size (dst_fp, dst_type))
1898 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1899 _("conflict for type %s against ID %lx: union "
1900 "size differs, old %li, new %li"), name,
1901 dst_type, (long) ctf_type_size (src_fp, src_type),
1902 (long) ctf_type_size (dst_fp, dst_type));
1903 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1906 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1908 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1909 _("conflict for type %s against ID %lx: members "
1910 "differ, see above"), name, dst_type);
1911 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1914 break;
1917 dst_type = ctf_add_struct_sized (dst_fp, flag, name,
1918 ctf_type_size (src_fp, src_type));
1919 if (dst_type == CTF_ERR)
1920 return CTF_ERR; /* errno is set for us. */
1922 /* Pre-emptively add this struct to the type mapping so that
1923 structures that refer to themselves work. */
1924 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1926 while ((offset = ctf_member_next (src_fp, src_type, &i, &membname,
1927 &src_membtype, 0)) >= 0)
1929 ctf_dict_t *dst = dst_fp;
1930 ctf_id_t dst_membtype = ctf_type_mapping (src_fp, src_membtype, &dst);
1932 if (dst_membtype == 0)
1934 dst_membtype = ctf_add_type_internal (dst_fp, src_fp,
1935 src_membtype,
1936 proc_tracking_fp);
1937 if (dst_membtype == CTF_ERR)
1939 if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1941 ctf_next_destroy (i);
1942 break;
1947 if (ctf_add_member_offset (dst_fp, dst_type, membname,
1948 dst_membtype, offset) < 0)
1950 ctf_next_destroy (i);
1951 break;
1954 if (ctf_errno (src_fp) != ECTF_NEXT_END)
1955 return CTF_ERR; /* errno is set for us. */
1956 break;
1959 case CTF_K_ENUM:
1960 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1961 && dst_kind != CTF_K_FORWARD)
1963 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1964 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1966 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1967 _("conflict for enum %s against ID %lx: members "
1968 "differ, see above"), name, dst_type);
1969 return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1972 else
1974 ctf_snapshot_id_t snap = ctf_snapshot (dst_fp);
1976 dst_type = ctf_add_enum (dst_fp, flag, name);
1977 if ((dst.ctb_type = dst_type) == CTF_ERR
1978 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1980 ctf_rollback (dst_fp, snap);
1981 return CTF_ERR; /* errno is set for us */
1984 break;
1986 case CTF_K_FORWARD:
1987 if (dst_type == CTF_ERR)
1988 dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
1989 break;
1991 case CTF_K_TYPEDEF:
1992 src_type = ctf_type_reference (src_fp, src_type);
1993 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1994 proc_tracking_fp);
1996 if (src_type == CTF_ERR)
1997 return CTF_ERR; /* errno is set for us. */
1999 /* If dst_type is not CTF_ERR at this point, we should check if
2000 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
2001 ECTF_CONFLICT. However, this causes problems with bitness typedefs
2002 that vary based on things like if 32-bit then pid_t is int otherwise
2003 long. We therefore omit this check and assume that if the identically
2004 named typedef already exists in dst_fp, it is correct or
2005 equivalent. */
2007 if (dst_type == CTF_ERR)
2008 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
2010 break;
2012 default:
2013 return (ctf_set_typed_errno (dst_fp, ECTF_CORRUPT));
2016 if (dst_type != CTF_ERR)
2017 ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
2018 return dst_type;
2021 ctf_id_t
2022 ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
2024 ctf_id_t id;
2026 if (!src_fp->ctf_add_processing)
2027 src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
2028 ctf_hash_eq_integer,
2029 NULL, NULL);
2031 /* We store the hash on the source, because it contains only source type IDs:
2032 but callers will invariably expect errors to appear on the dest. */
2033 if (!src_fp->ctf_add_processing)
2034 return (ctf_set_typed_errno (dst_fp, ENOMEM));
2036 id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
2037 ctf_dynhash_empty (src_fp->ctf_add_processing);
2039 return id;