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