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