libctf: add hash traversal helpers
[deliverable/binutils-gdb.git] / libctf / ctf-create.c
1 /* CTF file creation.
2 Copyright (C) 2019 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <ctf-impl.h>
21 #include <sys/param.h>
22 #include <assert.h>
23 #include <string.h>
24 #include <zlib.h>
25
26 #ifndef roundup
27 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
28 #endif
29
30 /* To create an empty CTF container, we just declare a zeroed header and call
31 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
32 and initialize the dynamic members. We set dtvstrlen to 1 to reserve the
33 first byte of the string table for a \0 byte, and we start assigning type
34 IDs at 1 because type ID 0 is used as a sentinel and a not-found
35 indicator. */
36
37 ctf_file_t *
38 ctf_create (int *errp)
39 {
40 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
41
42 ctf_dynhash_t *dthash;
43 ctf_dynhash_t *dvhash;
44 ctf_dynhash_t *dtbyname;
45 ctf_sect_t cts;
46 ctf_file_t *fp;
47
48 libctf_init_debug();
49 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
50 NULL, NULL);
51 if (dthash == NULL)
52 {
53 ctf_set_open_errno (errp, EAGAIN);
54 goto err;
55 }
56
57 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
58 NULL, NULL);
59 if (dvhash == NULL)
60 {
61 ctf_set_open_errno (errp, EAGAIN);
62 goto err_dt;
63 }
64
65 dtbyname = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
66 free, NULL);
67 if (dtbyname == NULL)
68 {
69 ctf_set_open_errno (errp, EAGAIN);
70 goto err_dv;
71 }
72
73 cts.cts_name = _CTF_SECTION;
74 cts.cts_data = &hdr;
75 cts.cts_size = sizeof (hdr);
76 cts.cts_entsize = 1;
77
78 if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
79 goto err_dtbyname;
80
81 fp->ctf_flags |= LCTF_RDWR;
82 fp->ctf_dtbyname = dtbyname;
83 fp->ctf_dthash = dthash;
84 fp->ctf_dvhash = dvhash;
85 fp->ctf_dtvstrlen = 1;
86 fp->ctf_dtnextid = 1;
87 fp->ctf_dtoldid = 0;
88 fp->ctf_snapshots = 0;
89 fp->ctf_snapshot_lu = 0;
90
91 return fp;
92
93 err_dtbyname:
94 ctf_dynhash_destroy (dtbyname);
95 err_dv:
96 ctf_dynhash_destroy (dvhash);
97 err_dt:
98 ctf_dynhash_destroy (dthash);
99 err:
100 return NULL;
101 }
102
103 static unsigned char *
104 ctf_copy_smembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
105 {
106 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
107 ctf_member_t ctm;
108
109 for (; dmd != NULL; dmd = ctf_list_next (dmd))
110 {
111 if (dmd->dmd_name)
112 {
113 ctm.ctm_name = soff;
114 soff += strlen (dmd->dmd_name) + 1;
115 }
116 else
117 ctm.ctm_name = 0;
118
119 ctm.ctm_type = (uint32_t) dmd->dmd_type;
120 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
121
122 memcpy (t, &ctm, sizeof (ctm));
123 t += sizeof (ctm);
124 }
125
126 return t;
127 }
128
129 static unsigned char *
130 ctf_copy_lmembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
131 {
132 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
133 ctf_lmember_t ctlm;
134
135 for (; dmd != NULL; dmd = ctf_list_next (dmd))
136 {
137 if (dmd->dmd_name)
138 {
139 ctlm.ctlm_name = soff;
140 soff += strlen (dmd->dmd_name) + 1;
141 }
142 else
143 ctlm.ctlm_name = 0;
144
145 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
146 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
147 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
148
149 memcpy (t, &ctlm, sizeof (ctlm));
150 t += sizeof (ctlm);
151 }
152
153 return t;
154 }
155
156 static unsigned char *
157 ctf_copy_emembers (ctf_dtdef_t *dtd, uint32_t soff, unsigned char *t)
158 {
159 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
160 ctf_enum_t cte;
161
162 for (; dmd != NULL; dmd = ctf_list_next (dmd))
163 {
164 cte.cte_name = soff;
165 cte.cte_value = dmd->dmd_value;
166 soff += strlen (dmd->dmd_name) + 1;
167 memcpy (t, &cte, sizeof (cte));
168 t += sizeof (cte);
169 }
170
171 return t;
172 }
173
174 static unsigned char *
175 ctf_copy_membnames (ctf_dtdef_t *dtd, unsigned char *s)
176 {
177 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
178 size_t len;
179
180 for (; dmd != NULL; dmd = ctf_list_next (dmd))
181 {
182 if (dmd->dmd_name == NULL)
183 continue; /* Skip anonymous members. */
184 len = strlen (dmd->dmd_name) + 1;
185 memcpy (s, dmd->dmd_name, len);
186 s += len;
187 }
188
189 return s;
190 }
191
192 /* Sort a newly-constructed static variable array. */
193
194 static int
195 ctf_sort_var (const void *one_, const void *two_, void *strtab_)
196 {
197 const ctf_varent_t *one = one_;
198 const ctf_varent_t *two = two_;
199 const char *strtab = strtab_;
200 const char *n1 = strtab + CTF_NAME_OFFSET (one->ctv_name);
201 const char *n2 = strtab + CTF_NAME_OFFSET (two->ctv_name);
202
203 return (strcmp (n1, n2));
204 }
205
206 /* If the specified CTF container is writable and has been modified, reload this
207 container with the updated type definitions. In order to make this code and
208 the rest of libctf as simple as possible, we perform updates by taking the
209 dynamic type definitions and creating an in-memory CTF file containing the
210 definitions, and then call ctf_simple_open() on it. This not only leverages
211 ctf_simple_open(), but also avoids having to bifurcate the rest of the library
212 code with different lookup paths for static and dynamic type definitions. We
213 are therefore optimizing greatly for lookup over update, which we assume will
214 be an uncommon operation. We perform one extra trick here for the benefit of
215 callers and to keep our code simple: ctf_simple_open() will return a new
216 ctf_file_t, but we want to keep the fp constant for the caller, so after
217 ctf_simple_open() returns, we use memcpy to swap the interior of the old and
218 new ctf_file_t's, and then free the old. */
219 int
220 ctf_update (ctf_file_t *fp)
221 {
222 ctf_file_t ofp, *nfp;
223 ctf_header_t hdr;
224 ctf_dtdef_t *dtd;
225 ctf_dvdef_t *dvd;
226 ctf_varent_t *dvarents;
227
228 unsigned char *s, *s0, *t;
229 unsigned long i;
230 size_t buf_size, type_size, nvars;
231 void *buf;
232 int err;
233
234 if (!(fp->ctf_flags & LCTF_RDWR))
235 return (ctf_set_errno (fp, ECTF_RDONLY));
236
237 /* Update required? */
238 if (!(fp->ctf_flags & LCTF_DIRTY))
239 return 0;
240
241 /* Fill in an initial CTF header. We will leave the label, object,
242 and function sections empty and only output a header, type section,
243 and string table. The type section begins at a 4-byte aligned
244 boundary past the CTF header itself (at relative offset zero). */
245
246 memset (&hdr, 0, sizeof (hdr));
247 hdr.cth_magic = CTF_MAGIC;
248 hdr.cth_version = CTF_VERSION;
249
250 if (fp->ctf_flags & LCTF_CHILD)
251 hdr.cth_parname = 1; /* parname added just below. */
252
253 /* Iterate through the dynamic type definition list and compute the
254 size of the CTF type section we will need to generate. */
255
256 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
257 dtd != NULL; dtd = ctf_list_next (dtd))
258 {
259 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
260 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
261
262 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
263 type_size += sizeof (ctf_stype_t);
264 else
265 type_size += sizeof (ctf_type_t);
266
267 switch (kind)
268 {
269 case CTF_K_INTEGER:
270 case CTF_K_FLOAT:
271 type_size += sizeof (uint32_t);
272 break;
273 case CTF_K_ARRAY:
274 type_size += sizeof (ctf_array_t);
275 break;
276 case CTF_K_SLICE:
277 type_size += sizeof (ctf_slice_t);
278 break;
279 case CTF_K_FUNCTION:
280 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
281 break;
282 case CTF_K_STRUCT:
283 case CTF_K_UNION:
284 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
285 type_size += sizeof (ctf_member_t) * vlen;
286 else
287 type_size += sizeof (ctf_lmember_t) * vlen;
288 break;
289 case CTF_K_ENUM:
290 type_size += sizeof (ctf_enum_t) * vlen;
291 break;
292 }
293 }
294
295 /* Computing the number of entries in the CTF variable section is much
296 simpler. */
297
298 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
299 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
300
301 /* Fill in the string table and type offset and size, compute the size
302 of the entire CTF buffer we need, and then allocate a new buffer and
303 memcpy the finished header to the start of the buffer. */
304
305 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
306 hdr.cth_stroff = hdr.cth_typeoff + type_size;
307 hdr.cth_strlen = fp->ctf_dtvstrlen;
308 if (fp->ctf_parname != NULL)
309 hdr.cth_strlen += strlen (fp->ctf_parname) + 1;
310
311 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
312
313 if ((buf = malloc (buf_size)) == NULL)
314 return (ctf_set_errno (fp, EAGAIN));
315
316 memcpy (buf, &hdr, sizeof (ctf_header_t));
317 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff;
318 s = s0 = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff;
319
320 s[0] = '\0';
321 s++;
322
323 if (fp->ctf_parname != NULL)
324 {
325 memcpy (s, fp->ctf_parname, strlen (fp->ctf_parname) + 1);
326 s += strlen (fp->ctf_parname) + 1;
327 }
328
329 /* Work over the variable list, translating everything into
330 ctf_varent_t's and filling out the string table, then sort the buffer
331 of ctf_varent_t's. */
332
333 dvarents = (ctf_varent_t *) t;
334 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
335 dvd = ctf_list_next (dvd), i++)
336 {
337 ctf_varent_t *var = &dvarents[i];
338 size_t len = strlen (dvd->dvd_name) + 1;
339
340 var->ctv_name = (uint32_t) (s - s0);
341 var->ctv_type = dvd->dvd_type;
342 memcpy (s, dvd->dvd_name, len);
343 s += len;
344 }
345 assert (i == nvars);
346
347 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
348 t += sizeof (ctf_varent_t) * nvars;
349
350 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
351
352 /* We now take a final lap through the dynamic type definition list and
353 copy the appropriate type records and strings to the output buffer. */
354
355 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
356 dtd != NULL; dtd = ctf_list_next (dtd))
357 {
358
359 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
360 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
361
362 ctf_array_t cta;
363 uint32_t encoding;
364 size_t len;
365
366 if (dtd->dtd_name != NULL)
367 {
368 dtd->dtd_data.ctt_name = (uint32_t) (s - s0);
369 len = strlen (dtd->dtd_name) + 1;
370 memcpy (s, dtd->dtd_name, len);
371 s += len;
372 }
373 else
374 dtd->dtd_data.ctt_name = 0;
375
376 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
377 len = sizeof (ctf_stype_t);
378 else
379 len = sizeof (ctf_type_t);
380
381 memcpy (t, &dtd->dtd_data, len);
382 t += len;
383
384 switch (kind)
385 {
386 case CTF_K_INTEGER:
387 case CTF_K_FLOAT:
388 if (kind == CTF_K_INTEGER)
389 {
390 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
391 dtd->dtd_u.dtu_enc.cte_offset,
392 dtd->dtd_u.dtu_enc.cte_bits);
393 }
394 else
395 {
396 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
397 dtd->dtd_u.dtu_enc.cte_offset,
398 dtd->dtd_u.dtu_enc.cte_bits);
399 }
400 memcpy (t, &encoding, sizeof (encoding));
401 t += sizeof (encoding);
402 break;
403
404 case CTF_K_SLICE:
405 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
406 t += sizeof (struct ctf_slice);
407 break;
408
409 case CTF_K_ARRAY:
410 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
411 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
412 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
413 memcpy (t, &cta, sizeof (cta));
414 t += sizeof (cta);
415 break;
416
417 case CTF_K_FUNCTION:
418 {
419 uint32_t *argv = (uint32_t *) (uintptr_t) t;
420 uint32_t argc;
421
422 for (argc = 0; argc < vlen; argc++)
423 *argv++ = (uint32_t) dtd->dtd_u.dtu_argv[argc];
424
425 if (vlen & 1)
426 *argv++ = 0; /* Pad to 4-byte boundary. */
427
428 t = (unsigned char *) argv;
429 break;
430 }
431
432 case CTF_K_STRUCT:
433 case CTF_K_UNION:
434 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
435 t = ctf_copy_smembers (dtd, (uint32_t) (s - s0), t);
436 else
437 t = ctf_copy_lmembers (dtd, (uint32_t) (s - s0), t);
438 s = ctf_copy_membnames (dtd, s);
439 break;
440
441 case CTF_K_ENUM:
442 t = ctf_copy_emembers (dtd, (uint32_t) (s - s0), t);
443 s = ctf_copy_membnames (dtd, s);
444 break;
445 }
446 }
447 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
448
449 /* Finally, we are ready to ctf_simple_open() the new container. If this
450 is successful, we then switch nfp and fp and free the old container. */
451
452 if ((nfp = ctf_simple_open (buf, buf_size, NULL, 0, 0, NULL, 0, &err)) == NULL)
453 {
454 ctf_free (buf);
455 return (ctf_set_errno (fp, err));
456 }
457
458 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
459 (void) ctf_import (nfp, fp->ctf_parent);
460
461 nfp->ctf_refcnt = fp->ctf_refcnt;
462 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
463 nfp->ctf_data.cts_data = NULL; /* Force ctf_free() on close. */
464 nfp->ctf_dthash = fp->ctf_dthash;
465 nfp->ctf_dtdefs = fp->ctf_dtdefs;
466 nfp->ctf_dtbyname = fp->ctf_dtbyname;
467 nfp->ctf_dvhash = fp->ctf_dvhash;
468 nfp->ctf_dvdefs = fp->ctf_dvdefs;
469 nfp->ctf_dtvstrlen = fp->ctf_dtvstrlen;
470 nfp->ctf_dtnextid = fp->ctf_dtnextid;
471 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
472 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
473 nfp->ctf_specific = fp->ctf_specific;
474
475 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
476
477 fp->ctf_dtbyname = NULL;
478 fp->ctf_dthash = NULL;
479 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
480
481 fp->ctf_dvhash = NULL;
482 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
483
484 memcpy (&ofp, fp, sizeof (ctf_file_t));
485 memcpy (fp, nfp, sizeof (ctf_file_t));
486 memcpy (nfp, &ofp, sizeof (ctf_file_t));
487
488 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
489 array of type name prefixes and the corresponding ctf_dynhash to use.
490 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
491
492 fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
493 fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
494 fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
495 fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
496
497 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
498 ctf_file_close (nfp);
499
500 return 0;
501 }
502
503 static char *
504 ctf_prefixed_name (int kind, const char *name)
505 {
506 char *prefixed;
507
508 switch (kind)
509 {
510 case CTF_K_STRUCT:
511 prefixed = ctf_strdup ("struct ");
512 break;
513 case CTF_K_UNION:
514 prefixed = ctf_strdup ("union ");
515 break;
516 case CTF_K_ENUM:
517 prefixed = ctf_strdup ("enum ");
518 break;
519 default:
520 prefixed = ctf_strdup ("");
521 }
522
523 prefixed = ctf_str_append (prefixed, name);
524 return prefixed;
525 }
526
527 int
528 ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
529 {
530 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0)
531 return -1;
532
533 if (dtd->dtd_name)
534 {
535 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
536 if (ctf_dynhash_insert (fp->ctf_dtbyname,
537 ctf_prefixed_name (kind, dtd->dtd_name),
538 dtd) < 0)
539 return -1;
540 }
541 ctf_list_append (&fp->ctf_dtdefs, dtd);
542 return 0;
543 }
544
545 void
546 ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
547 {
548 ctf_dmdef_t *dmd, *nmd;
549 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
550
551 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
552
553 switch (kind)
554 {
555 case CTF_K_STRUCT:
556 case CTF_K_UNION:
557 case CTF_K_ENUM:
558 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
559 dmd != NULL; dmd = nmd)
560 {
561 if (dmd->dmd_name != NULL)
562 {
563 fp->ctf_dtvstrlen -= strlen (dmd->dmd_name) + 1;
564 ctf_free (dmd->dmd_name);
565 }
566 nmd = ctf_list_next (dmd);
567 ctf_free (dmd);
568 }
569 break;
570 case CTF_K_FUNCTION:
571 ctf_free (dtd->dtd_u.dtu_argv);
572 break;
573 }
574
575 if (dtd->dtd_name)
576 {
577 char *name;
578
579 name = ctf_prefixed_name (kind, dtd->dtd_name);
580 ctf_dynhash_remove (fp->ctf_dtbyname, name);
581 free (name);
582
583 fp->ctf_dtvstrlen -= strlen (dtd->dtd_name) + 1;
584 ctf_free (dtd->dtd_name);
585 }
586
587 ctf_list_delete (&fp->ctf_dtdefs, dtd);
588 ctf_free (dtd);
589 }
590
591 ctf_dtdef_t *
592 ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
593 {
594 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
595 }
596
597 static ctf_id_t
598 ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
599 {
600 ctf_dtdef_t *dtd;
601 char *decorated = ctf_prefixed_name (kind, name);
602
603 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
604 free (decorated);
605
606 if (dtd)
607 return dtd->dtd_type;
608
609 return 0;
610 }
611
612 ctf_dtdef_t *
613 ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
614 {
615 ctf_id_t idx;
616
617 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
618 fp = fp->ctf_parent;
619
620 idx = LCTF_TYPE_TO_INDEX(fp, id);
621
622 if (((unsigned long) idx > fp->ctf_typemax) &&
623 ((unsigned long) idx < fp->ctf_dtnextid))
624 return ctf_dtd_lookup (fp, id);
625 return NULL;
626 }
627
628 int
629 ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
630 {
631 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
632 return -1;
633 ctf_list_append (&fp->ctf_dvdefs, dvd);
634 return 0;
635 }
636
637 void
638 ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
639 {
640 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
641
642 fp->ctf_dtvstrlen -= strlen (dvd->dvd_name) + 1;
643 ctf_free (dvd->dvd_name);
644
645 ctf_list_delete (&fp->ctf_dvdefs, dvd);
646 ctf_free (dvd);
647 }
648
649 ctf_dvdef_t *
650 ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
651 {
652 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
653 }
654
655 /* Discard all of the dynamic type definitions and variable definitions that
656 have been added to the container since the last call to ctf_update(). We
657 locate such types by scanning the dtd list and deleting elements that have
658 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
659 by scanning the variable list and deleting elements that have update IDs
660 equal to the current value of the last-update snapshot count (indicating that
661 they were added after the most recent call to ctf_update()). */
662 int
663 ctf_discard (ctf_file_t *fp)
664 {
665 ctf_snapshot_id_t last_update =
666 { fp->ctf_dtoldid,
667 fp->ctf_snapshot_lu + 1 };
668
669 /* Update required? */
670 if (!(fp->ctf_flags & LCTF_DIRTY))
671 return 0;
672
673 return (ctf_rollback (fp, last_update));
674 }
675
676 ctf_snapshot_id_t
677 ctf_snapshot (ctf_file_t *fp)
678 {
679 ctf_snapshot_id_t snapid;
680 snapid.dtd_id = fp->ctf_dtnextid - 1;
681 snapid.snapshot_id = fp->ctf_snapshots++;
682 return snapid;
683 }
684
685 /* Like ctf_discard(), only discards everything after a particular ID. */
686 int
687 ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
688 {
689 ctf_dtdef_t *dtd, *ntd;
690 ctf_dvdef_t *dvd, *nvd;
691
692 if (!(fp->ctf_flags & LCTF_RDWR))
693 return (ctf_set_errno (fp, ECTF_RDONLY));
694
695 if (fp->ctf_dtoldid > id.dtd_id)
696 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
697
698 if (fp->ctf_snapshot_lu >= id.snapshot_id)
699 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
700
701 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
702 {
703 ntd = ctf_list_next (dtd);
704
705 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
706 continue;
707
708 ctf_dtd_delete (fp, dtd);
709 }
710
711 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
712 {
713 nvd = ctf_list_next (dvd);
714
715 if (dvd->dvd_snapshots <= id.snapshot_id)
716 continue;
717
718 ctf_dvd_delete (fp, dvd);
719 }
720
721 fp->ctf_dtnextid = id.dtd_id + 1;
722 fp->ctf_snapshots = id.snapshot_id;
723
724 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
725 fp->ctf_flags &= ~LCTF_DIRTY;
726
727 return 0;
728 }
729
730 static ctf_id_t
731 ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
732 ctf_dtdef_t **rp)
733 {
734 ctf_dtdef_t *dtd;
735 ctf_id_t type;
736 char *s = NULL;
737
738 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
739 return (ctf_set_errno (fp, EINVAL));
740
741 if (!(fp->ctf_flags & LCTF_RDWR))
742 return (ctf_set_errno (fp, ECTF_RDONLY));
743
744 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
745 return (ctf_set_errno (fp, ECTF_FULL));
746
747 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
748 return (ctf_set_errno (fp, ECTF_FULL));
749
750 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
751 return (ctf_set_errno (fp, EAGAIN));
752
753 if (name != NULL && (s = ctf_strdup (name)) == NULL)
754 {
755 ctf_free (dtd);
756 return (ctf_set_errno (fp, EAGAIN));
757 }
758
759 type = fp->ctf_dtnextid++;
760 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
761
762 memset (dtd, 0, sizeof (ctf_dtdef_t));
763 dtd->dtd_name = s;
764 dtd->dtd_type = type;
765
766 if (s != NULL)
767 fp->ctf_dtvstrlen += strlen (s) + 1;
768
769 if (ctf_dtd_insert (fp, dtd) < 0)
770 {
771 ctf_free (dtd);
772 return CTF_ERR; /* errno is set for us. */
773 }
774 fp->ctf_flags |= LCTF_DIRTY;
775
776 *rp = dtd;
777 return type;
778 }
779
780 /* When encoding integer sizes, we want to convert a byte count in the range
781 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
782 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
783 static size_t
784 clp2 (size_t x)
785 {
786 x--;
787
788 x |= (x >> 1);
789 x |= (x >> 2);
790 x |= (x >> 4);
791 x |= (x >> 8);
792 x |= (x >> 16);
793
794 return (x + 1);
795 }
796
797 static ctf_id_t
798 ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
799 const char *name, const ctf_encoding_t *ep, uint32_t kind)
800 {
801 ctf_dtdef_t *dtd;
802 ctf_id_t type;
803
804 if (ep == NULL)
805 return (ctf_set_errno (fp, EINVAL));
806
807 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
808 return CTF_ERR; /* errno is set for us. */
809
810 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
811 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
812 / CHAR_BIT);
813 dtd->dtd_u.dtu_enc = *ep;
814
815 return type;
816 }
817
818 static ctf_id_t
819 ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
820 {
821 ctf_dtdef_t *dtd;
822 ctf_id_t type;
823 ctf_file_t *tmp = fp;
824
825 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
826 return (ctf_set_errno (fp, EINVAL));
827
828 if (ctf_lookup_by_id (&tmp, ref) == NULL)
829 return CTF_ERR; /* errno is set for us. */
830
831 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
832 return CTF_ERR; /* errno is set for us. */
833
834 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
835 dtd->dtd_data.ctt_type = (uint32_t) ref;
836
837 return type;
838 }
839
840 ctf_id_t
841 ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
842 const ctf_encoding_t *ep)
843 {
844 ctf_dtdef_t *dtd;
845 ctf_id_t type;
846 int kind;
847 const ctf_type_t *tp;
848 ctf_file_t *tmp = fp;
849
850 if (ep == NULL)
851 return (ctf_set_errno (fp, EINVAL));
852
853 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
854 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
855
856 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
857 return (ctf_set_errno (fp, EINVAL));
858
859 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
860 return CTF_ERR; /* errno is set for us. */
861
862 kind = ctf_type_kind_unsliced (tmp, ref);
863 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
864 (kind != CTF_K_ENUM))
865 return (ctf_set_errno (fp, ECTF_NOTINTFP));
866
867 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
868 return CTF_ERR; /* errno is set for us. */
869
870 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
871 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
872 / CHAR_BIT);
873 dtd->dtd_u.dtu_slice.cts_type = ref;
874 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
875 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
876
877 return type;
878 }
879
880 ctf_id_t
881 ctf_add_integer (ctf_file_t *fp, uint32_t flag,
882 const char *name, const ctf_encoding_t *ep)
883 {
884 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
885 }
886
887 ctf_id_t
888 ctf_add_float (ctf_file_t *fp, uint32_t flag,
889 const char *name, const ctf_encoding_t *ep)
890 {
891 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
892 }
893
894 ctf_id_t
895 ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
896 {
897 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
898 }
899
900 ctf_id_t
901 ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
902 {
903 ctf_dtdef_t *dtd;
904 ctf_id_t type;
905 ctf_file_t *tmp = fp;
906
907 if (arp == NULL)
908 return (ctf_set_errno (fp, EINVAL));
909
910 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
911 return CTF_ERR; /* errno is set for us. */
912
913 tmp = fp;
914 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
915 return CTF_ERR; /* errno is set for us. */
916
917 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
918 return CTF_ERR; /* errno is set for us. */
919
920 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
921 dtd->dtd_data.ctt_size = 0;
922 dtd->dtd_u.dtu_arr = *arp;
923
924 return type;
925 }
926
927 int
928 ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
929 {
930 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
931
932 if (!(fp->ctf_flags & LCTF_RDWR))
933 return (ctf_set_errno (fp, ECTF_RDONLY));
934
935 if (dtd == NULL
936 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
937 return (ctf_set_errno (fp, ECTF_BADID));
938
939 fp->ctf_flags |= LCTF_DIRTY;
940 dtd->dtd_u.dtu_arr = *arp;
941
942 return 0;
943 }
944
945 ctf_id_t
946 ctf_add_function (ctf_file_t *fp, uint32_t flag,
947 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
948 {
949 ctf_dtdef_t *dtd;
950 ctf_id_t type;
951 uint32_t vlen;
952 ctf_id_t *vdat = NULL;
953 ctf_file_t *tmp = fp;
954 size_t i;
955
956 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
957 || (ctc->ctc_argc != 0 && argv == NULL))
958 return (ctf_set_errno (fp, EINVAL));
959
960 vlen = ctc->ctc_argc;
961 if (ctc->ctc_flags & CTF_FUNC_VARARG)
962 vlen++; /* Add trailing zero to indicate varargs (see below). */
963
964 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
965 return CTF_ERR; /* errno is set for us. */
966
967 for (i = 0; i < ctc->ctc_argc; i++)
968 {
969 tmp = fp;
970 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
971 return CTF_ERR; /* errno is set for us. */
972 }
973
974 if (vlen > CTF_MAX_VLEN)
975 return (ctf_set_errno (fp, EOVERFLOW));
976
977 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
978 return (ctf_set_errno (fp, EAGAIN));
979
980 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
981 {
982 ctf_free (vdat);
983 return CTF_ERR; /* errno is set for us. */
984 }
985
986 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
987 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
988
989 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
990 if (ctc->ctc_flags & CTF_FUNC_VARARG)
991 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
992 dtd->dtd_u.dtu_argv = vdat;
993
994 return type;
995 }
996
997 ctf_id_t
998 ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
999 size_t size)
1000 {
1001 ctf_hash_t *hp = fp->ctf_structs;
1002 ctf_dtdef_t *dtd;
1003 ctf_id_t type = 0;
1004
1005 /* Promote forwards to structs. */
1006
1007 if (name != NULL)
1008 {
1009 type = ctf_hash_lookup_type (hp, fp, name);
1010 if (type == 0)
1011 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
1012 }
1013
1014 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1015 dtd = ctf_dtd_lookup (fp, type);
1016 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1017 return CTF_ERR; /* errno is set for us. */
1018
1019 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1020
1021 if (size > CTF_MAX_SIZE)
1022 {
1023 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1024 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1025 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1026 }
1027 else
1028 dtd->dtd_data.ctt_size = (uint32_t) size;
1029
1030 return type;
1031 }
1032
1033 ctf_id_t
1034 ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1035 {
1036 return (ctf_add_struct_sized (fp, flag, name, 0));
1037 }
1038
1039 ctf_id_t
1040 ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1041 size_t size)
1042 {
1043 ctf_hash_t *hp = fp->ctf_unions;
1044 ctf_dtdef_t *dtd;
1045 ctf_id_t type = 0;
1046
1047 /* Promote forwards to unions. */
1048 if (name != NULL)
1049 {
1050 type = ctf_hash_lookup_type (hp, fp, name);
1051 if (type == 0)
1052 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1053 }
1054
1055 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1056 dtd = ctf_dtd_lookup (fp, type);
1057 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1058 return CTF_ERR; /* errno is set for us */
1059
1060 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1061
1062 if (size > CTF_MAX_SIZE)
1063 {
1064 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1065 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1066 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1067 }
1068 else
1069 dtd->dtd_data.ctt_size = (uint32_t) size;
1070
1071 return type;
1072 }
1073
1074 ctf_id_t
1075 ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1076 {
1077 return (ctf_add_union_sized (fp, flag, name, 0));
1078 }
1079
1080 ctf_id_t
1081 ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1082 {
1083 ctf_hash_t *hp = fp->ctf_enums;
1084 ctf_dtdef_t *dtd;
1085 ctf_id_t type = 0;
1086
1087 /* Promote forwards to enums. */
1088 if (name != NULL)
1089 {
1090 type = ctf_hash_lookup_type (hp, fp, name);
1091 if (type == 0)
1092 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1093 }
1094
1095 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1096 dtd = ctf_dtd_lookup (fp, type);
1097 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1098 return CTF_ERR; /* errno is set for us. */
1099
1100 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1101 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1102
1103 return type;
1104 }
1105
1106 ctf_id_t
1107 ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1108 const ctf_encoding_t *ep)
1109 {
1110 ctf_hash_t *hp = fp->ctf_enums;
1111 ctf_id_t type = 0;
1112
1113 /* First, create the enum if need be, using most of the same machinery as
1114 ctf_add_enum(), to ensure that we do not allow things past that are not
1115 enums or forwards to them. (This includes other slices: you cannot slice a
1116 slice, which would be a useless thing to do anyway.) */
1117
1118 if (name != NULL)
1119 {
1120 type = ctf_hash_lookup_type (hp, fp, name);
1121 if (type == 0)
1122 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1123 }
1124
1125 if (type != 0)
1126 {
1127 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1128 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1129 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1130 }
1131 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1132 return CTF_ERR; /* errno is set for us. */
1133
1134 /* Now attach a suitable slice to it. */
1135
1136 return ctf_add_slice (fp, flag, type, ep);
1137 }
1138
1139 ctf_id_t
1140 ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1141 uint32_t kind)
1142 {
1143 ctf_hash_t *hp;
1144 ctf_dtdef_t *dtd;
1145 ctf_id_t type = 0;
1146
1147 switch (kind)
1148 {
1149 case CTF_K_STRUCT:
1150 hp = fp->ctf_structs;
1151 break;
1152 case CTF_K_UNION:
1153 hp = fp->ctf_unions;
1154 break;
1155 case CTF_K_ENUM:
1156 hp = fp->ctf_enums;
1157 break;
1158 default:
1159 return (ctf_set_errno (fp, ECTF_NOTSUE));
1160 }
1161
1162 /* If the type is already defined or exists as a forward tag, just
1163 return the ctf_id_t of the existing definition. */
1164
1165 if (name != NULL)
1166 {
1167 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1168 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1169 return type;
1170 }
1171
1172 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1173 return CTF_ERR; /* errno is set for us. */
1174
1175 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1176 dtd->dtd_data.ctt_type = kind;
1177
1178 return type;
1179 }
1180
1181 ctf_id_t
1182 ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1183 ctf_id_t ref)
1184 {
1185 ctf_dtdef_t *dtd;
1186 ctf_id_t type;
1187 ctf_file_t *tmp = fp;
1188
1189 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1190 return (ctf_set_errno (fp, EINVAL));
1191
1192 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1193 return CTF_ERR; /* errno is set for us. */
1194
1195 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1196 return CTF_ERR; /* errno is set for us. */
1197
1198 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1199 dtd->dtd_data.ctt_type = (uint32_t) ref;
1200
1201 return type;
1202 }
1203
1204 ctf_id_t
1205 ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1206 {
1207 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1208 }
1209
1210 ctf_id_t
1211 ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1212 {
1213 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1214 }
1215
1216 ctf_id_t
1217 ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1218 {
1219 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1220 }
1221
1222 int
1223 ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1224 int value)
1225 {
1226 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1227 ctf_dmdef_t *dmd;
1228
1229 uint32_t kind, vlen, root;
1230 char *s;
1231
1232 if (name == NULL)
1233 return (ctf_set_errno (fp, EINVAL));
1234
1235 if (!(fp->ctf_flags & LCTF_RDWR))
1236 return (ctf_set_errno (fp, ECTF_RDONLY));
1237
1238 if (dtd == NULL)
1239 return (ctf_set_errno (fp, ECTF_BADID));
1240
1241 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1242 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1243 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1244
1245 if (kind != CTF_K_ENUM)
1246 return (ctf_set_errno (fp, ECTF_NOTENUM));
1247
1248 if (vlen == CTF_MAX_VLEN)
1249 return (ctf_set_errno (fp, ECTF_DTFULL));
1250
1251 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1252 dmd != NULL; dmd = ctf_list_next (dmd))
1253 {
1254 if (strcmp (dmd->dmd_name, name) == 0)
1255 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1256 }
1257
1258 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1259 return (ctf_set_errno (fp, EAGAIN));
1260
1261 if ((s = ctf_strdup (name)) == NULL)
1262 {
1263 ctf_free (dmd);
1264 return (ctf_set_errno (fp, EAGAIN));
1265 }
1266
1267 dmd->dmd_name = s;
1268 dmd->dmd_type = CTF_ERR;
1269 dmd->dmd_offset = 0;
1270 dmd->dmd_value = value;
1271
1272 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1273 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1274
1275 fp->ctf_dtvstrlen += strlen (s) + 1;
1276 fp->ctf_flags |= LCTF_DIRTY;
1277
1278 return 0;
1279 }
1280
1281 int
1282 ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1283 ctf_id_t type, unsigned long bit_offset)
1284 {
1285 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1286 ctf_dmdef_t *dmd;
1287
1288 ssize_t msize, malign, ssize;
1289 uint32_t kind, vlen, root;
1290 char *s = NULL;
1291
1292 if (!(fp->ctf_flags & LCTF_RDWR))
1293 return (ctf_set_errno (fp, ECTF_RDONLY));
1294
1295 if (dtd == NULL)
1296 return (ctf_set_errno (fp, ECTF_BADID));
1297
1298 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1299 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1300 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1301
1302 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1303 return (ctf_set_errno (fp, ECTF_NOTSOU));
1304
1305 if (vlen == CTF_MAX_VLEN)
1306 return (ctf_set_errno (fp, ECTF_DTFULL));
1307
1308 if (name != NULL)
1309 {
1310 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1311 dmd != NULL; dmd = ctf_list_next (dmd))
1312 {
1313 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1314 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1315 }
1316 }
1317
1318 if ((msize = ctf_type_size (fp, type)) < 0 ||
1319 (malign = ctf_type_align (fp, type)) < 0)
1320 return -1; /* errno is set for us. */
1321
1322 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1323 return (ctf_set_errno (fp, EAGAIN));
1324
1325 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1326 {
1327 ctf_free (dmd);
1328 return (ctf_set_errno (fp, EAGAIN));
1329 }
1330
1331 dmd->dmd_name = s;
1332 dmd->dmd_type = type;
1333 dmd->dmd_value = -1;
1334
1335 if (kind == CTF_K_STRUCT && vlen != 0)
1336 {
1337 if (bit_offset == (unsigned long) - 1)
1338 {
1339 /* Natural alignment. */
1340
1341 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1342 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1343 size_t off = lmd->dmd_offset;
1344
1345 ctf_encoding_t linfo;
1346 ssize_t lsize;
1347
1348 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1349 off += linfo.cte_bits;
1350 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1351 off += lsize * CHAR_BIT;
1352
1353 /* Round up the offset of the end of the last member to
1354 the next byte boundary, convert 'off' to bytes, and
1355 then round it up again to the next multiple of the
1356 alignment required by the new member. Finally,
1357 convert back to bits and store the result in
1358 dmd_offset. Technically we could do more efficient
1359 packing if the new member is a bit-field, but we're
1360 the "compiler" and ANSI says we can do as we choose. */
1361
1362 off = roundup (off, CHAR_BIT) / CHAR_BIT;
1363 off = roundup (off, MAX (malign, 1));
1364 dmd->dmd_offset = off * CHAR_BIT;
1365 ssize = off + msize;
1366 }
1367 else
1368 {
1369 /* Specified offset in bits. */
1370
1371 dmd->dmd_offset = bit_offset;
1372 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1373 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1374 }
1375 }
1376 else
1377 {
1378 dmd->dmd_offset = 0;
1379 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1380 ssize = MAX (ssize, msize);
1381 }
1382
1383 if ((size_t) ssize > CTF_MAX_SIZE)
1384 {
1385 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1386 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1387 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1388 }
1389 else
1390 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1391
1392 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1393 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1394
1395 if (s != NULL)
1396 fp->ctf_dtvstrlen += strlen (s) + 1;
1397
1398 fp->ctf_flags |= LCTF_DIRTY;
1399 return 0;
1400 }
1401
1402 int
1403 ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1404 ctf_id_t type, unsigned long bit_offset,
1405 const ctf_encoding_t encoding)
1406 {
1407 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1408 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1409 int otype = type;
1410
1411 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1412 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1413
1414 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1415 return -1; /* errno is set for us. */
1416
1417 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1418 }
1419
1420 int
1421 ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1422 ctf_id_t type)
1423 {
1424 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1425 }
1426
1427 int
1428 ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1429 {
1430 ctf_dvdef_t *dvd;
1431 ctf_file_t *tmp = fp;
1432
1433 if (!(fp->ctf_flags & LCTF_RDWR))
1434 return (ctf_set_errno (fp, ECTF_RDONLY));
1435
1436 if (ctf_dvd_lookup (fp, name) != NULL)
1437 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1438
1439 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1440 return -1; /* errno is set for us. */
1441
1442 if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL)
1443 return (ctf_set_errno (fp, EAGAIN));
1444
1445 if (name != NULL && (dvd->dvd_name = ctf_strdup (name)) == NULL)
1446 {
1447 ctf_free (dvd);
1448 return (ctf_set_errno (fp, EAGAIN));
1449 }
1450 dvd->dvd_type = ref;
1451 dvd->dvd_snapshots = fp->ctf_snapshots;
1452
1453 if (ctf_dvd_insert (fp, dvd) < 0)
1454 {
1455 ctf_free (dvd);
1456 return -1; /* errno is set for us. */
1457 }
1458
1459 fp->ctf_dtvstrlen += strlen (name) + 1;
1460 fp->ctf_flags |= LCTF_DIRTY;
1461 return 0;
1462 }
1463
1464 static int
1465 enumcmp (const char *name, int value, void *arg)
1466 {
1467 ctf_bundle_t *ctb = arg;
1468 int bvalue;
1469
1470 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
1471 {
1472 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1473 return 1;
1474 }
1475 if (value != bvalue)
1476 {
1477 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1478 value, bvalue);
1479 return 1;
1480 }
1481 return 0;
1482 }
1483
1484 static int
1485 enumadd (const char *name, int value, void *arg)
1486 {
1487 ctf_bundle_t *ctb = arg;
1488
1489 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
1490 name, value) < 0);
1491 }
1492
1493 static int
1494 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1495 void *arg)
1496 {
1497 ctf_bundle_t *ctb = arg;
1498 ctf_membinfo_t ctm;
1499
1500 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
1501 {
1502 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1503 return 1;
1504 }
1505 if (ctm.ctm_offset != offset)
1506 {
1507 ctf_dprintf ("Conflict due to member %s offset change: "
1508 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1509 return 1;
1510 }
1511 return 0;
1512 }
1513
1514 static int
1515 membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1516 {
1517 ctf_bundle_t *ctb = arg;
1518 ctf_dmdef_t *dmd;
1519 char *s = NULL;
1520
1521 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1522 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1523
1524 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1525 {
1526 ctf_free (dmd);
1527 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1528 }
1529
1530 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1531 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1532 dmd->dmd_name = s;
1533 dmd->dmd_type = type;
1534 dmd->dmd_offset = offset;
1535 dmd->dmd_value = -1;
1536
1537 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1538
1539 if (s != NULL)
1540 ctb->ctb_file->ctf_dtvstrlen += strlen (s) + 1;
1541
1542 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1543 return 0;
1544 }
1545
1546 /* The ctf_add_type routine is used to copy a type from a source CTF container
1547 to a dynamic destination container. This routine operates recursively by
1548 following the source type's links and embedded member types. If the
1549 destination container already contains a named type which has the same
1550 attributes, then we succeed and return this type but no changes occur. */
1551 ctf_id_t
1552 ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1553 {
1554 ctf_id_t dst_type = CTF_ERR;
1555 uint32_t dst_kind = CTF_K_UNKNOWN;
1556 ctf_id_t tmp;
1557
1558 const char *name;
1559 uint32_t kind, flag, vlen;
1560
1561 const ctf_type_t *src_tp, *dst_tp;
1562 ctf_bundle_t src, dst;
1563 ctf_encoding_t src_en, dst_en;
1564 ctf_arinfo_t src_ar, dst_ar;
1565
1566 ctf_dtdef_t *dtd;
1567 ctf_funcinfo_t ctc;
1568
1569 ctf_hash_t *hp;
1570
1571 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1572 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1573
1574 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1575 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1576
1577 name = ctf_strptr (src_fp, src_tp->ctt_name);
1578 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1579 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1580 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1581
1582 switch (kind)
1583 {
1584 case CTF_K_STRUCT:
1585 hp = dst_fp->ctf_structs;
1586 break;
1587 case CTF_K_UNION:
1588 hp = dst_fp->ctf_unions;
1589 break;
1590 case CTF_K_ENUM:
1591 hp = dst_fp->ctf_enums;
1592 break;
1593 default:
1594 hp = dst_fp->ctf_names;
1595 break;
1596 }
1597
1598 /* If the source type has a name and is a root type (visible at the
1599 top-level scope), lookup the name in the destination container and
1600 verify that it is of the same kind before we do anything else. */
1601
1602 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1603 && (tmp = ctf_hash_lookup_type (hp, dst_fp, name)) != 0)
1604 {
1605 dst_type = tmp;
1606 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1607 }
1608
1609 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1610 unless dst_type is a forward declaration and src_type is a struct,
1611 union, or enum (i.e. the definition of the previous forward decl). */
1612
1613 if (dst_type != CTF_ERR && dst_kind != kind
1614 && (dst_kind != CTF_K_FORWARD
1615 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1616 && kind != CTF_K_UNION)))
1617 {
1618 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1619 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1620 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1621 }
1622
1623 /* We take special action for an integer, float, or slice since it is
1624 described not only by its name but also its encoding. For integers,
1625 bit-fields exploit this degeneracy. */
1626
1627 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1628 {
1629 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1630 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1631
1632 if (dst_type != CTF_ERR)
1633 {
1634 ctf_file_t *fp = dst_fp;
1635
1636 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1637 return CTF_ERR;
1638
1639 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1640 {
1641 /* The type that we found in the hash is also root-visible. If
1642 the two types match then use the existing one; otherwise,
1643 declare a conflict. Note: slices are not certain to match
1644 even if there is no conflict: we must check the contained type
1645 too. */
1646
1647 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1648 return CTF_ERR; /* errno set for us. */
1649
1650 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1651 {
1652 if (kind != CTF_K_SLICE)
1653 return dst_type;
1654 }
1655 else
1656 {
1657 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1658 }
1659 }
1660 else
1661 {
1662 /* We found a non-root-visible type in the hash. We reset
1663 dst_type to ensure that we continue to look for a possible
1664 conflict in the pending list. */
1665
1666 dst_type = CTF_ERR;
1667 }
1668 }
1669 }
1670
1671 /* If the non-empty name was not found in the appropriate hash, search
1672 the list of pending dynamic definitions that are not yet committed.
1673 If a matching name and kind are found, assume this is the type that
1674 we are looking for. This is necessary to permit ctf_add_type() to
1675 operate recursively on entities such as a struct that contains a
1676 pointer member that refers to the same struct type. */
1677
1678 if (dst_type == CTF_ERR && name[0] != '\0')
1679 {
1680 for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1681 && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1682 dtd = ctf_list_prev (dtd))
1683 {
1684 if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1685 && dtd->dtd_name != NULL && strcmp (dtd->dtd_name, name) == 0)
1686 {
1687 int sroot; /* Is the src root-visible? */
1688 int droot; /* Is the dst root-visible? */
1689 int match; /* Do the encodings match? */
1690
1691 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1692 return dtd->dtd_type;
1693
1694 sroot = (flag & CTF_ADD_ROOT);
1695 droot = (LCTF_INFO_ISROOT (dst_fp,
1696 dtd->dtd_data.
1697 ctt_info) & CTF_ADD_ROOT);
1698
1699 match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1700 sizeof (ctf_encoding_t)) == 0);
1701
1702 /* If the types share the same encoding then return the id of the
1703 first unless one type is root-visible and the other is not; in
1704 that case the new type must get a new id if a match is never
1705 found. Note: slices are not certain to match even if there is
1706 no conflict: we must check the contained type too. */
1707
1708 if (match && sroot == droot)
1709 {
1710 if (kind != CTF_K_SLICE)
1711 return dtd->dtd_type;
1712 }
1713 else if (!match && sroot && droot)
1714 {
1715 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1716 }
1717 }
1718 }
1719 }
1720
1721 src.ctb_file = src_fp;
1722 src.ctb_type = src_type;
1723 src.ctb_dtd = NULL;
1724
1725 dst.ctb_file = dst_fp;
1726 dst.ctb_type = dst_type;
1727 dst.ctb_dtd = NULL;
1728
1729 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1730 we add a new type with the same properties as src_type to dst_fp.
1731 If dst_type is not CTF_ERR, then we verify that dst_type has the
1732 same attributes as src_type. We recurse for embedded references. */
1733 switch (kind)
1734 {
1735 case CTF_K_INTEGER:
1736 /* If we found a match we will have either returned it or declared a
1737 conflict. */
1738 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1739 break;
1740
1741 case CTF_K_FLOAT:
1742 /* If we found a match we will have either returned it or declared a
1743 conflict. */
1744 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1745 break;
1746
1747 case CTF_K_SLICE:
1748 /* We have checked for conflicting encodings: now try to add the
1749 contained type. */
1750 src_type = ctf_type_reference (src_fp, src_type);
1751 dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1752
1753 if (src_type == CTF_ERR)
1754 return CTF_ERR; /* errno is set for us. */
1755
1756 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1757 break;
1758
1759 case CTF_K_POINTER:
1760 case CTF_K_VOLATILE:
1761 case CTF_K_CONST:
1762 case CTF_K_RESTRICT:
1763 src_type = ctf_type_reference (src_fp, src_type);
1764 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1765
1766 if (src_type == CTF_ERR)
1767 return CTF_ERR; /* errno is set for us. */
1768
1769 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1770 break;
1771
1772 case CTF_K_ARRAY:
1773 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1774 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1775
1776 src_ar.ctr_contents =
1777 ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1778 src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1779 src_ar.ctr_nelems = src_ar.ctr_nelems;
1780
1781 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1782 return CTF_ERR; /* errno is set for us. */
1783
1784 if (dst_type != CTF_ERR)
1785 {
1786 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1787 return CTF_ERR; /* errno is set for us. */
1788
1789 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1790 {
1791 ctf_dprintf ("Conflict for type %s against ID %lx: "
1792 "array info differs, old %lx/%lx/%x; "
1793 "new: %lx/%lx/%x\n", name, dst_type,
1794 src_ar.ctr_contents, src_ar.ctr_index,
1795 src_ar.ctr_nelems, dst_ar.ctr_contents,
1796 dst_ar.ctr_index, dst_ar.ctr_nelems);
1797 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1798 }
1799 }
1800 else
1801 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1802 break;
1803
1804 case CTF_K_FUNCTION:
1805 ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1806 ctc.ctc_argc = 0;
1807 ctc.ctc_flags = 0;
1808
1809 if (ctc.ctc_return == CTF_ERR)
1810 return CTF_ERR; /* errno is set for us. */
1811
1812 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1813 break;
1814
1815 case CTF_K_STRUCT:
1816 case CTF_K_UNION:
1817 {
1818 ctf_dmdef_t *dmd;
1819 int errs = 0;
1820 size_t size;
1821 ssize_t ssize;
1822
1823 /* Technically to match a struct or union we need to check both
1824 ways (src members vs. dst, dst members vs. src) but we make
1825 this more optimal by only checking src vs. dst and comparing
1826 the total size of the structure (which we must do anyway)
1827 which covers the possibility of dst members not in src.
1828 This optimization can be defeated for unions, but is so
1829 pathological as to render it irrelevant for our purposes. */
1830
1831 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1832 {
1833 if (ctf_type_size (src_fp, src_type) !=
1834 ctf_type_size (dst_fp, dst_type))
1835 {
1836 ctf_dprintf ("Conflict for type %s against ID %lx: "
1837 "union size differs, old %li, new %li\n",
1838 name, dst_type,
1839 (long) ctf_type_size (src_fp, src_type),
1840 (long) ctf_type_size (dst_fp, dst_type));
1841 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1842 }
1843
1844 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1845 {
1846 ctf_dprintf ("Conflict for type %s against ID %lx: "
1847 "members differ, see above\n", name, dst_type);
1848 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1849 }
1850
1851 break;
1852 }
1853
1854 /* Unlike the other cases, copying structs and unions is done
1855 manually so as to avoid repeated lookups in ctf_add_member
1856 and to ensure the exact same member offsets as in src_type. */
1857
1858 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1859 if (dst_type == CTF_ERR)
1860 return CTF_ERR; /* errno is set for us. */
1861
1862 dst.ctb_type = dst_type;
1863 dst.ctb_dtd = dtd;
1864
1865 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1866 errs++; /* Increment errs and fail at bottom of case. */
1867
1868 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1869 return CTF_ERR; /* errno is set for us. */
1870
1871 size = (size_t) ssize;
1872 if (size > CTF_MAX_SIZE)
1873 {
1874 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1875 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1876 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1877 }
1878 else
1879 dtd->dtd_data.ctt_size = (uint32_t) size;
1880
1881 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1882
1883 /* Make a final pass through the members changing each dmd_type (a
1884 src_fp type) to an equivalent type in dst_fp. We pass through all
1885 members, leaving any that fail set to CTF_ERR. */
1886 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1887 dmd != NULL; dmd = ctf_list_next (dmd))
1888 {
1889 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1890 dmd->dmd_type)) == CTF_ERR)
1891 errs++;
1892 }
1893
1894 if (errs)
1895 return CTF_ERR; /* errno is set for us. */
1896 break;
1897 }
1898
1899 case CTF_K_ENUM:
1900 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1901 {
1902 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1903 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1904 {
1905 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1906 "members differ, see above\n", name, dst_type);
1907 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1908 }
1909 }
1910 else
1911 {
1912 dst_type = ctf_add_enum (dst_fp, flag, name);
1913 if ((dst.ctb_type = dst_type) == CTF_ERR
1914 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1915 return CTF_ERR; /* errno is set for us */
1916 }
1917 break;
1918
1919 case CTF_K_FORWARD:
1920 if (dst_type == CTF_ERR)
1921 {
1922 dst_type = ctf_add_forward (dst_fp, flag,
1923 name, CTF_K_STRUCT); /* Assume STRUCT. */
1924 }
1925 break;
1926
1927 case CTF_K_TYPEDEF:
1928 src_type = ctf_type_reference (src_fp, src_type);
1929 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1930
1931 if (src_type == CTF_ERR)
1932 return CTF_ERR; /* errno is set for us. */
1933
1934 /* If dst_type is not CTF_ERR at this point, we should check if
1935 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1936 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1937 that vary based on things like if 32-bit then pid_t is int otherwise
1938 long. We therefore omit this check and assume that if the identically
1939 named typedef already exists in dst_fp, it is correct or
1940 equivalent. */
1941
1942 if (dst_type == CTF_ERR)
1943 {
1944 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1945 }
1946 break;
1947
1948 default:
1949 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1950 }
1951
1952 return dst_type;
1953 }
1954
1955 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1956 This is useful for saving the results of dynamic CTF containers. */
1957 int
1958 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1959 {
1960 const unsigned char *buf = fp->ctf_base;
1961 ssize_t resid = fp->ctf_size;
1962 ssize_t len;
1963
1964 while (resid != 0)
1965 {
1966 if ((len = gzwrite (fd, buf, resid)) <= 0)
1967 return (ctf_set_errno (fp, errno));
1968 resid -= len;
1969 buf += len;
1970 }
1971
1972 return 0;
1973 }
1974
1975 /* Compress the specified CTF data stream and write it to the specified file
1976 descriptor. */
1977 int
1978 ctf_compress_write (ctf_file_t *fp, int fd)
1979 {
1980 unsigned char *buf;
1981 unsigned char *bp;
1982 ctf_header_t h;
1983 ctf_header_t *hp = &h;
1984 ssize_t header_len = sizeof (ctf_header_t);
1985 ssize_t compress_len;
1986 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1987 ssize_t len;
1988 int rc;
1989 int err = 0;
1990
1991 memcpy (hp, fp->ctf_base, header_len);
1992 hp->cth_flags |= CTF_F_COMPRESS;
1993
1994 if ((buf = ctf_alloc (max_compress_len)) == NULL)
1995 return (ctf_set_errno (fp, ECTF_ZALLOC));
1996
1997 compress_len = max_compress_len;
1998 if ((rc = compress (buf, (uLongf *) &compress_len,
1999 fp->ctf_base + header_len,
2000 fp->ctf_size - header_len)) != Z_OK)
2001 {
2002 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2003 err = ctf_set_errno (fp, ECTF_COMPRESS);
2004 ctf_free (buf);
2005 goto ret;
2006 }
2007
2008 while (header_len > 0)
2009 {
2010 if ((len = write (fd, hp, header_len)) < 0)
2011 {
2012 err = ctf_set_errno (fp, errno);
2013 goto ret;
2014 }
2015 header_len -= len;
2016 hp += len;
2017 }
2018
2019 bp = buf;
2020 while (compress_len > 0)
2021 {
2022 if ((len = write (fd, bp, compress_len)) < 0)
2023 {
2024 err = ctf_set_errno (fp, errno);
2025 goto ret;
2026 }
2027 compress_len -= len;
2028 bp += len;
2029 }
2030
2031 ret:
2032 ctf_free (buf);
2033 return err;
2034 }
2035
2036 /* Write the uncompressed CTF data stream to the specified file descriptor.
2037 This is useful for saving the results of dynamic CTF containers. */
2038 int
2039 ctf_write (ctf_file_t *fp, int fd)
2040 {
2041 const unsigned char *buf = fp->ctf_base;
2042 ssize_t resid = fp->ctf_size;
2043 ssize_t len;
2044
2045 while (resid != 0)
2046 {
2047 if ((len = write (fd, buf, resid)) < 0)
2048 return (ctf_set_errno (fp, errno));
2049 resid -= len;
2050 buf += len;
2051 }
2052
2053 return 0;
2054 }
This page took 0.070703 seconds and 4 git commands to generate.