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