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