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