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