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