Home | History | Annotate | Line # | Download | only in libctf
      1  1.1.1.2  christos /* CTF dict creation.
      2  1.1.1.5  christos    Copyright (C) 2019-2026 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of libctf.
      5      1.1  christos 
      6      1.1  christos    libctf is free software; you can redistribute it and/or modify it under
      7      1.1  christos    the terms of the GNU General Public License as published by the Free
      8      1.1  christos    Software Foundation; either version 3, or (at your option) any later
      9      1.1  christos    version.
     10      1.1  christos 
     11      1.1  christos    This program is distributed in the hope that it will be useful, but
     12      1.1  christos    WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     14      1.1  christos    See the GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with this program; see the file COPYING.  If not see
     18      1.1  christos    <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include <ctf-impl.h>
     21      1.1  christos #include <string.h>
     22  1.1.1.2  christos #include <unistd.h>
     23  1.1.1.2  christos 
     24  1.1.1.2  christos #ifndef EOVERFLOW
     25  1.1.1.2  christos #define EOVERFLOW ERANGE
     26  1.1.1.2  christos #endif
     27      1.1  christos 
     28      1.1  christos #ifndef roundup
     29      1.1  christos #define roundup(x, y)  ((((x) + ((y) - 1)) / (y)) * (y))
     30      1.1  christos #endif
     31      1.1  christos 
     32  1.1.1.2  christos /* The initial size of a dynamic type's vlen in members.  Arbitrary: the bigger
     33  1.1.1.2  christos    this is, the less allocation needs to be done for small structure
     34  1.1.1.2  christos    initialization, and the more memory is wasted for small structures during CTF
     35  1.1.1.2  christos    construction.  No effect on generated CTF or ctf_open()ed CTF. */
     36  1.1.1.2  christos #define INITIAL_VLEN 16
     37  1.1.1.2  christos 
     38      1.1  christos /* Make sure the ptrtab has enough space for at least one more type.
     39      1.1  christos 
     40      1.1  christos    We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
     41      1.1  christos    at a time.  */
     42      1.1  christos 
     43      1.1  christos static int
     44  1.1.1.2  christos ctf_grow_ptrtab (ctf_dict_t *fp)
     45      1.1  christos {
     46      1.1  christos   size_t new_ptrtab_len = fp->ctf_ptrtab_len;
     47      1.1  christos 
     48      1.1  christos   /* We allocate one more ptrtab entry than we need, for the initial zero,
     49  1.1.1.4  christos      plus one because the caller will probably allocate a new type.
     50      1.1  christos 
     51  1.1.1.4  christos      Equally, if the ptrtab is small -- perhaps due to ctf_open of a small
     52  1.1.1.4  christos      dict -- boost it by quite a lot at first, so we don't need to keep
     53  1.1.1.4  christos      realloc()ing.  */
     54  1.1.1.4  christos 
     55  1.1.1.4  christos   if (fp->ctf_ptrtab == NULL || fp->ctf_ptrtab_len < 1024)
     56      1.1  christos     new_ptrtab_len = 1024;
     57      1.1  christos   else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
     58      1.1  christos     new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
     59      1.1  christos 
     60      1.1  christos   if (new_ptrtab_len != fp->ctf_ptrtab_len)
     61      1.1  christos     {
     62      1.1  christos       uint32_t *new_ptrtab;
     63      1.1  christos 
     64      1.1  christos       if ((new_ptrtab = realloc (fp->ctf_ptrtab,
     65      1.1  christos 				 new_ptrtab_len * sizeof (uint32_t))) == NULL)
     66      1.1  christos 	return (ctf_set_errno (fp, ENOMEM));
     67      1.1  christos 
     68      1.1  christos       fp->ctf_ptrtab = new_ptrtab;
     69      1.1  christos       memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
     70      1.1  christos 	      (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
     71      1.1  christos       fp->ctf_ptrtab_len = new_ptrtab_len;
     72      1.1  christos     }
     73      1.1  christos   return 0;
     74      1.1  christos }
     75      1.1  christos 
     76  1.1.1.2  christos /* Make sure a vlen has enough space: expand it otherwise.  Unlike the ptrtab,
     77  1.1.1.2  christos    which grows quite slowly, the vlen grows in big jumps because it is quite
     78  1.1.1.2  christos    expensive to expand: the caller has to scan the old vlen for string refs
     79  1.1.1.2  christos    first and remove them, then re-add them afterwards.  The initial size is
     80  1.1.1.2  christos    more or less arbitrary.  */
     81  1.1.1.2  christos static int
     82  1.1.1.2  christos ctf_grow_vlen (ctf_dict_t *fp, ctf_dtdef_t *dtd, size_t vlen)
     83  1.1.1.2  christos {
     84  1.1.1.2  christos   unsigned char *old = dtd->dtd_vlen;
     85  1.1.1.2  christos 
     86  1.1.1.2  christos   if (dtd->dtd_vlen_alloc > vlen)
     87  1.1.1.2  christos     return 0;
     88  1.1.1.2  christos 
     89  1.1.1.2  christos   if ((dtd->dtd_vlen = realloc (dtd->dtd_vlen,
     90  1.1.1.2  christos 				dtd->dtd_vlen_alloc * 2)) == NULL)
     91  1.1.1.2  christos     {
     92  1.1.1.2  christos       dtd->dtd_vlen = old;
     93  1.1.1.2  christos       return (ctf_set_errno (fp, ENOMEM));
     94  1.1.1.2  christos     }
     95  1.1.1.2  christos   memset (dtd->dtd_vlen + dtd->dtd_vlen_alloc, 0, dtd->dtd_vlen_alloc);
     96  1.1.1.2  christos   dtd->dtd_vlen_alloc *= 2;
     97  1.1.1.2  christos   return 0;
     98  1.1.1.2  christos }
     99  1.1.1.2  christos 
    100  1.1.1.2  christos /* To create an empty CTF dict, we just declare a zeroed header and call
    101  1.1.1.2  christos    ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new dict r/w and
    102  1.1.1.2  christos    initialize the dynamic members.  We start assigning type IDs at 1 because
    103      1.1  christos    type ID 0 is used as a sentinel and a not-found indicator.  */
    104      1.1  christos 
    105  1.1.1.2  christos ctf_dict_t *
    106      1.1  christos ctf_create (int *errp)
    107      1.1  christos {
    108      1.1  christos   static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
    109      1.1  christos 
    110      1.1  christos   ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
    111      1.1  christos   ctf_sect_t cts;
    112  1.1.1.2  christos   ctf_dict_t *fp;
    113      1.1  christos 
    114      1.1  christos   libctf_init_debug();
    115      1.1  christos 
    116      1.1  christos   structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
    117      1.1  christos 				NULL, NULL);
    118      1.1  christos   unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
    119      1.1  christos 			       NULL, NULL);
    120      1.1  christos   enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
    121      1.1  christos 			      NULL, NULL);
    122      1.1  christos   names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
    123      1.1  christos 			      NULL, NULL);
    124      1.1  christos   if (!structs || !unions || !enums || !names)
    125      1.1  christos     {
    126      1.1  christos       ctf_set_open_errno (errp, EAGAIN);
    127  1.1.1.4  christos       goto err;
    128      1.1  christos     }
    129      1.1  christos 
    130      1.1  christos   cts.cts_name = _CTF_SECTION;
    131      1.1  christos   cts.cts_data = &hdr;
    132      1.1  christos   cts.cts_size = sizeof (hdr);
    133      1.1  christos   cts.cts_entsize = 1;
    134      1.1  christos 
    135  1.1.1.4  christos   if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
    136  1.1.1.4  christos     goto err;
    137      1.1  christos 
    138  1.1.1.4  christos   /* These hashes will have been initialized with a starting size of zero,
    139  1.1.1.4  christos      which is surely wrong.  Use ones with slightly larger sizes.  */
    140  1.1.1.4  christos   ctf_dynhash_destroy (fp->ctf_structs);
    141  1.1.1.4  christos   ctf_dynhash_destroy (fp->ctf_unions);
    142  1.1.1.4  christos   ctf_dynhash_destroy (fp->ctf_enums);
    143  1.1.1.4  christos   ctf_dynhash_destroy (fp->ctf_names);
    144  1.1.1.4  christos   fp->ctf_structs = structs;
    145  1.1.1.4  christos   fp->ctf_unions = unions;
    146  1.1.1.4  christos   fp->ctf_enums = enums;
    147  1.1.1.4  christos   fp->ctf_names = names;
    148      1.1  christos   fp->ctf_dtoldid = 0;
    149      1.1  christos   fp->ctf_snapshot_lu = 0;
    150  1.1.1.4  christos 
    151  1.1.1.4  christos   /* Make sure the ptrtab starts out at a reasonable size.  */
    152      1.1  christos 
    153      1.1  christos   ctf_set_ctl_hashes (fp);
    154      1.1  christos   if (ctf_grow_ptrtab (fp) < 0)
    155      1.1  christos     {
    156      1.1  christos       ctf_set_open_errno (errp, ctf_errno (fp));
    157  1.1.1.2  christos       ctf_dict_close (fp);
    158      1.1  christos       return NULL;
    159      1.1  christos     }
    160      1.1  christos 
    161      1.1  christos   return fp;
    162      1.1  christos 
    163  1.1.1.4  christos  err:
    164      1.1  christos   ctf_dynhash_destroy (structs);
    165      1.1  christos   ctf_dynhash_destroy (unions);
    166      1.1  christos   ctf_dynhash_destroy (enums);
    167      1.1  christos   ctf_dynhash_destroy (names);
    168      1.1  christos   return NULL;
    169      1.1  christos }
    170      1.1  christos 
    171      1.1  christos /* Compatibility: just update the threshold for ctf_discard.  */
    172      1.1  christos int
    173  1.1.1.2  christos ctf_update (ctf_dict_t *fp)
    174      1.1  christos {
    175      1.1  christos   fp->ctf_dtoldid = fp->ctf_typemax;
    176      1.1  christos   return 0;
    177      1.1  christos }
    178      1.1  christos 
    179  1.1.1.4  christos ctf_dynhash_t *
    180  1.1.1.2  christos ctf_name_table (ctf_dict_t *fp, int kind)
    181      1.1  christos {
    182      1.1  christos   switch (kind)
    183      1.1  christos     {
    184      1.1  christos     case CTF_K_STRUCT:
    185  1.1.1.4  christos       return fp->ctf_structs;
    186      1.1  christos     case CTF_K_UNION:
    187  1.1.1.4  christos       return fp->ctf_unions;
    188      1.1  christos     case CTF_K_ENUM:
    189  1.1.1.4  christos       return fp->ctf_enums;
    190      1.1  christos     default:
    191  1.1.1.4  christos       return fp->ctf_names;
    192      1.1  christos     }
    193      1.1  christos }
    194      1.1  christos 
    195      1.1  christos int
    196  1.1.1.2  christos ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
    197      1.1  christos {
    198      1.1  christos   const char *name;
    199  1.1.1.2  christos   if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
    200  1.1.1.2  christos 			  dtd) < 0)
    201  1.1.1.3  christos     return ctf_set_errno (fp, ENOMEM);
    202      1.1  christos 
    203  1.1.1.2  christos   if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
    204      1.1  christos       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
    205      1.1  christos     {
    206  1.1.1.4  christos       if (ctf_dynhash_insert (ctf_name_table (fp, kind),
    207  1.1.1.2  christos 			      (char *) name, (void *) (uintptr_t)
    208  1.1.1.2  christos 			      dtd->dtd_type) < 0)
    209      1.1  christos 	{
    210  1.1.1.2  christos 	  ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
    211  1.1.1.2  christos 			      dtd->dtd_type);
    212  1.1.1.3  christos 	  return ctf_set_errno (fp, ENOMEM);
    213      1.1  christos 	}
    214      1.1  christos     }
    215      1.1  christos   ctf_list_append (&fp->ctf_dtdefs, dtd);
    216      1.1  christos   return 0;
    217      1.1  christos }
    218      1.1  christos 
    219      1.1  christos void
    220  1.1.1.2  christos ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
    221      1.1  christos {
    222      1.1  christos   int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
    223  1.1.1.2  christos   size_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
    224  1.1.1.2  christos   int name_kind = kind;
    225      1.1  christos   const char *name;
    226      1.1  christos 
    227  1.1.1.2  christos   ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
    228      1.1  christos 
    229      1.1  christos   switch (kind)
    230      1.1  christos     {
    231      1.1  christos     case CTF_K_STRUCT:
    232      1.1  christos     case CTF_K_UNION:
    233  1.1.1.2  christos       {
    234  1.1.1.2  christos 	ctf_lmember_t *memb = (ctf_lmember_t *) dtd->dtd_vlen;
    235  1.1.1.2  christos 	size_t i;
    236  1.1.1.2  christos 
    237  1.1.1.2  christos 	for (i = 0; i < vlen; i++)
    238  1.1.1.2  christos 	  ctf_str_remove_ref (fp, ctf_strraw (fp, memb[i].ctlm_name),
    239  1.1.1.2  christos 			      &memb[i].ctlm_name);
    240  1.1.1.2  christos       }
    241  1.1.1.2  christos       break;
    242      1.1  christos     case CTF_K_ENUM:
    243  1.1.1.2  christos       {
    244  1.1.1.2  christos 	ctf_enum_t *en = (ctf_enum_t *) dtd->dtd_vlen;
    245  1.1.1.2  christos 	size_t i;
    246  1.1.1.2  christos 
    247  1.1.1.2  christos 	for (i = 0; i < vlen; i++)
    248  1.1.1.2  christos 	  ctf_str_remove_ref (fp, ctf_strraw (fp, en[i].cte_name),
    249  1.1.1.2  christos 			      &en[i].cte_name);
    250  1.1.1.2  christos       }
    251      1.1  christos       break;
    252  1.1.1.2  christos     case CTF_K_FORWARD:
    253  1.1.1.2  christos       name_kind = dtd->dtd_data.ctt_type;
    254      1.1  christos       break;
    255      1.1  christos     }
    256  1.1.1.2  christos   free (dtd->dtd_vlen);
    257  1.1.1.2  christos   dtd->dtd_vlen_alloc = 0;
    258      1.1  christos 
    259      1.1  christos   if (dtd->dtd_data.ctt_name
    260  1.1.1.4  christos       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
    261      1.1  christos     {
    262  1.1.1.4  christos       if (LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
    263  1.1.1.4  christos 	ctf_dynhash_remove (ctf_name_table (fp, name_kind), name);
    264      1.1  christos       ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
    265      1.1  christos     }
    266      1.1  christos 
    267      1.1  christos   ctf_list_delete (&fp->ctf_dtdefs, dtd);
    268      1.1  christos   free (dtd);
    269      1.1  christos }
    270      1.1  christos 
    271      1.1  christos ctf_dtdef_t *
    272  1.1.1.2  christos ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
    273      1.1  christos {
    274  1.1.1.3  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
    275  1.1.1.3  christos     fp = fp->ctf_parent;
    276  1.1.1.3  christos 
    277  1.1.1.2  christos   return (ctf_dtdef_t *)
    278  1.1.1.2  christos     ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
    279      1.1  christos }
    280      1.1  christos 
    281      1.1  christos ctf_dtdef_t *
    282  1.1.1.2  christos ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
    283      1.1  christos {
    284      1.1  christos   ctf_id_t idx;
    285      1.1  christos 
    286      1.1  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
    287      1.1  christos     fp = fp->ctf_parent;
    288      1.1  christos 
    289      1.1  christos   idx = LCTF_TYPE_TO_INDEX(fp, id);
    290      1.1  christos 
    291      1.1  christos   if ((unsigned long) idx <= fp->ctf_typemax)
    292      1.1  christos     return ctf_dtd_lookup (fp, id);
    293      1.1  christos   return NULL;
    294      1.1  christos }
    295      1.1  christos 
    296  1.1.1.4  christos static int
    297  1.1.1.4  christos ctf_static_type (const ctf_dict_t *fp, ctf_id_t id)
    298  1.1.1.4  christos {
    299  1.1.1.4  christos   ctf_id_t idx;
    300  1.1.1.4  christos 
    301  1.1.1.4  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
    302  1.1.1.4  christos     fp = fp->ctf_parent;
    303  1.1.1.4  christos 
    304  1.1.1.4  christos   idx = LCTF_TYPE_TO_INDEX(fp, id);
    305  1.1.1.4  christos 
    306  1.1.1.4  christos   return ((unsigned long) idx <= fp->ctf_stypes);
    307  1.1.1.4  christos }
    308  1.1.1.4  christos 
    309      1.1  christos int
    310  1.1.1.2  christos ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
    311      1.1  christos {
    312      1.1  christos   if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
    313  1.1.1.3  christos     return ctf_set_errno (fp, ENOMEM);
    314      1.1  christos   ctf_list_append (&fp->ctf_dvdefs, dvd);
    315      1.1  christos   return 0;
    316      1.1  christos }
    317      1.1  christos 
    318      1.1  christos void
    319  1.1.1.2  christos ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
    320      1.1  christos {
    321      1.1  christos   ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
    322      1.1  christos   free (dvd->dvd_name);
    323      1.1  christos 
    324      1.1  christos   ctf_list_delete (&fp->ctf_dvdefs, dvd);
    325      1.1  christos   free (dvd);
    326      1.1  christos }
    327      1.1  christos 
    328      1.1  christos ctf_dvdef_t *
    329  1.1.1.2  christos ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
    330      1.1  christos {
    331      1.1  christos   return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
    332      1.1  christos }
    333      1.1  christos 
    334      1.1  christos /* Discard all of the dynamic type definitions and variable definitions that
    335  1.1.1.2  christos    have been added to the dict since the last call to ctf_update().  We locate
    336  1.1.1.2  christos    such types by scanning the dtd list and deleting elements that have type IDs
    337  1.1.1.2  christos    greater than ctf_dtoldid, which is set by ctf_update(), above, and by
    338  1.1.1.2  christos    scanning the variable list and deleting elements that have update IDs equal
    339  1.1.1.2  christos    to the current value of the last-update snapshot count (indicating that they
    340  1.1.1.2  christos    were added after the most recent call to ctf_update()).  */
    341      1.1  christos int
    342  1.1.1.2  christos ctf_discard (ctf_dict_t *fp)
    343      1.1  christos {
    344      1.1  christos   ctf_snapshot_id_t last_update =
    345      1.1  christos     { fp->ctf_dtoldid,
    346      1.1  christos       fp->ctf_snapshot_lu + 1 };
    347      1.1  christos 
    348      1.1  christos   return (ctf_rollback (fp, last_update));
    349      1.1  christos }
    350      1.1  christos 
    351      1.1  christos ctf_snapshot_id_t
    352  1.1.1.2  christos ctf_snapshot (ctf_dict_t *fp)
    353      1.1  christos {
    354      1.1  christos   ctf_snapshot_id_t snapid;
    355      1.1  christos   snapid.dtd_id = fp->ctf_typemax;
    356      1.1  christos   snapid.snapshot_id = fp->ctf_snapshots++;
    357      1.1  christos   return snapid;
    358      1.1  christos }
    359      1.1  christos 
    360      1.1  christos /* Like ctf_discard(), only discards everything after a particular ID.  */
    361      1.1  christos int
    362  1.1.1.2  christos ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
    363      1.1  christos {
    364      1.1  christos   ctf_dtdef_t *dtd, *ntd;
    365      1.1  christos   ctf_dvdef_t *dvd, *nvd;
    366      1.1  christos 
    367  1.1.1.4  christos   if (id.snapshot_id < fp->ctf_stypes)
    368      1.1  christos     return (ctf_set_errno (fp, ECTF_RDONLY));
    369      1.1  christos 
    370      1.1  christos   if (fp->ctf_snapshot_lu >= id.snapshot_id)
    371      1.1  christos     return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
    372      1.1  christos 
    373      1.1  christos   for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
    374      1.1  christos     {
    375      1.1  christos       int kind;
    376      1.1  christos       const char *name;
    377      1.1  christos 
    378      1.1  christos       ntd = ctf_list_next (dtd);
    379      1.1  christos 
    380      1.1  christos       if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
    381      1.1  christos 	continue;
    382      1.1  christos 
    383      1.1  christos       kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
    384  1.1.1.2  christos       if (kind == CTF_K_FORWARD)
    385  1.1.1.2  christos 	kind = dtd->dtd_data.ctt_type;
    386      1.1  christos 
    387      1.1  christos       if (dtd->dtd_data.ctt_name
    388  1.1.1.2  christos 	  && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
    389  1.1.1.2  christos 	  && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
    390      1.1  christos 	{
    391  1.1.1.4  christos 	  ctf_dynhash_remove (ctf_name_table (fp, kind), name);
    392      1.1  christos 	  ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
    393      1.1  christos 	}
    394      1.1  christos 
    395  1.1.1.2  christos       ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
    396      1.1  christos       ctf_dtd_delete (fp, dtd);
    397      1.1  christos     }
    398      1.1  christos 
    399      1.1  christos   for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
    400      1.1  christos     {
    401      1.1  christos       nvd = ctf_list_next (dvd);
    402      1.1  christos 
    403      1.1  christos       if (dvd->dvd_snapshots <= id.snapshot_id)
    404      1.1  christos 	continue;
    405      1.1  christos 
    406      1.1  christos       ctf_dvd_delete (fp, dvd);
    407      1.1  christos     }
    408      1.1  christos 
    409      1.1  christos   fp->ctf_typemax = id.dtd_id;
    410      1.1  christos   fp->ctf_snapshots = id.snapshot_id;
    411      1.1  christos 
    412      1.1  christos   return 0;
    413      1.1  christos }
    414      1.1  christos 
    415  1.1.1.2  christos /* Note: vlen is the amount of space *allocated* for the vlen.  It may well not
    416  1.1.1.2  christos    be the amount of space used (yet): the space used is declared in per-kind
    417  1.1.1.2  christos    fashion in the dtd_data's info word.  */
    418      1.1  christos static ctf_id_t
    419  1.1.1.2  christos ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
    420  1.1.1.2  christos 		 size_t vlen, ctf_dtdef_t **rp)
    421      1.1  christos {
    422      1.1  christos   ctf_dtdef_t *dtd;
    423      1.1  christos   ctf_id_t type;
    424      1.1  christos 
    425      1.1  christos   if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
    426  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    427      1.1  christos 
    428      1.1  christos   if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
    429  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_FULL));
    430      1.1  christos 
    431      1.1  christos   if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
    432  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_FULL));
    433      1.1  christos 
    434  1.1.1.4  christos   /* Prohibit addition of a root-visible type that is already present
    435  1.1.1.4  christos      in the non-dynamic portion. */
    436  1.1.1.4  christos 
    437  1.1.1.4  christos   if (flag == CTF_ADD_ROOT && name != NULL && name[0] != '\0')
    438  1.1.1.4  christos     {
    439  1.1.1.4  christos       ctf_id_t existing;
    440  1.1.1.4  christos 
    441  1.1.1.4  christos       if (((existing = ctf_dynhash_lookup_type (ctf_name_table (fp, kind),
    442  1.1.1.4  christos 						name)) > 0)
    443  1.1.1.4  christos 	  && ctf_static_type (fp, existing))
    444  1.1.1.4  christos 	return (ctf_set_typed_errno (fp, ECTF_RDONLY));
    445  1.1.1.4  christos     }
    446  1.1.1.4  christos 
    447      1.1  christos   /* Make sure ptrtab always grows to be big enough for all types.  */
    448      1.1  christos   if (ctf_grow_ptrtab (fp) < 0)
    449  1.1.1.2  christos       return CTF_ERR;				/* errno is set for us. */
    450      1.1  christos 
    451  1.1.1.2  christos   if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
    452  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EAGAIN));
    453      1.1  christos 
    454  1.1.1.2  christos   dtd->dtd_vlen_alloc = vlen;
    455  1.1.1.2  christos   if (vlen > 0)
    456  1.1.1.2  christos     {
    457  1.1.1.2  christos       if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
    458  1.1.1.2  christos 	goto oom;
    459  1.1.1.2  christos     }
    460  1.1.1.2  christos   else
    461  1.1.1.2  christos     dtd->dtd_vlen = NULL;
    462  1.1.1.2  christos 
    463      1.1  christos   type = ++fp->ctf_typemax;
    464      1.1  christos   type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
    465      1.1  christos 
    466  1.1.1.4  christos   dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
    467      1.1  christos   dtd->dtd_type = type;
    468      1.1  christos 
    469      1.1  christos   if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
    470  1.1.1.2  christos     goto oom;
    471  1.1.1.2  christos 
    472  1.1.1.2  christos   if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
    473  1.1.1.2  christos     goto err;					/* errno is set for us.  */
    474      1.1  christos 
    475      1.1  christos   *rp = dtd;
    476      1.1  christos   return type;
    477  1.1.1.2  christos 
    478  1.1.1.2  christos  oom:
    479  1.1.1.2  christos   ctf_set_errno (fp, EAGAIN);
    480  1.1.1.2  christos  err:
    481  1.1.1.2  christos   free (dtd->dtd_vlen);
    482  1.1.1.2  christos   free (dtd);
    483  1.1.1.2  christos   return CTF_ERR;
    484      1.1  christos }
    485      1.1  christos 
    486      1.1  christos /* When encoding integer sizes, we want to convert a byte count in the range
    487      1.1  christos    1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc).  The clp2() function
    488      1.1  christos    is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.  */
    489      1.1  christos static size_t
    490      1.1  christos clp2 (size_t x)
    491      1.1  christos {
    492      1.1  christos   x--;
    493      1.1  christos 
    494      1.1  christos   x |= (x >> 1);
    495      1.1  christos   x |= (x >> 2);
    496      1.1  christos   x |= (x >> 4);
    497      1.1  christos   x |= (x >> 8);
    498      1.1  christos   x |= (x >> 16);
    499      1.1  christos 
    500      1.1  christos   return (x + 1);
    501      1.1  christos }
    502      1.1  christos 
    503  1.1.1.2  christos ctf_id_t
    504  1.1.1.2  christos ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
    505      1.1  christos 		 const char *name, const ctf_encoding_t *ep, uint32_t kind)
    506      1.1  christos {
    507      1.1  christos   ctf_dtdef_t *dtd;
    508      1.1  christos   ctf_id_t type;
    509  1.1.1.2  christos   uint32_t encoding;
    510      1.1  christos 
    511      1.1  christos   if (ep == NULL)
    512  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    513      1.1  christos 
    514  1.1.1.2  christos   if (name == NULL || name[0] == '\0')
    515  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_NONAME));
    516  1.1.1.2  christos 
    517  1.1.1.2  christos   if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
    518  1.1.1.3  christos     return CTF_ERR;					/* errno is set for us.  */
    519  1.1.1.2  christos 
    520  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
    521  1.1.1.2  christos 			       &dtd)) == CTF_ERR)
    522      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    523      1.1  christos 
    524      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
    525      1.1  christos   dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
    526      1.1  christos 				 / CHAR_BIT);
    527  1.1.1.2  christos   switch (kind)
    528  1.1.1.2  christos     {
    529  1.1.1.2  christos     case CTF_K_INTEGER:
    530  1.1.1.2  christos       encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
    531  1.1.1.2  christos       break;
    532  1.1.1.2  christos     case CTF_K_FLOAT:
    533  1.1.1.2  christos       encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
    534  1.1.1.2  christos       break;
    535  1.1.1.4  christos     default:
    536  1.1.1.4  christos       /* ctf_assert is opaque with -fno-inline.  This dead code avoids
    537  1.1.1.4  christos 	 a warning about "encoding" being used uninitialized.  */
    538  1.1.1.4  christos       return CTF_ERR;
    539  1.1.1.2  christos     }
    540  1.1.1.2  christos   memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
    541      1.1  christos 
    542      1.1  christos   return type;
    543      1.1  christos }
    544      1.1  christos 
    545  1.1.1.2  christos ctf_id_t
    546  1.1.1.2  christos ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
    547      1.1  christos {
    548      1.1  christos   ctf_dtdef_t *dtd;
    549      1.1  christos   ctf_id_t type;
    550  1.1.1.2  christos   ctf_dict_t *tmp = fp;
    551      1.1  christos   int child = fp->ctf_flags & LCTF_CHILD;
    552      1.1  christos 
    553      1.1  christos   if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
    554  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    555      1.1  christos 
    556  1.1.1.2  christos   if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
    557      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    558      1.1  christos 
    559  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
    560      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    561      1.1  christos 
    562      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
    563      1.1  christos   dtd->dtd_data.ctt_type = (uint32_t) ref;
    564      1.1  christos 
    565      1.1  christos   if (kind != CTF_K_POINTER)
    566      1.1  christos     return type;
    567      1.1  christos 
    568  1.1.1.2  christos   /* If we are adding a pointer, update the ptrtab, pointing at this type from
    569  1.1.1.2  christos      the type it points to.  Note that ctf_typemax is at this point one higher
    570  1.1.1.2  christos      than we want to check against, because it's just been incremented for the
    571  1.1.1.2  christos      addition of this type.  The pptrtab is lazily-updated as needed, so is not
    572  1.1.1.2  christos      touched here.  */
    573      1.1  christos 
    574      1.1  christos   uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
    575      1.1  christos   uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
    576      1.1  christos 
    577      1.1  christos   if (LCTF_TYPE_ISCHILD (fp, ref) == child
    578      1.1  christos       && ref_idx < fp->ctf_typemax)
    579  1.1.1.2  christos     fp->ctf_ptrtab[ref_idx] = type_idx;
    580      1.1  christos 
    581      1.1  christos   return type;
    582      1.1  christos }
    583      1.1  christos 
    584      1.1  christos ctf_id_t
    585  1.1.1.2  christos ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
    586      1.1  christos 	       const ctf_encoding_t *ep)
    587      1.1  christos {
    588      1.1  christos   ctf_dtdef_t *dtd;
    589  1.1.1.2  christos   ctf_slice_t slice;
    590  1.1.1.2  christos   ctf_id_t resolved_ref = ref;
    591      1.1  christos   ctf_id_t type;
    592      1.1  christos   int kind;
    593      1.1  christos   const ctf_type_t *tp;
    594  1.1.1.2  christos   ctf_dict_t *tmp = fp;
    595      1.1  christos 
    596      1.1  christos   if (ep == NULL)
    597  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    598      1.1  christos 
    599      1.1  christos   if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
    600  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_SLICEOVERFLOW));
    601      1.1  christos 
    602      1.1  christos   if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
    603  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    604      1.1  christos 
    605  1.1.1.2  christos   if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
    606      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    607      1.1  christos 
    608  1.1.1.2  christos   /* Make sure we ultimately point to an integral type.  We also allow slices to
    609  1.1.1.2  christos      point to the unimplemented type, for now, because the compiler can emit
    610  1.1.1.2  christos      such slices, though they're not very much use.  */
    611  1.1.1.2  christos 
    612  1.1.1.3  christos   resolved_ref = ctf_type_resolve_unsliced (fp, ref);
    613  1.1.1.3  christos   kind = ctf_type_kind_unsliced (fp, resolved_ref);
    614  1.1.1.2  christos 
    615      1.1  christos   if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
    616  1.1.1.2  christos       (kind != CTF_K_ENUM)
    617  1.1.1.2  christos       && (ref != 0))
    618  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
    619      1.1  christos 
    620  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
    621  1.1.1.2  christos 			       sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
    622      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    623      1.1  christos 
    624  1.1.1.2  christos   memset (&slice, 0, sizeof (ctf_slice_t));
    625  1.1.1.2  christos 
    626      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
    627      1.1  christos   dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
    628      1.1  christos 				 / CHAR_BIT);
    629  1.1.1.2  christos   slice.cts_type = (uint32_t) ref;
    630  1.1.1.2  christos   slice.cts_bits = ep->cte_bits;
    631  1.1.1.2  christos   slice.cts_offset = ep->cte_offset;
    632  1.1.1.2  christos   memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
    633      1.1  christos 
    634      1.1  christos   return type;
    635      1.1  christos }
    636      1.1  christos 
    637      1.1  christos ctf_id_t
    638  1.1.1.2  christos ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
    639      1.1  christos 		 const char *name, const ctf_encoding_t *ep)
    640      1.1  christos {
    641      1.1  christos   return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
    642      1.1  christos }
    643      1.1  christos 
    644      1.1  christos ctf_id_t
    645  1.1.1.2  christos ctf_add_float (ctf_dict_t *fp, uint32_t flag,
    646      1.1  christos 	       const char *name, const ctf_encoding_t *ep)
    647      1.1  christos {
    648      1.1  christos   return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
    649      1.1  christos }
    650      1.1  christos 
    651      1.1  christos ctf_id_t
    652  1.1.1.2  christos ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
    653      1.1  christos {
    654      1.1  christos   return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
    655      1.1  christos }
    656      1.1  christos 
    657      1.1  christos ctf_id_t
    658  1.1.1.2  christos ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
    659      1.1  christos {
    660      1.1  christos   ctf_dtdef_t *dtd;
    661  1.1.1.2  christos   ctf_array_t cta;
    662      1.1  christos   ctf_id_t type;
    663  1.1.1.2  christos   ctf_dict_t *tmp = fp;
    664      1.1  christos 
    665      1.1  christos   if (arp == NULL)
    666  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    667      1.1  christos 
    668  1.1.1.2  christos   if (arp->ctr_contents != 0
    669  1.1.1.2  christos       && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
    670      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    671      1.1  christos 
    672      1.1  christos   tmp = fp;
    673      1.1  christos   if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
    674      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    675      1.1  christos 
    676  1.1.1.2  christos   if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
    677  1.1.1.2  christos     {
    678  1.1.1.2  christos       ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
    679  1.1.1.2  christos 		    _("ctf_add_array: index type %lx is incomplete"),
    680  1.1.1.2  christos 		    arp->ctr_contents);
    681  1.1.1.3  christos       return (ctf_set_typed_errno (fp, ECTF_INCOMPLETE));
    682  1.1.1.2  christos     }
    683  1.1.1.2  christos 
    684  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
    685  1.1.1.2  christos 			       sizeof (ctf_array_t), &dtd)) == CTF_ERR)
    686      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    687      1.1  christos 
    688  1.1.1.2  christos   memset (&cta, 0, sizeof (ctf_array_t));
    689  1.1.1.2  christos 
    690      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
    691      1.1  christos   dtd->dtd_data.ctt_size = 0;
    692  1.1.1.2  christos   cta.cta_contents = (uint32_t) arp->ctr_contents;
    693  1.1.1.2  christos   cta.cta_index = (uint32_t) arp->ctr_index;
    694  1.1.1.2  christos   cta.cta_nelems = arp->ctr_nelems;
    695  1.1.1.2  christos   memcpy (dtd->dtd_vlen, &cta, sizeof (ctf_array_t));
    696      1.1  christos 
    697      1.1  christos   return type;
    698      1.1  christos }
    699      1.1  christos 
    700      1.1  christos int
    701  1.1.1.2  christos ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
    702      1.1  christos {
    703  1.1.1.3  christos   ctf_dict_t *ofp = fp;
    704      1.1  christos   ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
    705  1.1.1.2  christos   ctf_array_t *vlen;
    706      1.1  christos 
    707  1.1.1.3  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
    708  1.1.1.3  christos     fp = fp->ctf_parent;
    709  1.1.1.3  christos 
    710  1.1.1.4  christos   /* You can only call ctf_set_array on a type you have added, not a
    711  1.1.1.4  christos      type that was read in via ctf_open().  */
    712  1.1.1.4  christos   if (type < fp->ctf_stypes)
    713  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_RDONLY));
    714      1.1  christos 
    715      1.1  christos   if (dtd == NULL
    716      1.1  christos       || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
    717  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_BADID));
    718      1.1  christos 
    719  1.1.1.2  christos   vlen = (ctf_array_t *) dtd->dtd_vlen;
    720  1.1.1.2  christos   vlen->cta_contents = (uint32_t) arp->ctr_contents;
    721  1.1.1.2  christos   vlen->cta_index = (uint32_t) arp->ctr_index;
    722  1.1.1.2  christos   vlen->cta_nelems = arp->ctr_nelems;
    723      1.1  christos 
    724      1.1  christos   return 0;
    725      1.1  christos }
    726      1.1  christos 
    727      1.1  christos ctf_id_t
    728  1.1.1.2  christos ctf_add_function (ctf_dict_t *fp, uint32_t flag,
    729      1.1  christos 		  const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
    730      1.1  christos {
    731      1.1  christos   ctf_dtdef_t *dtd;
    732      1.1  christos   ctf_id_t type;
    733      1.1  christos   uint32_t vlen;
    734  1.1.1.2  christos   uint32_t *vdat;
    735  1.1.1.2  christos   ctf_dict_t *tmp = fp;
    736  1.1.1.2  christos   size_t initial_vlen;
    737      1.1  christos   size_t i;
    738      1.1  christos 
    739      1.1  christos   if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
    740      1.1  christos       || (ctc->ctc_argc != 0 && argv == NULL))
    741  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
    742      1.1  christos 
    743      1.1  christos   vlen = ctc->ctc_argc;
    744      1.1  christos   if (ctc->ctc_flags & CTF_FUNC_VARARG)
    745      1.1  christos     vlen++;	       /* Add trailing zero to indicate varargs (see below).  */
    746      1.1  christos 
    747  1.1.1.2  christos   if (ctc->ctc_return != 0
    748  1.1.1.2  christos       && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
    749  1.1.1.2  christos     return CTF_ERR;				/* errno is set for us.  */
    750      1.1  christos 
    751      1.1  christos   if (vlen > CTF_MAX_VLEN)
    752  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EOVERFLOW));
    753      1.1  christos 
    754  1.1.1.2  christos   /* One word extra allocated for padding for 4-byte alignment if need be.
    755  1.1.1.2  christos      Not reflected in vlen: we don't want to copy anything into it, and
    756  1.1.1.2  christos      it's in addition to (e.g.) the trailing 0 indicating varargs.  */
    757      1.1  christos 
    758  1.1.1.2  christos   initial_vlen = (sizeof (uint32_t) * (vlen + (vlen & 1)));
    759      1.1  christos   if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
    760  1.1.1.2  christos 			       initial_vlen, &dtd)) == CTF_ERR)
    761  1.1.1.2  christos     return CTF_ERR;				/* errno is set for us.  */
    762  1.1.1.2  christos 
    763  1.1.1.2  christos   vdat = (uint32_t *) dtd->dtd_vlen;
    764  1.1.1.2  christos 
    765  1.1.1.2  christos   for (i = 0; i < ctc->ctc_argc; i++)
    766      1.1  christos     {
    767  1.1.1.2  christos       tmp = fp;
    768  1.1.1.2  christos       if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
    769  1.1.1.2  christos 	return CTF_ERR;				/* errno is set for us.  */
    770  1.1.1.2  christos       vdat[i] = (uint32_t) argv[i];
    771      1.1  christos     }
    772      1.1  christos 
    773      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
    774      1.1  christos   dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
    775      1.1  christos 
    776      1.1  christos   if (ctc->ctc_flags & CTF_FUNC_VARARG)
    777      1.1  christos     vdat[vlen - 1] = 0;		   /* Add trailing zero to indicate varargs.  */
    778      1.1  christos 
    779      1.1  christos   return type;
    780      1.1  christos }
    781      1.1  christos 
    782      1.1  christos ctf_id_t
    783  1.1.1.2  christos ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
    784      1.1  christos 		      size_t size)
    785      1.1  christos {
    786      1.1  christos   ctf_dtdef_t *dtd;
    787      1.1  christos   ctf_id_t type = 0;
    788  1.1.1.2  christos   size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
    789      1.1  christos 
    790  1.1.1.2  christos   /* Promote root-visible forwards to structs.  */
    791  1.1.1.4  christos   if (name != NULL && flag == CTF_ADD_ROOT)
    792      1.1  christos     type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
    793      1.1  christos 
    794  1.1.1.4  christos   /* Prohibit promotion if this type was ctf_open()ed.  */
    795  1.1.1.4  christos   if (type > 0 && type < fp->ctf_stypes)
    796  1.1.1.4  christos     return (ctf_set_errno (fp, ECTF_RDONLY));
    797  1.1.1.4  christos 
    798      1.1  christos   if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
    799      1.1  christos     dtd = ctf_dtd_lookup (fp, type);
    800      1.1  christos   else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
    801  1.1.1.2  christos 				    initial_vlen, &dtd)) == CTF_ERR)
    802      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    803      1.1  christos 
    804  1.1.1.2  christos   /* Forwards won't have any vlen yet.  */
    805  1.1.1.2  christos   if (dtd->dtd_vlen_alloc == 0)
    806      1.1  christos     {
    807  1.1.1.2  christos       if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
    808  1.1.1.3  christos 	return (ctf_set_typed_errno (fp, ENOMEM));
    809  1.1.1.2  christos       dtd->dtd_vlen_alloc = initial_vlen;
    810      1.1  christos     }
    811  1.1.1.2  christos 
    812  1.1.1.2  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
    813  1.1.1.2  christos   dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
    814  1.1.1.2  christos   dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
    815  1.1.1.2  christos   dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
    816      1.1  christos 
    817      1.1  christos   return type;
    818      1.1  christos }
    819      1.1  christos 
    820      1.1  christos ctf_id_t
    821  1.1.1.2  christos ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
    822      1.1  christos {
    823      1.1  christos   return (ctf_add_struct_sized (fp, flag, name, 0));
    824      1.1  christos }
    825      1.1  christos 
    826      1.1  christos ctf_id_t
    827  1.1.1.2  christos ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
    828      1.1  christos 		     size_t size)
    829      1.1  christos {
    830      1.1  christos   ctf_dtdef_t *dtd;
    831      1.1  christos   ctf_id_t type = 0;
    832  1.1.1.2  christos   size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
    833      1.1  christos 
    834  1.1.1.2  christos   /* Promote root-visible forwards to unions.  */
    835  1.1.1.4  christos   if (name != NULL && flag == CTF_ADD_ROOT)
    836      1.1  christos     type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
    837      1.1  christos 
    838  1.1.1.4  christos   /* Prohibit promotion if this type was ctf_open()ed.  */
    839  1.1.1.4  christos   if (type > 0 && type < fp->ctf_stypes)
    840  1.1.1.4  christos     return (ctf_set_errno (fp, ECTF_RDONLY));
    841  1.1.1.4  christos 
    842      1.1  christos   if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
    843      1.1  christos     dtd = ctf_dtd_lookup (fp, type);
    844      1.1  christos   else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
    845  1.1.1.2  christos 				    initial_vlen, &dtd)) == CTF_ERR)
    846  1.1.1.4  christos     return CTF_ERR;		/* errno is set for us.  */
    847      1.1  christos 
    848  1.1.1.2  christos   /* Forwards won't have any vlen yet.  */
    849  1.1.1.2  christos   if (dtd->dtd_vlen_alloc == 0)
    850      1.1  christos     {
    851  1.1.1.2  christos       if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
    852  1.1.1.3  christos 	return (ctf_set_typed_errno (fp, ENOMEM));
    853  1.1.1.2  christos       dtd->dtd_vlen_alloc = initial_vlen;
    854      1.1  christos     }
    855  1.1.1.2  christos 
    856  1.1.1.2  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
    857  1.1.1.2  christos   dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
    858  1.1.1.2  christos   dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
    859  1.1.1.2  christos   dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
    860      1.1  christos 
    861      1.1  christos   return type;
    862      1.1  christos }
    863      1.1  christos 
    864      1.1  christos ctf_id_t
    865  1.1.1.2  christos ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
    866      1.1  christos {
    867      1.1  christos   return (ctf_add_union_sized (fp, flag, name, 0));
    868      1.1  christos }
    869      1.1  christos 
    870      1.1  christos ctf_id_t
    871  1.1.1.2  christos ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
    872      1.1  christos {
    873      1.1  christos   ctf_dtdef_t *dtd;
    874      1.1  christos   ctf_id_t type = 0;
    875  1.1.1.2  christos   size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN;
    876      1.1  christos 
    877  1.1.1.2  christos   /* Promote root-visible forwards to enums.  */
    878  1.1.1.4  christos   if (name != NULL && flag == CTF_ADD_ROOT)
    879      1.1  christos     type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
    880      1.1  christos 
    881  1.1.1.4  christos   /* Prohibit promotion if this type was ctf_open()ed.  */
    882  1.1.1.4  christos   if (type > 0 && type < fp->ctf_stypes)
    883  1.1.1.4  christos     return (ctf_set_errno (fp, ECTF_RDONLY));
    884  1.1.1.4  christos 
    885      1.1  christos   if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
    886      1.1  christos     dtd = ctf_dtd_lookup (fp, type);
    887      1.1  christos   else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
    888  1.1.1.2  christos 				    initial_vlen, &dtd)) == CTF_ERR)
    889      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    890      1.1  christos 
    891  1.1.1.2  christos   /* Forwards won't have any vlen yet.  */
    892  1.1.1.2  christos   if (dtd->dtd_vlen_alloc == 0)
    893  1.1.1.2  christos     {
    894  1.1.1.2  christos       if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
    895  1.1.1.3  christos 	return (ctf_set_typed_errno (fp, ENOMEM));
    896  1.1.1.2  christos       dtd->dtd_vlen_alloc = initial_vlen;
    897  1.1.1.2  christos     }
    898  1.1.1.2  christos 
    899      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
    900      1.1  christos   dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
    901      1.1  christos 
    902      1.1  christos   return type;
    903      1.1  christos }
    904      1.1  christos 
    905      1.1  christos ctf_id_t
    906  1.1.1.2  christos ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
    907      1.1  christos 		      const ctf_encoding_t *ep)
    908      1.1  christos {
    909      1.1  christos   ctf_id_t type = 0;
    910      1.1  christos 
    911      1.1  christos   /* First, create the enum if need be, using most of the same machinery as
    912      1.1  christos      ctf_add_enum(), to ensure that we do not allow things past that are not
    913      1.1  christos      enums or forwards to them.  (This includes other slices: you cannot slice a
    914      1.1  christos      slice, which would be a useless thing to do anyway.)  */
    915      1.1  christos 
    916      1.1  christos   if (name != NULL)
    917      1.1  christos     type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
    918      1.1  christos 
    919      1.1  christos   if (type != 0)
    920      1.1  christos     {
    921      1.1  christos       if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
    922      1.1  christos 	  (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
    923  1.1.1.3  christos 	return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
    924      1.1  christos     }
    925      1.1  christos   else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
    926      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    927      1.1  christos 
    928      1.1  christos   /* Now attach a suitable slice to it.  */
    929      1.1  christos 
    930      1.1  christos   return ctf_add_slice (fp, flag, type, ep);
    931      1.1  christos }
    932      1.1  christos 
    933      1.1  christos ctf_id_t
    934  1.1.1.2  christos ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
    935      1.1  christos 		 uint32_t kind)
    936      1.1  christos {
    937      1.1  christos   ctf_dtdef_t *dtd;
    938      1.1  christos   ctf_id_t type = 0;
    939      1.1  christos 
    940  1.1.1.2  christos   if (!ctf_forwardable_kind (kind))
    941  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_NOTSUE));
    942      1.1  christos 
    943  1.1.1.2  christos   if (name == NULL || name[0] == '\0')
    944  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_NONAME));
    945  1.1.1.2  christos 
    946  1.1.1.4  christos   /* If the type is already defined or exists as a forward tag, just return
    947  1.1.1.4  christos      the ctf_id_t of the existing definition.  Since this changes nothing,
    948  1.1.1.4  christos      it's safe to do even on the read-only portion of the dict.  */
    949      1.1  christos 
    950  1.1.1.2  christos   type = ctf_lookup_by_rawname (fp, kind, name);
    951      1.1  christos 
    952  1.1.1.2  christos   if (type)
    953  1.1.1.2  christos     return type;
    954  1.1.1.2  christos 
    955  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
    956      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
    957      1.1  christos 
    958      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
    959      1.1  christos   dtd->dtd_data.ctt_type = kind;
    960      1.1  christos 
    961      1.1  christos   return type;
    962      1.1  christos }
    963      1.1  christos 
    964      1.1  christos ctf_id_t
    965  1.1.1.2  christos ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name)
    966  1.1.1.2  christos {
    967  1.1.1.2  christos   ctf_dtdef_t *dtd;
    968  1.1.1.2  christos   ctf_id_t type = 0;
    969  1.1.1.2  christos 
    970  1.1.1.2  christos   /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN)
    971  1.1.1.2  christos      or just return it.  */
    972  1.1.1.2  christos 
    973  1.1.1.2  christos   if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT
    974  1.1.1.2  christos       && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name)))
    975  1.1.1.2  christos     {
    976  1.1.1.2  christos       if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN)
    977  1.1.1.2  christos 	return type;
    978  1.1.1.2  christos       else
    979  1.1.1.2  christos 	{
    980  1.1.1.2  christos 	  ctf_err_warn (fp, 1, ECTF_CONFLICT,
    981  1.1.1.2  christos 			_("ctf_add_unknown: cannot add unknown type "
    982  1.1.1.2  christos 			  "named %s: type of this name already defined"),
    983  1.1.1.2  christos 			name ? name : _("(unnamed type)"));
    984  1.1.1.3  christos 	  return (ctf_set_typed_errno (fp, ECTF_CONFLICT));
    985  1.1.1.2  christos 	}
    986  1.1.1.2  christos     }
    987  1.1.1.2  christos 
    988  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR)
    989  1.1.1.2  christos     return CTF_ERR;		/* errno is set for us.  */
    990  1.1.1.2  christos 
    991  1.1.1.2  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0);
    992  1.1.1.2  christos   dtd->dtd_data.ctt_type = 0;
    993  1.1.1.2  christos 
    994  1.1.1.2  christos   return type;
    995  1.1.1.2  christos }
    996  1.1.1.2  christos 
    997  1.1.1.2  christos ctf_id_t
    998  1.1.1.2  christos ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
    999      1.1  christos 		 ctf_id_t ref)
   1000      1.1  christos {
   1001      1.1  christos   ctf_dtdef_t *dtd;
   1002      1.1  christos   ctf_id_t type;
   1003  1.1.1.2  christos   ctf_dict_t *tmp = fp;
   1004      1.1  christos 
   1005      1.1  christos   if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
   1006  1.1.1.3  christos     return (ctf_set_typed_errno (fp, EINVAL));
   1007      1.1  christos 
   1008  1.1.1.2  christos   if (name == NULL || name[0] == '\0')
   1009  1.1.1.3  christos     return (ctf_set_typed_errno (fp, ECTF_NONAME));
   1010  1.1.1.2  christos 
   1011  1.1.1.2  christos   if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
   1012      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
   1013      1.1  christos 
   1014  1.1.1.2  christos   if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
   1015      1.1  christos 			       &dtd)) == CTF_ERR)
   1016      1.1  christos     return CTF_ERR;		/* errno is set for us.  */
   1017      1.1  christos 
   1018      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
   1019      1.1  christos   dtd->dtd_data.ctt_type = (uint32_t) ref;
   1020      1.1  christos 
   1021      1.1  christos   return type;
   1022      1.1  christos }
   1023      1.1  christos 
   1024      1.1  christos ctf_id_t
   1025  1.1.1.2  christos ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
   1026      1.1  christos {
   1027      1.1  christos   return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
   1028      1.1  christos }
   1029      1.1  christos 
   1030      1.1  christos ctf_id_t
   1031  1.1.1.2  christos ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
   1032      1.1  christos {
   1033      1.1  christos   return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
   1034      1.1  christos }
   1035      1.1  christos 
   1036      1.1  christos ctf_id_t
   1037  1.1.1.2  christos ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
   1038      1.1  christos {
   1039      1.1  christos   return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
   1040      1.1  christos }
   1041      1.1  christos 
   1042      1.1  christos int
   1043  1.1.1.2  christos ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
   1044      1.1  christos 		    int value)
   1045      1.1  christos {
   1046  1.1.1.3  christos   ctf_dict_t *ofp = fp;
   1047  1.1.1.4  christos   ctf_dtdef_t *dtd;
   1048  1.1.1.2  christos   unsigned char *old_vlen;
   1049  1.1.1.2  christos   ctf_enum_t *en;
   1050      1.1  christos 
   1051      1.1  christos   uint32_t kind, vlen, root;
   1052      1.1  christos 
   1053      1.1  christos   if (name == NULL)
   1054      1.1  christos     return (ctf_set_errno (fp, EINVAL));
   1055      1.1  christos 
   1056  1.1.1.4  christos   if ((enid = ctf_type_resolve_unsliced (fp, enid)) == CTF_ERR)
   1057  1.1.1.4  christos       return -1;				/* errno is set for us.  */
   1058  1.1.1.4  christos 
   1059  1.1.1.4  christos   dtd = ctf_dtd_lookup (fp, enid);
   1060  1.1.1.3  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, enid))
   1061  1.1.1.3  christos     fp = fp->ctf_parent;
   1062  1.1.1.3  christos 
   1063  1.1.1.4  christos   if (enid < fp->ctf_stypes)
   1064  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_RDONLY));
   1065      1.1  christos 
   1066      1.1  christos   if (dtd == NULL)
   1067  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_BADID));
   1068      1.1  christos 
   1069      1.1  christos   kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
   1070      1.1  christos   root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
   1071      1.1  christos   vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
   1072      1.1  christos 
   1073  1.1.1.4  christos   /* Enumeration constant names are only added, and only checked for duplicates,
   1074  1.1.1.4  christos      if the enum they are part of is a root-visible type.  */
   1075  1.1.1.4  christos 
   1076  1.1.1.4  christos   if (root && ctf_dynhash_lookup (fp->ctf_names, name))
   1077  1.1.1.4  christos     {
   1078  1.1.1.4  christos       if (fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS)
   1079  1.1.1.4  christos 	return (ctf_set_errno (ofp, ECTF_DUPLICATE));
   1080  1.1.1.4  christos 
   1081  1.1.1.4  christos       if (ctf_track_enumerator (fp, enid, name) < 0)
   1082  1.1.1.4  christos 	return (ctf_set_errno (ofp, ctf_errno (fp)));
   1083  1.1.1.4  christos     }
   1084  1.1.1.4  christos 
   1085      1.1  christos   if (kind != CTF_K_ENUM)
   1086  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_NOTENUM));
   1087      1.1  christos 
   1088      1.1  christos   if (vlen == CTF_MAX_VLEN)
   1089  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_DTFULL));
   1090      1.1  christos 
   1091  1.1.1.2  christos   old_vlen = dtd->dtd_vlen;
   1092  1.1.1.4  christos 
   1093  1.1.1.2  christos   if (ctf_grow_vlen (fp, dtd, sizeof (ctf_enum_t) * (vlen + 1)) < 0)
   1094  1.1.1.2  christos     return -1;					/* errno is set for us.  */
   1095  1.1.1.4  christos 
   1096  1.1.1.2  christos   en = (ctf_enum_t *) dtd->dtd_vlen;
   1097  1.1.1.2  christos 
   1098  1.1.1.4  christos   /* Remove refs in the old vlen region and reapply them.  */
   1099  1.1.1.4  christos 
   1100  1.1.1.4  christos   ctf_str_move_refs (fp, old_vlen, sizeof (ctf_enum_t) * vlen, dtd->dtd_vlen);
   1101      1.1  christos 
   1102  1.1.1.4  christos   /* Check for constant duplication within any given enum: only needed for
   1103  1.1.1.4  christos      non-root-visible types, since the duplicate detection above does the job
   1104  1.1.1.4  christos      for root-visible types just fine.  */
   1105  1.1.1.4  christos 
   1106  1.1.1.4  christos   if (root == CTF_ADD_NONROOT && (fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS))
   1107  1.1.1.4  christos     {
   1108  1.1.1.4  christos       size_t i;
   1109      1.1  christos 
   1110  1.1.1.2  christos       for (i = 0; i < vlen; i++)
   1111  1.1.1.4  christos 	if (strcmp (ctf_strptr (fp, en[i].cte_name), name) == 0)
   1112  1.1.1.4  christos 	  return (ctf_set_errno (ofp, ECTF_DUPLICATE));
   1113      1.1  christos     }
   1114      1.1  christos 
   1115  1.1.1.4  christos   en[vlen].cte_name = ctf_str_add_movable_ref (fp, name, &en[vlen].cte_name);
   1116  1.1.1.4  christos   en[vlen].cte_value = value;
   1117  1.1.1.2  christos 
   1118  1.1.1.4  christos   if (en[vlen].cte_name == 0 && name != NULL && name[0] != '\0')
   1119  1.1.1.3  christos     return (ctf_set_errno (ofp, ctf_errno (fp)));
   1120      1.1  christos 
   1121  1.1.1.4  christos   /* Put the newly-added enumerator name into the name table if this type is
   1122  1.1.1.4  christos      root-visible.  */
   1123      1.1  christos 
   1124  1.1.1.4  christos   if (root == CTF_ADD_ROOT)
   1125  1.1.1.4  christos     {
   1126  1.1.1.4  christos       if (ctf_dynhash_insert (fp->ctf_names,
   1127  1.1.1.4  christos 			      (char *) ctf_strptr (fp, en[vlen].cte_name),
   1128  1.1.1.4  christos 			      (void *) (uintptr_t) enid) < 0)
   1129  1.1.1.4  christos 	return ctf_set_errno (fp, ENOMEM);
   1130  1.1.1.4  christos     }
   1131  1.1.1.4  christos 
   1132  1.1.1.4  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
   1133      1.1  christos 
   1134      1.1  christos   return 0;
   1135      1.1  christos }
   1136      1.1  christos 
   1137      1.1  christos int
   1138  1.1.1.2  christos ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
   1139      1.1  christos 		       ctf_id_t type, unsigned long bit_offset)
   1140      1.1  christos {
   1141  1.1.1.3  christos   ctf_dict_t *ofp = fp;
   1142      1.1  christos   ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
   1143      1.1  christos 
   1144      1.1  christos   ssize_t msize, malign, ssize;
   1145      1.1  christos   uint32_t kind, vlen, root;
   1146  1.1.1.2  christos   size_t i;
   1147  1.1.1.2  christos   int is_incomplete = 0;
   1148  1.1.1.2  christos   unsigned char *old_vlen;
   1149  1.1.1.2  christos   ctf_lmember_t *memb;
   1150      1.1  christos 
   1151  1.1.1.3  christos   if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, souid))
   1152  1.1.1.3  christos     {
   1153  1.1.1.3  christos       /* Adding a child type to a parent, even via the child, is prohibited.
   1154  1.1.1.3  christos 	 Otherwise, climb to the parent and do all work there.  */
   1155  1.1.1.3  christos 
   1156  1.1.1.3  christos       if (LCTF_TYPE_ISCHILD (fp, type))
   1157  1.1.1.3  christos 	return (ctf_set_errno (ofp, ECTF_BADID));
   1158  1.1.1.3  christos 
   1159  1.1.1.3  christos       fp = fp->ctf_parent;
   1160  1.1.1.3  christos     }
   1161  1.1.1.3  christos 
   1162  1.1.1.4  christos   if (souid < fp->ctf_stypes)
   1163  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_RDONLY));
   1164      1.1  christos 
   1165      1.1  christos   if (dtd == NULL)
   1166  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_BADID));
   1167      1.1  christos 
   1168  1.1.1.2  christos   if (name != NULL && name[0] == '\0')
   1169  1.1.1.2  christos     name = NULL;
   1170  1.1.1.2  christos 
   1171      1.1  christos   kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
   1172      1.1  christos   root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
   1173      1.1  christos   vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
   1174      1.1  christos 
   1175      1.1  christos   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
   1176  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_NOTSOU));
   1177      1.1  christos 
   1178      1.1  christos   if (vlen == CTF_MAX_VLEN)
   1179  1.1.1.3  christos     return (ctf_set_errno (ofp, ECTF_DTFULL));
   1180      1.1  christos 
   1181  1.1.1.2  christos   old_vlen = dtd->dtd_vlen;
   1182  1.1.1.2  christos   if (ctf_grow_vlen (fp, dtd, sizeof (ctf_lmember_t) * (vlen + 1)) < 0)
   1183  1.1.1.3  christos     return (ctf_set_errno (ofp, ctf_errno (fp)));
   1184  1.1.1.2  christos   memb = (ctf_lmember_t *) dtd->dtd_vlen;
   1185  1.1.1.2  christos 
   1186  1.1.1.4  christos   /* Remove pending refs in the old vlen region and reapply them.  */
   1187  1.1.1.2  christos 
   1188  1.1.1.4  christos   ctf_str_move_refs (fp, old_vlen, sizeof (ctf_lmember_t) * vlen, dtd->dtd_vlen);
   1189  1.1.1.2  christos 
   1190      1.1  christos   if (name != NULL)
   1191      1.1  christos     {
   1192  1.1.1.2  christos       for (i = 0; i < vlen; i++)
   1193  1.1.1.2  christos 	if (strcmp (ctf_strptr (fp, memb[i].ctlm_name), name) == 0)
   1194  1.1.1.3  christos 	  return (ctf_set_errno (ofp, ECTF_DUPLICATE));
   1195      1.1  christos     }
   1196      1.1  christos 
   1197      1.1  christos   if ((msize = ctf_type_size (fp, type)) < 0 ||
   1198      1.1  christos       (malign = ctf_type_align (fp, type)) < 0)
   1199      1.1  christos     {
   1200  1.1.1.2  christos       /* The unimplemented type, and any type that resolves to it, has no size
   1201  1.1.1.2  christos 	 and no alignment: it can correspond to any number of compiler-inserted
   1202  1.1.1.2  christos 	 types.  We allow incomplete types through since they are routinely
   1203  1.1.1.2  christos 	 added to the ends of structures, and can even be added elsewhere in
   1204  1.1.1.2  christos 	 structures by the deduplicator.  They are assumed to be zero-size with
   1205  1.1.1.2  christos 	 no alignment: this is often wrong, but problems can be avoided in this
   1206  1.1.1.2  christos 	 case by explicitly specifying the size of the structure via the _sized
   1207  1.1.1.2  christos 	 functions.  The deduplicator always does this.  */
   1208  1.1.1.2  christos 
   1209  1.1.1.2  christos       msize = 0;
   1210  1.1.1.2  christos       malign = 0;
   1211  1.1.1.2  christos       if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
   1212  1.1.1.2  christos 	ctf_set_errno (fp, 0);
   1213  1.1.1.2  christos       else if (ctf_errno (fp) == ECTF_INCOMPLETE)
   1214  1.1.1.2  christos 	is_incomplete = 1;
   1215  1.1.1.2  christos       else
   1216  1.1.1.2  christos 	return -1;		/* errno is set for us.  */
   1217      1.1  christos     }
   1218      1.1  christos 
   1219  1.1.1.4  christos   memb[vlen].ctlm_name = ctf_str_add_movable_ref (fp, name, &memb[vlen].ctlm_name);
   1220  1.1.1.2  christos   memb[vlen].ctlm_type = type;
   1221  1.1.1.2  christos   if (memb[vlen].ctlm_name == 0 && name != NULL && name[0] != '\0')
   1222  1.1.1.2  christos     return -1;			/* errno is set for us.  */
   1223      1.1  christos 
   1224      1.1  christos   if (kind == CTF_K_STRUCT && vlen != 0)
   1225      1.1  christos     {
   1226      1.1  christos       if (bit_offset == (unsigned long) - 1)
   1227      1.1  christos 	{
   1228      1.1  christos 	  /* Natural alignment.  */
   1229      1.1  christos 
   1230  1.1.1.2  christos 	  ctf_id_t ltype = ctf_type_resolve (fp, memb[vlen - 1].ctlm_type);
   1231  1.1.1.2  christos 	  size_t off = CTF_LMEM_OFFSET(&memb[vlen - 1]);
   1232      1.1  christos 
   1233      1.1  christos 	  ctf_encoding_t linfo;
   1234      1.1  christos 	  ssize_t lsize;
   1235      1.1  christos 
   1236  1.1.1.2  christos 	  /* Propagate any error from ctf_type_resolve.  If the last member was
   1237  1.1.1.2  christos 	     of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
   1238  1.1.1.2  christos 	     cannot insert right after such a member without explicit offset
   1239  1.1.1.2  christos 	     specification, because its alignment and size is not known.  */
   1240  1.1.1.2  christos 	  if (ltype == CTF_ERR)
   1241  1.1.1.2  christos 	    return -1;	/* errno is set for us.  */
   1242  1.1.1.2  christos 
   1243  1.1.1.2  christos 	  if (is_incomplete)
   1244  1.1.1.2  christos 	    {
   1245  1.1.1.3  christos 	      ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
   1246  1.1.1.2  christos 			    _("ctf_add_member_offset: cannot add member %s of "
   1247  1.1.1.2  christos 			      "incomplete type %lx to struct %lx without "
   1248  1.1.1.2  christos 			      "specifying explicit offset\n"),
   1249  1.1.1.2  christos 			    name ? name : _("(unnamed member)"), type, souid);
   1250  1.1.1.3  christos 	      return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
   1251  1.1.1.2  christos 	    }
   1252  1.1.1.2  christos 
   1253      1.1  christos 	  if (ctf_type_encoding (fp, ltype, &linfo) == 0)
   1254      1.1  christos 	    off += linfo.cte_bits;
   1255      1.1  christos 	  else if ((lsize = ctf_type_size (fp, ltype)) > 0)
   1256      1.1  christos 	    off += lsize * CHAR_BIT;
   1257  1.1.1.2  christos 	  else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
   1258  1.1.1.2  christos 	    {
   1259  1.1.1.2  christos 	      const char *lname = ctf_strraw (fp, memb[vlen - 1].ctlm_name);
   1260  1.1.1.2  christos 
   1261  1.1.1.3  christos 	      ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
   1262  1.1.1.2  christos 			    _("ctf_add_member_offset: cannot add member %s of "
   1263  1.1.1.2  christos 			      "type %lx to struct %lx without specifying "
   1264  1.1.1.2  christos 			      "explicit offset after member %s of type %lx, "
   1265  1.1.1.2  christos 			      "which is an incomplete type\n"),
   1266  1.1.1.2  christos 			    name ? name : _("(unnamed member)"), type, souid,
   1267  1.1.1.2  christos 			    lname ? lname : _("(unnamed member)"), ltype);
   1268  1.1.1.3  christos 	      return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
   1269  1.1.1.2  christos 	    }
   1270      1.1  christos 
   1271      1.1  christos 	  /* Round up the offset of the end of the last member to
   1272      1.1  christos 	     the next byte boundary, convert 'off' to bytes, and
   1273      1.1  christos 	     then round it up again to the next multiple of the
   1274      1.1  christos 	     alignment required by the new member.  Finally,
   1275      1.1  christos 	     convert back to bits and store the result in
   1276      1.1  christos 	     dmd_offset.  Technically we could do more efficient
   1277      1.1  christos 	     packing if the new member is a bit-field, but we're
   1278      1.1  christos 	     the "compiler" and ANSI says we can do as we choose.  */
   1279      1.1  christos 
   1280      1.1  christos 	  off = roundup (off, CHAR_BIT) / CHAR_BIT;
   1281      1.1  christos 	  off = roundup (off, MAX (malign, 1));
   1282  1.1.1.2  christos 	  memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (off * CHAR_BIT);
   1283  1.1.1.2  christos 	  memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (off * CHAR_BIT);
   1284      1.1  christos 	  ssize = off + msize;
   1285      1.1  christos 	}
   1286      1.1  christos       else
   1287      1.1  christos 	{
   1288      1.1  christos 	  /* Specified offset in bits.  */
   1289      1.1  christos 
   1290  1.1.1.2  christos 	  memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (bit_offset);
   1291  1.1.1.2  christos 	  memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (bit_offset);
   1292      1.1  christos 	  ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
   1293      1.1  christos 	  ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
   1294      1.1  christos 	}
   1295      1.1  christos     }
   1296      1.1  christos   else
   1297      1.1  christos     {
   1298  1.1.1.2  christos       memb[vlen].ctlm_offsethi = 0;
   1299  1.1.1.2  christos       memb[vlen].ctlm_offsetlo = 0;
   1300      1.1  christos       ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
   1301      1.1  christos       ssize = MAX (ssize, msize);
   1302      1.1  christos     }
   1303      1.1  christos 
   1304  1.1.1.2  christos   dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
   1305  1.1.1.2  christos   dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
   1306  1.1.1.2  christos   dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
   1307      1.1  christos   dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
   1308      1.1  christos 
   1309      1.1  christos   return 0;
   1310      1.1  christos }
   1311      1.1  christos 
   1312      1.1  christos int
   1313  1.1.1.2  christos ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
   1314      1.1  christos 			ctf_id_t type, unsigned long bit_offset,
   1315      1.1  christos 			const ctf_encoding_t encoding)
   1316      1.1  christos {
   1317      1.1  christos   ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
   1318  1.1.1.3  christos   int kind;
   1319      1.1  christos   int otype = type;
   1320      1.1  christos 
   1321  1.1.1.3  christos   if (dtd == NULL)
   1322  1.1.1.3  christos     return (ctf_set_errno (fp, ECTF_BADID));
   1323  1.1.1.3  christos 
   1324  1.1.1.3  christos   kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
   1325  1.1.1.3  christos 
   1326      1.1  christos   if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
   1327      1.1  christos     return (ctf_set_errno (fp, ECTF_NOTINTFP));
   1328      1.1  christos 
   1329      1.1  christos   if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
   1330      1.1  christos     return -1;			/* errno is set for us.  */
   1331      1.1  christos 
   1332      1.1  christos   return ctf_add_member_offset (fp, souid, name, type, bit_offset);
   1333      1.1  christos }
   1334      1.1  christos 
   1335      1.1  christos int
   1336  1.1.1.2  christos ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
   1337      1.1  christos 		ctf_id_t type)
   1338      1.1  christos {
   1339      1.1  christos   return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
   1340      1.1  christos }
   1341      1.1  christos 
   1342  1.1.1.4  christos /* Add a variable regardless of whether or not it is already present.
   1343  1.1.1.4  christos 
   1344  1.1.1.4  christos    Internal use only.  */
   1345      1.1  christos int
   1346  1.1.1.4  christos ctf_add_variable_forced (ctf_dict_t *fp, const char *name, ctf_id_t ref)
   1347      1.1  christos {
   1348      1.1  christos   ctf_dvdef_t *dvd;
   1349  1.1.1.2  christos   ctf_dict_t *tmp = fp;
   1350      1.1  christos 
   1351      1.1  christos   if (ctf_lookup_by_id (&tmp, ref) == NULL)
   1352      1.1  christos     return -1;			/* errno is set for us.  */
   1353      1.1  christos 
   1354      1.1  christos   /* Make sure this type is representable.  */
   1355      1.1  christos   if ((ctf_type_resolve (fp, ref) == CTF_ERR)
   1356      1.1  christos       && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
   1357      1.1  christos     return -1;
   1358      1.1  christos 
   1359      1.1  christos   if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
   1360      1.1  christos     return (ctf_set_errno (fp, EAGAIN));
   1361      1.1  christos 
   1362      1.1  christos   if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
   1363      1.1  christos     {
   1364      1.1  christos       free (dvd);
   1365      1.1  christos       return (ctf_set_errno (fp, EAGAIN));
   1366      1.1  christos     }
   1367      1.1  christos   dvd->dvd_type = ref;
   1368      1.1  christos   dvd->dvd_snapshots = fp->ctf_snapshots;
   1369      1.1  christos 
   1370      1.1  christos   if (ctf_dvd_insert (fp, dvd) < 0)
   1371      1.1  christos     {
   1372      1.1  christos       free (dvd->dvd_name);
   1373      1.1  christos       free (dvd);
   1374      1.1  christos       return -1;			/* errno is set for us.  */
   1375      1.1  christos     }
   1376      1.1  christos 
   1377      1.1  christos   return 0;
   1378      1.1  christos }
   1379      1.1  christos 
   1380  1.1.1.2  christos int
   1381  1.1.1.4  christos ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
   1382  1.1.1.4  christos {
   1383  1.1.1.4  christos   if (ctf_lookup_variable_here (fp, name) != CTF_ERR)
   1384  1.1.1.4  christos     return (ctf_set_errno (fp, ECTF_DUPLICATE));
   1385  1.1.1.4  christos 
   1386  1.1.1.4  christos   if (ctf_errno (fp) != ECTF_NOTYPEDAT)
   1387  1.1.1.4  christos     return -1;				/* errno is set for us.  */
   1388  1.1.1.4  christos 
   1389  1.1.1.4  christos   return ctf_add_variable_forced (fp, name, ref);
   1390  1.1.1.4  christos }
   1391  1.1.1.4  christos 
   1392  1.1.1.4  christos /* Add a function or object symbol regardless of whether or not it is already
   1393  1.1.1.4  christos    present (already existing symbols are silently overwritten).
   1394  1.1.1.4  christos 
   1395  1.1.1.4  christos    Internal use only.  */
   1396  1.1.1.4  christos int
   1397  1.1.1.4  christos ctf_add_funcobjt_sym_forced (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
   1398  1.1.1.2  christos {
   1399  1.1.1.2  christos   ctf_dict_t *tmp = fp;
   1400  1.1.1.2  christos   char *dupname;
   1401  1.1.1.2  christos   ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
   1402  1.1.1.2  christos 
   1403  1.1.1.2  christos   if (ctf_lookup_by_id (&tmp, id) == NULL)
   1404  1.1.1.4  christos     return -1;				/* errno is set for us.  */
   1405  1.1.1.2  christos 
   1406  1.1.1.2  christos   if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
   1407  1.1.1.2  christos     return (ctf_set_errno (fp, ECTF_NOTFUNC));
   1408  1.1.1.2  christos 
   1409  1.1.1.2  christos   if ((dupname = strdup (name)) == NULL)
   1410  1.1.1.2  christos     return (ctf_set_errno (fp, ENOMEM));
   1411  1.1.1.2  christos 
   1412  1.1.1.2  christos   if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
   1413  1.1.1.2  christos     {
   1414  1.1.1.2  christos       free (dupname);
   1415  1.1.1.2  christos       return (ctf_set_errno (fp, ENOMEM));
   1416  1.1.1.2  christos     }
   1417  1.1.1.2  christos   return 0;
   1418  1.1.1.2  christos }
   1419  1.1.1.2  christos 
   1420  1.1.1.2  christos int
   1421  1.1.1.4  christos ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
   1422  1.1.1.4  christos {
   1423  1.1.1.4  christos   if (ctf_lookup_by_sym_or_name (fp, 0, name, 0, is_function) != CTF_ERR)
   1424  1.1.1.4  christos     return (ctf_set_errno (fp, ECTF_DUPLICATE));
   1425  1.1.1.4  christos 
   1426  1.1.1.4  christos   return ctf_add_funcobjt_sym_forced (fp, is_function, name, id);
   1427  1.1.1.4  christos }
   1428  1.1.1.4  christos 
   1429  1.1.1.4  christos int
   1430  1.1.1.2  christos ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
   1431  1.1.1.2  christos {
   1432  1.1.1.2  christos   return (ctf_add_funcobjt_sym (fp, 0, name, id));
   1433  1.1.1.2  christos }
   1434  1.1.1.2  christos 
   1435  1.1.1.2  christos int
   1436  1.1.1.2  christos ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
   1437  1.1.1.2  christos {
   1438  1.1.1.2  christos   return (ctf_add_funcobjt_sym (fp, 1, name, id));
   1439  1.1.1.2  christos }
   1440  1.1.1.2  christos 
   1441  1.1.1.4  christos /* Add an enumeration constant observed in a given enum type as an identifier.
   1442  1.1.1.4  christos    They appear as names that cite the enum type.
   1443  1.1.1.4  christos 
   1444  1.1.1.4  christos    Constants that appear in more than one enum, or which are already the names
   1445  1.1.1.4  christos    of types, appear in ctf_conflicting_enums as well.
   1446  1.1.1.4  christos 
   1447  1.1.1.4  christos    This is done for all enumeration types at open time, and for newly-added ones
   1448  1.1.1.4  christos    as well: if the strict-enum flag is turned on, this table must be kept up to
   1449  1.1.1.4  christos    date with enums added in the interim.  */
   1450  1.1.1.4  christos 
   1451  1.1.1.4  christos int
   1452  1.1.1.4  christos ctf_track_enumerator (ctf_dict_t *fp, ctf_id_t type, const char *cte_name)
   1453  1.1.1.4  christos {
   1454  1.1.1.4  christos   int err;
   1455  1.1.1.4  christos 
   1456  1.1.1.4  christos   if (ctf_dynhash_lookup_type (fp->ctf_names, cte_name) == 0)
   1457  1.1.1.4  christos     {
   1458  1.1.1.4  christos       uint32_t name = ctf_str_add (fp, cte_name);
   1459  1.1.1.4  christos 
   1460  1.1.1.4  christos       if (name == 0)
   1461  1.1.1.4  christos 	return -1;				/* errno is set for us.  */
   1462  1.1.1.4  christos 
   1463  1.1.1.4  christos       err = ctf_dynhash_insert_type (fp, fp->ctf_names, type, name);
   1464  1.1.1.4  christos     }
   1465  1.1.1.4  christos   else
   1466  1.1.1.4  christos     {
   1467  1.1.1.4  christos       err = ctf_dynset_insert (fp->ctf_conflicting_enums, (void *)
   1468  1.1.1.4  christos 			       cte_name);
   1469  1.1.1.4  christos       if (err != 0)
   1470  1.1.1.4  christos 	ctf_set_errno (fp, err * -1);
   1471  1.1.1.4  christos     }
   1472  1.1.1.4  christos   if (err != 0)
   1473  1.1.1.4  christos     return -1;					/* errno is set for us.  */
   1474  1.1.1.4  christos   return 0;
   1475  1.1.1.4  christos }
   1476  1.1.1.4  christos 
   1477  1.1.1.2  christos typedef struct ctf_bundle
   1478  1.1.1.2  christos {
   1479  1.1.1.2  christos   ctf_dict_t *ctb_dict;		/* CTF dict handle.  */
   1480  1.1.1.2  christos   ctf_id_t ctb_type;		/* CTF type identifier.  */
   1481  1.1.1.2  christos   ctf_dtdef_t *ctb_dtd;		/* CTF dynamic type definition (if any).  */
   1482  1.1.1.2  christos } ctf_bundle_t;
   1483  1.1.1.2  christos 
   1484      1.1  christos static int
   1485      1.1  christos enumcmp (const char *name, int value, void *arg)
   1486      1.1  christos {
   1487      1.1  christos   ctf_bundle_t *ctb = arg;
   1488      1.1  christos   int bvalue;
   1489      1.1  christos 
   1490  1.1.1.2  christos   if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
   1491      1.1  christos     {
   1492  1.1.1.2  christos       ctf_err_warn (ctb->ctb_dict, 0, 0,
   1493  1.1.1.2  christos 		    _("conflict due to enum %s iteration error"), name);
   1494      1.1  christos       return 1;
   1495      1.1  christos     }
   1496      1.1  christos   if (value != bvalue)
   1497      1.1  christos     {
   1498  1.1.1.2  christos       ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
   1499  1.1.1.2  christos 		    _("conflict due to enum value change: %i versus %i"),
   1500  1.1.1.2  christos 		    value, bvalue);
   1501      1.1  christos       return 1;
   1502      1.1  christos     }
   1503      1.1  christos   return 0;
   1504      1.1  christos }
   1505      1.1  christos 
   1506      1.1  christos static int
   1507      1.1  christos enumadd (const char *name, int value, void *arg)
   1508      1.1  christos {
   1509      1.1  christos   ctf_bundle_t *ctb = arg;
   1510      1.1  christos 
   1511  1.1.1.2  christos   return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
   1512      1.1  christos 			      name, value) < 0);
   1513      1.1  christos }
   1514      1.1  christos 
   1515      1.1  christos static int
   1516      1.1  christos membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
   1517      1.1  christos 	 void *arg)
   1518      1.1  christos {
   1519      1.1  christos   ctf_bundle_t *ctb = arg;
   1520      1.1  christos   ctf_membinfo_t ctm;
   1521      1.1  christos 
   1522  1.1.1.2  christos   /* Don't check nameless members (e.g. anonymous structs/unions) against each
   1523  1.1.1.2  christos      other.  */
   1524  1.1.1.2  christos   if (name[0] == 0)
   1525  1.1.1.2  christos     return 0;
   1526  1.1.1.2  christos 
   1527  1.1.1.2  christos   if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
   1528      1.1  christos     {
   1529  1.1.1.2  christos       ctf_err_warn (ctb->ctb_dict, 0, 0,
   1530  1.1.1.2  christos 		    _("conflict due to struct member %s iteration error"),
   1531  1.1.1.2  christos 		    name);
   1532      1.1  christos       return 1;
   1533      1.1  christos     }
   1534      1.1  christos   if (ctm.ctm_offset != offset)
   1535      1.1  christos     {
   1536  1.1.1.2  christos       ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
   1537  1.1.1.2  christos 		    _("conflict due to struct member %s offset change: "
   1538  1.1.1.2  christos 		      "%lx versus %lx"),
   1539  1.1.1.2  christos 		    name, ctm.ctm_offset, offset);
   1540      1.1  christos       return 1;
   1541      1.1  christos     }
   1542      1.1  christos   return 0;
   1543      1.1  christos }
   1544      1.1  christos 
   1545  1.1.1.2  christos /* Record the correspondence between a source and ctf_add_type()-added
   1546  1.1.1.2  christos    destination type: both types are translated into parent type IDs if need be,
   1547  1.1.1.2  christos    so they relate to the actual dictionary they are in.  Outside controlled
   1548  1.1.1.2  christos    circumstances (like linking) it is probably not useful to do more than
   1549  1.1.1.2  christos    compare these pointers, since there is nothing stopping the user closing the
   1550  1.1.1.2  christos    source dict whenever they want to.
   1551  1.1.1.2  christos 
   1552  1.1.1.2  christos    Our OOM handling here is just to not do anything, because this is called deep
   1553  1.1.1.2  christos    enough in the call stack that doing anything useful is painfully difficult:
   1554  1.1.1.2  christos    the worst consequence if we do OOM is a bit of type duplication anyway.  */
   1555  1.1.1.2  christos 
   1556  1.1.1.2  christos static void
   1557  1.1.1.2  christos ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
   1558  1.1.1.2  christos 		      ctf_dict_t *dst_fp, ctf_id_t dst_type)
   1559      1.1  christos {
   1560  1.1.1.2  christos   if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
   1561  1.1.1.2  christos     src_fp = src_fp->ctf_parent;
   1562  1.1.1.2  christos 
   1563  1.1.1.2  christos   src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
   1564      1.1  christos 
   1565  1.1.1.2  christos   if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
   1566  1.1.1.2  christos     dst_fp = dst_fp->ctf_parent;
   1567      1.1  christos 
   1568  1.1.1.2  christos   dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
   1569  1.1.1.2  christos 
   1570  1.1.1.2  christos   if (dst_fp->ctf_link_type_mapping == NULL)
   1571      1.1  christos     {
   1572  1.1.1.2  christos       ctf_hash_fun f = ctf_hash_type_key;
   1573  1.1.1.2  christos       ctf_hash_eq_fun e = ctf_hash_eq_type_key;
   1574  1.1.1.2  christos 
   1575  1.1.1.2  christos       if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
   1576  1.1.1.2  christos 							       NULL)) == NULL)
   1577  1.1.1.2  christos 	return;
   1578      1.1  christos     }
   1579      1.1  christos 
   1580  1.1.1.2  christos   ctf_link_type_key_t *key;
   1581  1.1.1.2  christos   key = calloc (1, sizeof (struct ctf_link_type_key));
   1582  1.1.1.2  christos   if (!key)
   1583  1.1.1.2  christos     return;
   1584      1.1  christos 
   1585  1.1.1.2  christos   key->cltk_fp = src_fp;
   1586  1.1.1.2  christos   key->cltk_idx = src_type;
   1587      1.1  christos 
   1588  1.1.1.2  christos   /* No OOM checking needed, because if this doesn't work the worst we'll do is
   1589  1.1.1.2  christos      add a few more duplicate types (which will probably run out of memory
   1590  1.1.1.2  christos      anyway).  */
   1591  1.1.1.2  christos   ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
   1592  1.1.1.2  christos 		      (void *) (uintptr_t) dst_type);
   1593      1.1  christos }
   1594      1.1  christos 
   1595  1.1.1.2  christos /* Look up a type mapping: return 0 if none.  The DST_FP is modified to point to
   1596  1.1.1.2  christos    the parent if need be.  The ID returned is from the dst_fp's perspective.  */
   1597  1.1.1.2  christos static ctf_id_t
   1598  1.1.1.2  christos ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
   1599  1.1.1.2  christos {
   1600  1.1.1.2  christos   ctf_link_type_key_t key;
   1601  1.1.1.2  christos   ctf_dict_t *target_fp = *dst_fp;
   1602  1.1.1.2  christos   ctf_id_t dst_type = 0;
   1603  1.1.1.2  christos 
   1604  1.1.1.2  christos   if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
   1605  1.1.1.2  christos     src_fp = src_fp->ctf_parent;
   1606  1.1.1.2  christos 
   1607  1.1.1.2  christos   src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
   1608  1.1.1.2  christos   key.cltk_fp = src_fp;
   1609  1.1.1.2  christos   key.cltk_idx = src_type;
   1610  1.1.1.2  christos 
   1611  1.1.1.2  christos   if (target_fp->ctf_link_type_mapping)
   1612  1.1.1.2  christos     dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
   1613  1.1.1.2  christos 					       &key);
   1614  1.1.1.2  christos 
   1615  1.1.1.2  christos   if (dst_type != 0)
   1616  1.1.1.2  christos     {
   1617  1.1.1.2  christos       dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
   1618  1.1.1.2  christos 				     target_fp->ctf_parent != NULL);
   1619  1.1.1.2  christos       *dst_fp = target_fp;
   1620  1.1.1.2  christos       return dst_type;
   1621  1.1.1.2  christos     }
   1622  1.1.1.2  christos 
   1623  1.1.1.2  christos   if (target_fp->ctf_parent)
   1624  1.1.1.2  christos     target_fp = target_fp->ctf_parent;
   1625  1.1.1.2  christos   else
   1626  1.1.1.2  christos     return 0;
   1627  1.1.1.2  christos 
   1628  1.1.1.2  christos   if (target_fp->ctf_link_type_mapping)
   1629  1.1.1.2  christos     dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
   1630  1.1.1.2  christos 					       &key);
   1631  1.1.1.2  christos 
   1632  1.1.1.2  christos   if (dst_type)
   1633  1.1.1.2  christos     dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
   1634  1.1.1.2  christos 				   target_fp->ctf_parent != NULL);
   1635  1.1.1.2  christos 
   1636  1.1.1.2  christos   *dst_fp = target_fp;
   1637  1.1.1.2  christos   return dst_type;
   1638  1.1.1.2  christos }
   1639  1.1.1.2  christos 
   1640  1.1.1.2  christos /* The ctf_add_type routine is used to copy a type from a source CTF dictionary
   1641  1.1.1.2  christos    to a dynamic destination dictionary.  This routine operates recursively by
   1642      1.1  christos    following the source type's links and embedded member types.  If the
   1643  1.1.1.2  christos    destination dict already contains a named type which has the same attributes,
   1644  1.1.1.2  christos    then we succeed and return this type but no changes occur.  */
   1645      1.1  christos static ctf_id_t
   1646  1.1.1.2  christos ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
   1647  1.1.1.2  christos 		       ctf_dict_t *proc_tracking_fp)
   1648      1.1  christos {
   1649      1.1  christos   ctf_id_t dst_type = CTF_ERR;
   1650      1.1  christos   uint32_t dst_kind = CTF_K_UNKNOWN;
   1651  1.1.1.2  christos   ctf_dict_t *tmp_fp = dst_fp;
   1652      1.1  christos   ctf_id_t tmp;
   1653      1.1  christos 
   1654      1.1  christos   const char *name;
   1655      1.1  christos   uint32_t kind, forward_kind, flag, vlen;
   1656      1.1  christos 
   1657      1.1  christos   const ctf_type_t *src_tp, *dst_tp;
   1658      1.1  christos   ctf_bundle_t src, dst;
   1659      1.1  christos   ctf_encoding_t src_en, dst_en;
   1660      1.1  christos   ctf_arinfo_t src_ar, dst_ar;
   1661      1.1  christos 
   1662      1.1  christos   ctf_funcinfo_t ctc;
   1663      1.1  christos 
   1664      1.1  christos   ctf_id_t orig_src_type = src_type;
   1665      1.1  christos 
   1666      1.1  christos   if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
   1667  1.1.1.3  christos     return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
   1668      1.1  christos 
   1669      1.1  christos   if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
   1670      1.1  christos       && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
   1671  1.1.1.3  christos     return (ctf_set_typed_errno (dst_fp, ECTF_NONREPRESENTABLE));
   1672      1.1  christos 
   1673      1.1  christos   name = ctf_strptr (src_fp, src_tp->ctt_name);
   1674      1.1  christos   kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
   1675      1.1  christos   flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
   1676      1.1  christos   vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
   1677      1.1  christos 
   1678      1.1  christos   /* If this is a type we are currently in the middle of adding, hand it
   1679      1.1  christos      straight back.  (This lets us handle self-referential structures without
   1680      1.1  christos      considering forwards and empty structures the same as their completed
   1681      1.1  christos      forms.)  */
   1682      1.1  christos 
   1683      1.1  christos   tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
   1684      1.1  christos 
   1685      1.1  christos   if (tmp != 0)
   1686      1.1  christos     {
   1687      1.1  christos       if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
   1688      1.1  christos 			      (void *) (uintptr_t) src_type))
   1689      1.1  christos 	return tmp;
   1690      1.1  christos 
   1691  1.1.1.2  christos       /* If this type has already been added from this dictionary, and is the
   1692  1.1.1.2  christos 	 same kind and (if a struct or union) has the same number of members,
   1693  1.1.1.2  christos 	 hand it straight back.  */
   1694  1.1.1.2  christos 
   1695  1.1.1.2  christos       if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
   1696      1.1  christos 	{
   1697  1.1.1.2  christos 	  if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
   1698  1.1.1.2  christos 	      || kind == CTF_K_ENUM)
   1699  1.1.1.2  christos 	    {
   1700  1.1.1.2  christos 	      if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
   1701  1.1.1.2  christos 		if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
   1702  1.1.1.2  christos 		  return tmp;
   1703  1.1.1.2  christos 	    }
   1704  1.1.1.2  christos 	  else
   1705  1.1.1.2  christos 	    return tmp;
   1706      1.1  christos 	}
   1707      1.1  christos     }
   1708      1.1  christos 
   1709      1.1  christos   forward_kind = kind;
   1710      1.1  christos   if (kind == CTF_K_FORWARD)
   1711      1.1  christos     forward_kind = src_tp->ctt_type;
   1712      1.1  christos 
   1713  1.1.1.2  christos   /* If the source type has a name and is a root type (visible at the top-level
   1714  1.1.1.2  christos      scope), lookup the name in the destination dictionary and verify that it is
   1715  1.1.1.2  christos      of the same kind before we do anything else.  */
   1716      1.1  christos 
   1717      1.1  christos   if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
   1718      1.1  christos       && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
   1719      1.1  christos     {
   1720      1.1  christos       dst_type = tmp;
   1721      1.1  christos       dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
   1722      1.1  christos     }
   1723      1.1  christos 
   1724      1.1  christos   /* If an identically named dst_type exists, fail with ECTF_CONFLICT
   1725      1.1  christos      unless dst_type is a forward declaration and src_type is a struct,
   1726      1.1  christos      union, or enum (i.e. the definition of the previous forward decl).
   1727      1.1  christos 
   1728      1.1  christos      We also allow addition in the opposite order (addition of a forward when a
   1729      1.1  christos      struct, union, or enum already exists), which is a NOP and returns the
   1730      1.1  christos      already-present struct, union, or enum.  */
   1731      1.1  christos 
   1732      1.1  christos   if (dst_type != CTF_ERR && dst_kind != kind)
   1733      1.1  christos     {
   1734      1.1  christos       if (kind == CTF_K_FORWARD
   1735      1.1  christos 	  && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
   1736      1.1  christos 	      || dst_kind == CTF_K_UNION))
   1737      1.1  christos 	{
   1738      1.1  christos 	  ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
   1739      1.1  christos 	  return dst_type;
   1740      1.1  christos 	}
   1741      1.1  christos 
   1742      1.1  christos       if (dst_kind != CTF_K_FORWARD
   1743      1.1  christos 	  || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
   1744      1.1  christos 	      && kind != CTF_K_UNION))
   1745      1.1  christos 	{
   1746  1.1.1.2  christos 	  ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
   1747  1.1.1.2  christos 			_("ctf_add_type: conflict for type %s: "
   1748  1.1.1.2  christos 			  "kinds differ, new: %i; old (ID %lx): %i"),
   1749  1.1.1.2  christos 			name, kind, dst_type, dst_kind);
   1750  1.1.1.3  christos 	  return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   1751      1.1  christos 	}
   1752      1.1  christos     }
   1753      1.1  christos 
   1754      1.1  christos   /* We take special action for an integer, float, or slice since it is
   1755      1.1  christos      described not only by its name but also its encoding.  For integers,
   1756      1.1  christos      bit-fields exploit this degeneracy.  */
   1757      1.1  christos 
   1758      1.1  christos   if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
   1759      1.1  christos     {
   1760      1.1  christos       if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
   1761  1.1.1.3  christos 	return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
   1762      1.1  christos 
   1763      1.1  christos       if (dst_type != CTF_ERR)
   1764      1.1  christos 	{
   1765  1.1.1.2  christos 	  ctf_dict_t *fp = dst_fp;
   1766      1.1  christos 
   1767      1.1  christos 	  if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
   1768      1.1  christos 	    return CTF_ERR;
   1769      1.1  christos 
   1770      1.1  christos 	  if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
   1771      1.1  christos 	    return CTF_ERR;			/* errno set for us.  */
   1772      1.1  christos 
   1773      1.1  christos 	  if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
   1774      1.1  christos 	    {
   1775      1.1  christos 	      /* The type that we found in the hash is also root-visible.  If
   1776      1.1  christos 		 the two types match then use the existing one; otherwise,
   1777      1.1  christos 		 declare a conflict.  Note: slices are not certain to match
   1778      1.1  christos 		 even if there is no conflict: we must check the contained type
   1779      1.1  christos 		 too.  */
   1780      1.1  christos 
   1781      1.1  christos 	      if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
   1782      1.1  christos 		{
   1783      1.1  christos 		  if (kind != CTF_K_SLICE)
   1784      1.1  christos 		    {
   1785      1.1  christos 		      ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
   1786      1.1  christos 		      return dst_type;
   1787      1.1  christos 		    }
   1788      1.1  christos 		}
   1789      1.1  christos 	      else
   1790      1.1  christos 		  {
   1791  1.1.1.3  christos 		    return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   1792      1.1  christos 		  }
   1793      1.1  christos 	    }
   1794      1.1  christos 	  else
   1795      1.1  christos 	    {
   1796      1.1  christos 	      /* We found a non-root-visible type in the hash.  If its encoding
   1797      1.1  christos 		 is the same, we can reuse it, unless it is a slice.  */
   1798      1.1  christos 
   1799      1.1  christos 	      if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
   1800      1.1  christos 		{
   1801      1.1  christos 		  if (kind != CTF_K_SLICE)
   1802      1.1  christos 		    {
   1803      1.1  christos 		      ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
   1804      1.1  christos 		      return dst_type;
   1805      1.1  christos 		    }
   1806      1.1  christos 		}
   1807      1.1  christos 	    }
   1808      1.1  christos 	}
   1809      1.1  christos     }
   1810      1.1  christos 
   1811  1.1.1.2  christos   src.ctb_dict = src_fp;
   1812      1.1  christos   src.ctb_type = src_type;
   1813      1.1  christos   src.ctb_dtd = NULL;
   1814      1.1  christos 
   1815  1.1.1.2  christos   dst.ctb_dict = dst_fp;
   1816      1.1  christos   dst.ctb_type = dst_type;
   1817      1.1  christos   dst.ctb_dtd = NULL;
   1818      1.1  christos 
   1819      1.1  christos   /* Now perform kind-specific processing.  If dst_type is CTF_ERR, then we add
   1820      1.1  christos      a new type with the same properties as src_type to dst_fp.  If dst_type is
   1821      1.1  christos      not CTF_ERR, then we verify that dst_type has the same attributes as
   1822      1.1  christos      src_type.  We recurse for embedded references.  Before we start, we note
   1823      1.1  christos      that we are processing this type, to prevent infinite recursion: we do not
   1824      1.1  christos      re-process any type that appears in this list.  The list is emptied
   1825      1.1  christos      wholesale at the end of processing everything in this recursive stack.  */
   1826      1.1  christos 
   1827      1.1  christos   if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
   1828      1.1  christos 			  (void *) (uintptr_t) src_type, (void *) 1) < 0)
   1829  1.1.1.3  christos     return ctf_set_typed_errno (dst_fp, ENOMEM);
   1830      1.1  christos 
   1831      1.1  christos   switch (kind)
   1832      1.1  christos     {
   1833      1.1  christos     case CTF_K_INTEGER:
   1834      1.1  christos       /*  If we found a match we will have either returned it or declared a
   1835      1.1  christos 	  conflict.  */
   1836      1.1  christos       dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
   1837      1.1  christos       break;
   1838      1.1  christos 
   1839      1.1  christos     case CTF_K_FLOAT:
   1840      1.1  christos       /* If we found a match we will have either returned it or declared a
   1841      1.1  christos        conflict.  */
   1842      1.1  christos       dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
   1843      1.1  christos       break;
   1844      1.1  christos 
   1845      1.1  christos     case CTF_K_SLICE:
   1846      1.1  christos       /* We have checked for conflicting encodings: now try to add the
   1847      1.1  christos 	 contained type.  */
   1848      1.1  christos       src_type = ctf_type_reference (src_fp, src_type);
   1849      1.1  christos       src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
   1850      1.1  christos 					proc_tracking_fp);
   1851      1.1  christos 
   1852      1.1  christos       if (src_type == CTF_ERR)
   1853      1.1  christos 	return CTF_ERR;				/* errno is set for us.  */
   1854      1.1  christos 
   1855      1.1  christos       dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
   1856      1.1  christos       break;
   1857      1.1  christos 
   1858      1.1  christos     case CTF_K_POINTER:
   1859      1.1  christos     case CTF_K_VOLATILE:
   1860      1.1  christos     case CTF_K_CONST:
   1861      1.1  christos     case CTF_K_RESTRICT:
   1862      1.1  christos       src_type = ctf_type_reference (src_fp, src_type);
   1863      1.1  christos       src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
   1864      1.1  christos 					proc_tracking_fp);
   1865      1.1  christos 
   1866      1.1  christos       if (src_type == CTF_ERR)
   1867      1.1  christos 	return CTF_ERR;				/* errno is set for us.  */
   1868      1.1  christos 
   1869      1.1  christos       dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
   1870      1.1  christos       break;
   1871      1.1  christos 
   1872      1.1  christos     case CTF_K_ARRAY:
   1873      1.1  christos       if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
   1874  1.1.1.3  christos 	return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
   1875      1.1  christos 
   1876      1.1  christos       src_ar.ctr_contents =
   1877      1.1  christos 	ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
   1878      1.1  christos 			       proc_tracking_fp);
   1879      1.1  christos       src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
   1880      1.1  christos 						src_ar.ctr_index,
   1881      1.1  christos 						proc_tracking_fp);
   1882      1.1  christos       src_ar.ctr_nelems = src_ar.ctr_nelems;
   1883      1.1  christos 
   1884      1.1  christos       if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
   1885      1.1  christos 	return CTF_ERR;				/* errno is set for us.  */
   1886      1.1  christos 
   1887      1.1  christos       if (dst_type != CTF_ERR)
   1888      1.1  christos 	{
   1889      1.1  christos 	  if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
   1890      1.1  christos 	    return CTF_ERR;			/* errno is set for us.  */
   1891      1.1  christos 
   1892      1.1  christos 	  if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
   1893      1.1  christos 	    {
   1894  1.1.1.2  christos 	      ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
   1895  1.1.1.2  christos 			    _("conflict for type %s against ID %lx: array info "
   1896  1.1.1.2  christos 			      "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
   1897  1.1.1.2  christos 			    name, dst_type, src_ar.ctr_contents,
   1898  1.1.1.2  christos 			    src_ar.ctr_index, src_ar.ctr_nelems,
   1899  1.1.1.2  christos 			    dst_ar.ctr_contents, dst_ar.ctr_index,
   1900  1.1.1.2  christos 			    dst_ar.ctr_nelems);
   1901  1.1.1.3  christos 	      return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   1902      1.1  christos 	    }
   1903      1.1  christos 	}
   1904      1.1  christos       else
   1905      1.1  christos 	dst_type = ctf_add_array (dst_fp, flag, &src_ar);
   1906      1.1  christos       break;
   1907      1.1  christos 
   1908      1.1  christos     case CTF_K_FUNCTION:
   1909      1.1  christos       ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
   1910      1.1  christos 					      src_tp->ctt_type,
   1911      1.1  christos 					      proc_tracking_fp);
   1912      1.1  christos       ctc.ctc_argc = 0;
   1913      1.1  christos       ctc.ctc_flags = 0;
   1914      1.1  christos 
   1915      1.1  christos       if (ctc.ctc_return == CTF_ERR)
   1916      1.1  christos 	return CTF_ERR;				/* errno is set for us.  */
   1917      1.1  christos 
   1918      1.1  christos       dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
   1919      1.1  christos       break;
   1920      1.1  christos 
   1921      1.1  christos     case CTF_K_STRUCT:
   1922      1.1  christos     case CTF_K_UNION:
   1923      1.1  christos       {
   1924  1.1.1.2  christos 	ctf_next_t *i = NULL;
   1925  1.1.1.2  christos 	ssize_t offset;
   1926  1.1.1.2  christos 	const char *membname;
   1927  1.1.1.2  christos 	ctf_id_t src_membtype;
   1928      1.1  christos 
   1929      1.1  christos 	/* Technically to match a struct or union we need to check both
   1930      1.1  christos 	   ways (src members vs. dst, dst members vs. src) but we make
   1931      1.1  christos 	   this more optimal by only checking src vs. dst and comparing
   1932      1.1  christos 	   the total size of the structure (which we must do anyway)
   1933      1.1  christos 	   which covers the possibility of dst members not in src.
   1934      1.1  christos 	   This optimization can be defeated for unions, but is so
   1935      1.1  christos 	   pathological as to render it irrelevant for our purposes.  */
   1936      1.1  christos 
   1937      1.1  christos 	if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
   1938      1.1  christos 	    && dst_kind != CTF_K_FORWARD)
   1939      1.1  christos 	  {
   1940      1.1  christos 	    if (ctf_type_size (src_fp, src_type) !=
   1941      1.1  christos 		ctf_type_size (dst_fp, dst_type))
   1942      1.1  christos 	      {
   1943  1.1.1.2  christos 		ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
   1944  1.1.1.2  christos 			      _("conflict for type %s against ID %lx: union "
   1945  1.1.1.2  christos 				"size differs, old %li, new %li"), name,
   1946  1.1.1.2  christos 			      dst_type, (long) ctf_type_size (src_fp, src_type),
   1947  1.1.1.2  christos 			      (long) ctf_type_size (dst_fp, dst_type));
   1948  1.1.1.3  christos 		return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   1949      1.1  christos 	      }
   1950      1.1  christos 
   1951      1.1  christos 	    if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
   1952      1.1  christos 	      {
   1953  1.1.1.2  christos 		ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
   1954  1.1.1.2  christos 			      _("conflict for type %s against ID %lx: members "
   1955  1.1.1.2  christos 				"differ, see above"), name, dst_type);
   1956  1.1.1.3  christos 		return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   1957      1.1  christos 	      }
   1958      1.1  christos 
   1959      1.1  christos 	    break;
   1960      1.1  christos 	  }
   1961      1.1  christos 
   1962  1.1.1.2  christos 	dst_type = ctf_add_struct_sized (dst_fp, flag, name,
   1963  1.1.1.2  christos 					 ctf_type_size (src_fp, src_type));
   1964      1.1  christos 	if (dst_type == CTF_ERR)
   1965      1.1  christos 	  return CTF_ERR;			/* errno is set for us.  */
   1966      1.1  christos 
   1967      1.1  christos 	/* Pre-emptively add this struct to the type mapping so that
   1968      1.1  christos 	   structures that refer to themselves work.  */
   1969      1.1  christos 	ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
   1970      1.1  christos 
   1971  1.1.1.2  christos 	while ((offset = ctf_member_next (src_fp, src_type, &i, &membname,
   1972  1.1.1.2  christos 					  &src_membtype, 0)) >= 0)
   1973      1.1  christos 	  {
   1974  1.1.1.2  christos 	    ctf_dict_t *dst = dst_fp;
   1975  1.1.1.2  christos 	    ctf_id_t dst_membtype = ctf_type_mapping (src_fp, src_membtype, &dst);
   1976      1.1  christos 
   1977  1.1.1.2  christos 	    if (dst_membtype == 0)
   1978      1.1  christos 	      {
   1979  1.1.1.2  christos 		dst_membtype = ctf_add_type_internal (dst_fp, src_fp,
   1980  1.1.1.2  christos 						      src_membtype,
   1981  1.1.1.2  christos 						      proc_tracking_fp);
   1982  1.1.1.2  christos 		if (dst_membtype == CTF_ERR)
   1983      1.1  christos 		  {
   1984      1.1  christos 		    if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
   1985  1.1.1.2  christos 		      {
   1986  1.1.1.2  christos 			ctf_next_destroy (i);
   1987  1.1.1.2  christos 			break;
   1988  1.1.1.2  christos 		      }
   1989      1.1  christos 		  }
   1990      1.1  christos 	      }
   1991      1.1  christos 
   1992  1.1.1.2  christos 	    if (ctf_add_member_offset (dst_fp, dst_type, membname,
   1993  1.1.1.2  christos 				       dst_membtype, offset) < 0)
   1994  1.1.1.2  christos 	      {
   1995  1.1.1.2  christos 		ctf_next_destroy (i);
   1996  1.1.1.2  christos 		break;
   1997  1.1.1.2  christos 	      }
   1998  1.1.1.2  christos 	  }
   1999  1.1.1.2  christos 	if (ctf_errno (src_fp) != ECTF_NEXT_END)
   2000      1.1  christos 	  return CTF_ERR;			/* errno is set for us.  */
   2001      1.1  christos 	break;
   2002      1.1  christos       }
   2003      1.1  christos 
   2004      1.1  christos     case CTF_K_ENUM:
   2005      1.1  christos       if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
   2006      1.1  christos 	  && dst_kind != CTF_K_FORWARD)
   2007      1.1  christos 	{
   2008      1.1  christos 	  if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
   2009      1.1  christos 	      || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
   2010      1.1  christos 	    {
   2011  1.1.1.2  christos 	      ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
   2012  1.1.1.2  christos 			    _("conflict for enum %s against ID %lx: members "
   2013  1.1.1.2  christos 			      "differ, see above"), name, dst_type);
   2014  1.1.1.3  christos 	      return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
   2015      1.1  christos 	    }
   2016      1.1  christos 	}
   2017      1.1  christos       else
   2018      1.1  christos 	{
   2019  1.1.1.4  christos 	  ctf_snapshot_id_t snap = ctf_snapshot (dst_fp);
   2020  1.1.1.4  christos 
   2021      1.1  christos 	  dst_type = ctf_add_enum (dst_fp, flag, name);
   2022      1.1  christos 	  if ((dst.ctb_type = dst_type) == CTF_ERR
   2023      1.1  christos 	      || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
   2024  1.1.1.4  christos 	    {
   2025  1.1.1.4  christos 	      ctf_rollback (dst_fp, snap);
   2026  1.1.1.4  christos 	      return CTF_ERR;			/* errno is set for us */
   2027  1.1.1.4  christos 	    }
   2028      1.1  christos 	}
   2029      1.1  christos       break;
   2030      1.1  christos 
   2031      1.1  christos     case CTF_K_FORWARD:
   2032      1.1  christos       if (dst_type == CTF_ERR)
   2033      1.1  christos 	  dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
   2034      1.1  christos       break;
   2035      1.1  christos 
   2036      1.1  christos     case CTF_K_TYPEDEF:
   2037      1.1  christos       src_type = ctf_type_reference (src_fp, src_type);
   2038      1.1  christos       src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
   2039      1.1  christos 					proc_tracking_fp);
   2040      1.1  christos 
   2041      1.1  christos       if (src_type == CTF_ERR)
   2042      1.1  christos 	return CTF_ERR;				/* errno is set for us.  */
   2043      1.1  christos 
   2044      1.1  christos       /* If dst_type is not CTF_ERR at this point, we should check if
   2045      1.1  christos 	 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
   2046      1.1  christos 	 ECTF_CONFLICT.  However, this causes problems with bitness typedefs
   2047      1.1  christos 	 that vary based on things like if 32-bit then pid_t is int otherwise
   2048      1.1  christos 	 long.  We therefore omit this check and assume that if the identically
   2049      1.1  christos 	 named typedef already exists in dst_fp, it is correct or
   2050      1.1  christos 	 equivalent.  */
   2051      1.1  christos 
   2052      1.1  christos       if (dst_type == CTF_ERR)
   2053      1.1  christos 	  dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
   2054      1.1  christos 
   2055      1.1  christos       break;
   2056      1.1  christos 
   2057      1.1  christos     default:
   2058  1.1.1.3  christos       return (ctf_set_typed_errno (dst_fp, ECTF_CORRUPT));
   2059      1.1  christos     }
   2060      1.1  christos 
   2061      1.1  christos   if (dst_type != CTF_ERR)
   2062      1.1  christos     ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
   2063      1.1  christos   return dst_type;
   2064      1.1  christos }
   2065      1.1  christos 
   2066      1.1  christos ctf_id_t
   2067  1.1.1.2  christos ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
   2068      1.1  christos {
   2069      1.1  christos   ctf_id_t id;
   2070      1.1  christos 
   2071      1.1  christos   if (!src_fp->ctf_add_processing)
   2072      1.1  christos     src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
   2073      1.1  christos 						     ctf_hash_eq_integer,
   2074      1.1  christos 						     NULL, NULL);
   2075      1.1  christos 
   2076      1.1  christos   /* We store the hash on the source, because it contains only source type IDs:
   2077      1.1  christos      but callers will invariably expect errors to appear on the dest.  */
   2078      1.1  christos   if (!src_fp->ctf_add_processing)
   2079  1.1.1.3  christos     return (ctf_set_typed_errno (dst_fp, ENOMEM));
   2080      1.1  christos 
   2081      1.1  christos   id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
   2082      1.1  christos   ctf_dynhash_empty (src_fp->ctf_add_processing);
   2083      1.1  christos 
   2084      1.1  christos   return id;
   2085      1.1  christos }
   2086