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