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