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