[BACK]Return to ctf-create.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / libctf

Annotation of src/external/gpl3/binutils.old/dist/libctf/ctf-create.c, Revision 1.1

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

CVSweb <webmaster@jp.NetBSD.org>