]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libctf/ctf-create.c
libctf: look for BSD versus GNU qsort_r signatures
[thirdparty/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 = ctf_data_alloc (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 ctf_data_protect (buf, buf_size);
453
454 if ((nfp = ctf_simple_open (buf, buf_size, NULL, 0, 0, NULL, 0, &err)) == NULL)
455 {
456 ctf_data_free (buf, buf_size);
457 return (ctf_set_errno (fp, err));
458 }
459
460 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
461 (void) ctf_import (nfp, fp->ctf_parent);
462
463 nfp->ctf_refcnt = fp->ctf_refcnt;
464 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
465 nfp->ctf_data.cts_data = NULL; /* Force ctf_data_free() on close. */
466 nfp->ctf_dthash = fp->ctf_dthash;
467 nfp->ctf_dtdefs = fp->ctf_dtdefs;
468 nfp->ctf_dtbyname = fp->ctf_dtbyname;
469 nfp->ctf_dvhash = fp->ctf_dvhash;
470 nfp->ctf_dvdefs = fp->ctf_dvdefs;
471 nfp->ctf_dtvstrlen = fp->ctf_dtvstrlen;
472 nfp->ctf_dtnextid = fp->ctf_dtnextid;
473 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
474 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
475 nfp->ctf_specific = fp->ctf_specific;
476
477 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
478
479 fp->ctf_dtbyname = NULL;
480 fp->ctf_dthash = NULL;
481 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
482
483 fp->ctf_dvhash = NULL;
484 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
485
486 memcpy (&ofp, fp, sizeof (ctf_file_t));
487 memcpy (fp, nfp, sizeof (ctf_file_t));
488 memcpy (nfp, &ofp, sizeof (ctf_file_t));
489
490 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
491 array of type name prefixes and the corresponding ctf_dynhash to use.
492 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
493
494 fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
495 fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
496 fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
497 fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
498
499 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
500 ctf_file_close (nfp);
501
502 return 0;
503 }
504
505 static char *
506 ctf_prefixed_name (int kind, const char *name)
507 {
508 char *prefixed;
509
510 switch (kind)
511 {
512 case CTF_K_STRUCT:
513 prefixed = ctf_strdup ("struct ");
514 break;
515 case CTF_K_UNION:
516 prefixed = ctf_strdup ("union ");
517 break;
518 case CTF_K_ENUM:
519 prefixed = ctf_strdup ("enum ");
520 break;
521 default:
522 prefixed = ctf_strdup ("");
523 }
524
525 prefixed = ctf_str_append (prefixed, name);
526 return prefixed;
527 }
528
529 void
530 ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
531 {
532 ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd);
533 ctf_list_append (&fp->ctf_dtdefs, dtd);
534 if (dtd->dtd_name)
535 {
536 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
537 ctf_dynhash_insert (fp->ctf_dtbyname, ctf_prefixed_name (kind,
538 dtd->dtd_name),
539 dtd);
540 }
541 }
542
543 void
544 ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
545 {
546 ctf_dmdef_t *dmd, *nmd;
547 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
548
549 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
550
551 switch (kind)
552 {
553 case CTF_K_STRUCT:
554 case CTF_K_UNION:
555 case CTF_K_ENUM:
556 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
557 dmd != NULL; dmd = nmd)
558 {
559 if (dmd->dmd_name != NULL)
560 {
561 fp->ctf_dtvstrlen -= strlen (dmd->dmd_name) + 1;
562 ctf_free (dmd->dmd_name);
563 }
564 nmd = ctf_list_next (dmd);
565 ctf_free (dmd);
566 }
567 break;
568 case CTF_K_FUNCTION:
569 ctf_free (dtd->dtd_u.dtu_argv);
570 break;
571 }
572
573 if (dtd->dtd_name)
574 {
575 char *name;
576
577 name = ctf_prefixed_name (kind, dtd->dtd_name);
578 ctf_dynhash_remove (fp->ctf_dtbyname, name);
579 free (name);
580
581 fp->ctf_dtvstrlen -= strlen (dtd->dtd_name) + 1;
582 ctf_free (dtd->dtd_name);
583 }
584
585 ctf_list_delete (&fp->ctf_dtdefs, dtd);
586 ctf_free (dtd);
587 }
588
589 ctf_dtdef_t *
590 ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
591 {
592 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
593 }
594
595 static ctf_id_t
596 ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
597 {
598 ctf_dtdef_t *dtd;
599 char *decorated = ctf_prefixed_name (kind, name);
600
601 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
602 free (decorated);
603
604 if (dtd)
605 return dtd->dtd_type;
606
607 return 0;
608 }
609
610 ctf_dtdef_t *
611 ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
612 {
613 ctf_id_t idx;
614
615 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
616 fp = fp->ctf_parent;
617
618 idx = LCTF_TYPE_TO_INDEX(fp, id);
619
620 if (((unsigned long) idx > fp->ctf_typemax) &&
621 ((unsigned long) idx < fp->ctf_dtnextid))
622 return ctf_dtd_lookup (fp, id);
623 return NULL;
624 }
625
626 void
627 ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
628 {
629 ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd);
630 ctf_list_append (&fp->ctf_dvdefs, dvd);
631 }
632
633 void
634 ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
635 {
636 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
637
638 fp->ctf_dtvstrlen -= strlen (dvd->dvd_name) + 1;
639 ctf_free (dvd->dvd_name);
640
641 ctf_list_delete (&fp->ctf_dvdefs, dvd);
642 ctf_free (dvd);
643 }
644
645 ctf_dvdef_t *
646 ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
647 {
648 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
649 }
650
651 /* Discard all of the dynamic type definitions and variable definitions that
652 have been added to the container since the last call to ctf_update(). We
653 locate such types by scanning the dtd list and deleting elements that have
654 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
655 by scanning the variable list and deleting elements that have update IDs
656 equal to the current value of the last-update snapshot count (indicating that
657 they were added after the most recent call to ctf_update()). */
658 int
659 ctf_discard (ctf_file_t *fp)
660 {
661 ctf_snapshot_id_t last_update =
662 { fp->ctf_dtoldid,
663 fp->ctf_snapshot_lu + 1 };
664
665 /* Update required? */
666 if (!(fp->ctf_flags & LCTF_DIRTY))
667 return 0;
668
669 return (ctf_rollback (fp, last_update));
670 }
671
672 ctf_snapshot_id_t
673 ctf_snapshot (ctf_file_t *fp)
674 {
675 ctf_snapshot_id_t snapid;
676 snapid.dtd_id = fp->ctf_dtnextid - 1;
677 snapid.snapshot_id = fp->ctf_snapshots++;
678 return snapid;
679 }
680
681 /* Like ctf_discard(), only discards everything after a particular ID. */
682 int
683 ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
684 {
685 ctf_dtdef_t *dtd, *ntd;
686 ctf_dvdef_t *dvd, *nvd;
687
688 if (!(fp->ctf_flags & LCTF_RDWR))
689 return (ctf_set_errno (fp, ECTF_RDONLY));
690
691 if (fp->ctf_dtoldid > id.dtd_id)
692 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
693
694 if (fp->ctf_snapshot_lu >= id.snapshot_id)
695 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
696
697 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
698 {
699 ntd = ctf_list_next (dtd);
700
701 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
702 continue;
703
704 ctf_dtd_delete (fp, dtd);
705 }
706
707 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
708 {
709 nvd = ctf_list_next (dvd);
710
711 if (dvd->dvd_snapshots <= id.snapshot_id)
712 continue;
713
714 ctf_dvd_delete (fp, dvd);
715 }
716
717 fp->ctf_dtnextid = id.dtd_id + 1;
718 fp->ctf_snapshots = id.snapshot_id;
719
720 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
721 fp->ctf_flags &= ~LCTF_DIRTY;
722
723 return 0;
724 }
725
726 static ctf_id_t
727 ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
728 ctf_dtdef_t **rp)
729 {
730 ctf_dtdef_t *dtd;
731 ctf_id_t type;
732 char *s = NULL;
733
734 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
735 return (ctf_set_errno (fp, EINVAL));
736
737 if (!(fp->ctf_flags & LCTF_RDWR))
738 return (ctf_set_errno (fp, ECTF_RDONLY));
739
740 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
741 return (ctf_set_errno (fp, ECTF_FULL));
742
743 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
744 return (ctf_set_errno (fp, ECTF_FULL));
745
746 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
747 return (ctf_set_errno (fp, EAGAIN));
748
749 if (name != NULL && (s = ctf_strdup (name)) == NULL)
750 {
751 ctf_free (dtd);
752 return (ctf_set_errno (fp, EAGAIN));
753 }
754
755 type = fp->ctf_dtnextid++;
756 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
757
758 memset (dtd, 0, sizeof (ctf_dtdef_t));
759 dtd->dtd_name = s;
760 dtd->dtd_type = type;
761
762 if (s != NULL)
763 fp->ctf_dtvstrlen += strlen (s) + 1;
764
765 ctf_dtd_insert (fp, dtd);
766 fp->ctf_flags |= LCTF_DIRTY;
767
768 *rp = dtd;
769 return type;
770 }
771
772 /* When encoding integer sizes, we want to convert a byte count in the range
773 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
774 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
775 static size_t
776 clp2 (size_t x)
777 {
778 x--;
779
780 x |= (x >> 1);
781 x |= (x >> 2);
782 x |= (x >> 4);
783 x |= (x >> 8);
784 x |= (x >> 16);
785
786 return (x + 1);
787 }
788
789 static ctf_id_t
790 ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
791 const char *name, const ctf_encoding_t *ep, uint32_t kind)
792 {
793 ctf_dtdef_t *dtd;
794 ctf_id_t type;
795
796 if (ep == NULL)
797 return (ctf_set_errno (fp, EINVAL));
798
799 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
800 return CTF_ERR; /* errno is set for us. */
801
802 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
803 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, NBBY) / NBBY);
804 dtd->dtd_u.dtu_enc = *ep;
805
806 return type;
807 }
808
809 static ctf_id_t
810 ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
811 {
812 ctf_dtdef_t *dtd;
813 ctf_id_t type;
814 ctf_file_t *tmp = fp;
815
816 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
817 return (ctf_set_errno (fp, EINVAL));
818
819 if (ctf_lookup_by_id (&tmp, ref) == NULL)
820 return CTF_ERR; /* errno is set for us. */
821
822 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
823 return CTF_ERR; /* errno is set for us. */
824
825 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
826 dtd->dtd_data.ctt_type = (uint32_t) ref;
827
828 return type;
829 }
830
831 ctf_id_t
832 ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
833 const ctf_encoding_t *ep)
834 {
835 ctf_dtdef_t *dtd;
836 ctf_id_t type;
837 int kind;
838 const ctf_type_t *tp;
839 ctf_file_t *tmp = fp;
840
841 if (ep == NULL)
842 return (ctf_set_errno (fp, EINVAL));
843
844 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
845 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
846
847 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
848 return (ctf_set_errno (fp, EINVAL));
849
850 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
851 return CTF_ERR; /* errno is set for us. */
852
853 kind = ctf_type_kind_unsliced (tmp, ref);
854 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
855 (kind != CTF_K_ENUM))
856 return (ctf_set_errno (fp, ECTF_NOTINTFP));
857
858 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
859 return CTF_ERR; /* errno is set for us. */
860
861 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
862 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, NBBY) / NBBY);
863 dtd->dtd_u.dtu_slice.cts_type = ref;
864 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
865 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
866
867 return type;
868 }
869
870 ctf_id_t
871 ctf_add_integer (ctf_file_t *fp, uint32_t flag,
872 const char *name, const ctf_encoding_t *ep)
873 {
874 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
875 }
876
877 ctf_id_t
878 ctf_add_float (ctf_file_t *fp, uint32_t flag,
879 const char *name, const ctf_encoding_t *ep)
880 {
881 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
882 }
883
884 ctf_id_t
885 ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
886 {
887 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
888 }
889
890 ctf_id_t
891 ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
892 {
893 ctf_dtdef_t *dtd;
894 ctf_id_t type;
895 ctf_file_t *tmp = fp;
896
897 if (arp == NULL)
898 return (ctf_set_errno (fp, EINVAL));
899
900 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
901 return CTF_ERR; /* errno is set for us. */
902
903 tmp = fp;
904 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
905 return CTF_ERR; /* errno is set for us. */
906
907 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
908 return CTF_ERR; /* errno is set for us. */
909
910 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
911 dtd->dtd_data.ctt_size = 0;
912 dtd->dtd_u.dtu_arr = *arp;
913
914 return type;
915 }
916
917 int
918 ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
919 {
920 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
921
922 if (!(fp->ctf_flags & LCTF_RDWR))
923 return (ctf_set_errno (fp, ECTF_RDONLY));
924
925 if (dtd == NULL
926 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
927 return (ctf_set_errno (fp, ECTF_BADID));
928
929 fp->ctf_flags |= LCTF_DIRTY;
930 dtd->dtd_u.dtu_arr = *arp;
931
932 return 0;
933 }
934
935 ctf_id_t
936 ctf_add_function (ctf_file_t *fp, uint32_t flag,
937 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
938 {
939 ctf_dtdef_t *dtd;
940 ctf_id_t type;
941 uint32_t vlen;
942 ctf_id_t *vdat = NULL;
943 ctf_file_t *tmp = fp;
944 size_t i;
945
946 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
947 || (ctc->ctc_argc != 0 && argv == NULL))
948 return (ctf_set_errno (fp, EINVAL));
949
950 vlen = ctc->ctc_argc;
951 if (ctc->ctc_flags & CTF_FUNC_VARARG)
952 vlen++; /* Add trailing zero to indicate varargs (see below). */
953
954 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
955 return CTF_ERR; /* errno is set for us. */
956
957 for (i = 0; i < ctc->ctc_argc; i++)
958 {
959 tmp = fp;
960 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
961 return CTF_ERR; /* errno is set for us. */
962 }
963
964 if (vlen > CTF_MAX_VLEN)
965 return (ctf_set_errno (fp, EOVERFLOW));
966
967 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
968 return (ctf_set_errno (fp, EAGAIN));
969
970 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
971 {
972 ctf_free (vdat);
973 return CTF_ERR; /* errno is set for us. */
974 }
975
976 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
977 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
978
979 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
980 if (ctc->ctc_flags & CTF_FUNC_VARARG)
981 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
982 dtd->dtd_u.dtu_argv = vdat;
983
984 return type;
985 }
986
987 ctf_id_t
988 ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
989 size_t size)
990 {
991 ctf_hash_t *hp = fp->ctf_structs;
992 ctf_dtdef_t *dtd;
993 ctf_id_t type = 0;
994
995 /* Promote forwards to structs. */
996
997 if (name != NULL)
998 {
999 type = ctf_hash_lookup_type (hp, fp, name);
1000 if (type == 0)
1001 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
1002 }
1003
1004 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1005 dtd = ctf_dtd_lookup (fp, type);
1006 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1007 return CTF_ERR; /* errno is set for us. */
1008
1009 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1010
1011 if (size > CTF_MAX_SIZE)
1012 {
1013 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1014 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1015 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1016 }
1017 else
1018 dtd->dtd_data.ctt_size = (uint32_t) size;
1019
1020 return type;
1021 }
1022
1023 ctf_id_t
1024 ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1025 {
1026 return (ctf_add_struct_sized (fp, flag, name, 0));
1027 }
1028
1029 ctf_id_t
1030 ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1031 size_t size)
1032 {
1033 ctf_hash_t *hp = fp->ctf_unions;
1034 ctf_dtdef_t *dtd;
1035 ctf_id_t type = 0;
1036
1037 /* Promote forwards to unions. */
1038 if (name != NULL)
1039 {
1040 type = ctf_hash_lookup_type (hp, fp, name);
1041 if (type == 0)
1042 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1043 }
1044
1045 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1046 dtd = ctf_dtd_lookup (fp, type);
1047 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1048 return CTF_ERR; /* errno is set for us */
1049
1050 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1051
1052 if (size > CTF_MAX_SIZE)
1053 {
1054 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1055 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1056 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1057 }
1058 else
1059 dtd->dtd_data.ctt_size = (uint32_t) size;
1060
1061 return type;
1062 }
1063
1064 ctf_id_t
1065 ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1066 {
1067 return (ctf_add_union_sized (fp, flag, name, 0));
1068 }
1069
1070 ctf_id_t
1071 ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1072 {
1073 ctf_hash_t *hp = fp->ctf_enums;
1074 ctf_dtdef_t *dtd;
1075 ctf_id_t type = 0;
1076
1077 /* Promote forwards to enums. */
1078 if (name != NULL)
1079 {
1080 type = ctf_hash_lookup_type (hp, fp, name);
1081 if (type == 0)
1082 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1083 }
1084
1085 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1086 dtd = ctf_dtd_lookup (fp, type);
1087 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1088 return CTF_ERR; /* errno is set for us. */
1089
1090 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1091 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1092
1093 return type;
1094 }
1095
1096 ctf_id_t
1097 ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1098 const ctf_encoding_t *ep)
1099 {
1100 ctf_hash_t *hp = fp->ctf_enums;
1101 ctf_id_t type = 0;
1102
1103 /* First, create the enum if need be, using most of the same machinery as
1104 ctf_add_enum(), to ensure that we do not allow things past that are not
1105 enums or forwards to them. (This includes other slices: you cannot slice a
1106 slice, which would be a useless thing to do anyway.) */
1107
1108 if (name != NULL)
1109 {
1110 type = ctf_hash_lookup_type (hp, fp, name);
1111 if (type == 0)
1112 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1113 }
1114
1115 if (type != 0)
1116 {
1117 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1118 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1119 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1120 }
1121 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1122 return CTF_ERR; /* errno is set for us. */
1123
1124 /* Now attach a suitable slice to it. */
1125
1126 return ctf_add_slice (fp, flag, type, ep);
1127 }
1128
1129 ctf_id_t
1130 ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1131 uint32_t kind)
1132 {
1133 ctf_hash_t *hp;
1134 ctf_dtdef_t *dtd;
1135 ctf_id_t type = 0;
1136
1137 switch (kind)
1138 {
1139 case CTF_K_STRUCT:
1140 hp = fp->ctf_structs;
1141 break;
1142 case CTF_K_UNION:
1143 hp = fp->ctf_unions;
1144 break;
1145 case CTF_K_ENUM:
1146 hp = fp->ctf_enums;
1147 break;
1148 default:
1149 return (ctf_set_errno (fp, ECTF_NOTSUE));
1150 }
1151
1152 /* If the type is already defined or exists as a forward tag, just
1153 return the ctf_id_t of the existing definition. */
1154
1155 if (name != NULL)
1156 {
1157 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1158 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1159 return type;
1160 }
1161
1162 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1163 return CTF_ERR; /* errno is set for us. */
1164
1165 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1166 dtd->dtd_data.ctt_type = kind;
1167
1168 return type;
1169 }
1170
1171 ctf_id_t
1172 ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1173 ctf_id_t ref)
1174 {
1175 ctf_dtdef_t *dtd;
1176 ctf_id_t type;
1177 ctf_file_t *tmp = fp;
1178
1179 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1180 return (ctf_set_errno (fp, EINVAL));
1181
1182 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1183 return CTF_ERR; /* errno is set for us. */
1184
1185 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1186 return CTF_ERR; /* errno is set for us. */
1187
1188 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1189 dtd->dtd_data.ctt_type = (uint32_t) ref;
1190
1191 return type;
1192 }
1193
1194 ctf_id_t
1195 ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1196 {
1197 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1198 }
1199
1200 ctf_id_t
1201 ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1202 {
1203 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1204 }
1205
1206 ctf_id_t
1207 ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1208 {
1209 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1210 }
1211
1212 int
1213 ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1214 int value)
1215 {
1216 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1217 ctf_dmdef_t *dmd;
1218
1219 uint32_t kind, vlen, root;
1220 char *s;
1221
1222 if (name == NULL)
1223 return (ctf_set_errno (fp, EINVAL));
1224
1225 if (!(fp->ctf_flags & LCTF_RDWR))
1226 return (ctf_set_errno (fp, ECTF_RDONLY));
1227
1228 if (dtd == NULL)
1229 return (ctf_set_errno (fp, ECTF_BADID));
1230
1231 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1232 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1233 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1234
1235 if (kind != CTF_K_ENUM)
1236 return (ctf_set_errno (fp, ECTF_NOTENUM));
1237
1238 if (vlen == CTF_MAX_VLEN)
1239 return (ctf_set_errno (fp, ECTF_DTFULL));
1240
1241 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1242 dmd != NULL; dmd = ctf_list_next (dmd))
1243 {
1244 if (strcmp (dmd->dmd_name, name) == 0)
1245 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1246 }
1247
1248 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1249 return (ctf_set_errno (fp, EAGAIN));
1250
1251 if ((s = ctf_strdup (name)) == NULL)
1252 {
1253 ctf_free (dmd);
1254 return (ctf_set_errno (fp, EAGAIN));
1255 }
1256
1257 dmd->dmd_name = s;
1258 dmd->dmd_type = CTF_ERR;
1259 dmd->dmd_offset = 0;
1260 dmd->dmd_value = value;
1261
1262 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1263 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1264
1265 fp->ctf_dtvstrlen += strlen (s) + 1;
1266 fp->ctf_flags |= LCTF_DIRTY;
1267
1268 return 0;
1269 }
1270
1271 int
1272 ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1273 ctf_id_t type, unsigned long bit_offset)
1274 {
1275 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1276 ctf_dmdef_t *dmd;
1277
1278 ssize_t msize, malign, ssize;
1279 uint32_t kind, vlen, root;
1280 char *s = NULL;
1281
1282 if (!(fp->ctf_flags & LCTF_RDWR))
1283 return (ctf_set_errno (fp, ECTF_RDONLY));
1284
1285 if (dtd == NULL)
1286 return (ctf_set_errno (fp, ECTF_BADID));
1287
1288 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1289 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1290 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1291
1292 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1293 return (ctf_set_errno (fp, ECTF_NOTSOU));
1294
1295 if (vlen == CTF_MAX_VLEN)
1296 return (ctf_set_errno (fp, ECTF_DTFULL));
1297
1298 if (name != NULL)
1299 {
1300 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1301 dmd != NULL; dmd = ctf_list_next (dmd))
1302 {
1303 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1304 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1305 }
1306 }
1307
1308 if ((msize = ctf_type_size (fp, type)) < 0 ||
1309 (malign = ctf_type_align (fp, type)) < 0)
1310 return -1; /* errno is set for us. */
1311
1312 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1313 return (ctf_set_errno (fp, EAGAIN));
1314
1315 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1316 {
1317 ctf_free (dmd);
1318 return (ctf_set_errno (fp, EAGAIN));
1319 }
1320
1321 dmd->dmd_name = s;
1322 dmd->dmd_type = type;
1323 dmd->dmd_value = -1;
1324
1325 if (kind == CTF_K_STRUCT && vlen != 0)
1326 {
1327 if (bit_offset == (unsigned long) - 1)
1328 {
1329 /* Natural alignment. */
1330
1331 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1332 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1333 size_t off = lmd->dmd_offset;
1334
1335 ctf_encoding_t linfo;
1336 ssize_t lsize;
1337
1338 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1339 off += linfo.cte_bits;
1340 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1341 off += lsize * NBBY;
1342
1343 /* Round up the offset of the end of the last member to
1344 the next byte boundary, convert 'off' to bytes, and
1345 then round it up again to the next multiple of the
1346 alignment required by the new member. Finally,
1347 convert back to bits and store the result in
1348 dmd_offset. Technically we could do more efficient
1349 packing if the new member is a bit-field, but we're
1350 the "compiler" and ANSI says we can do as we choose. */
1351
1352 off = roundup (off, NBBY) / NBBY;
1353 off = roundup (off, MAX (malign, 1));
1354 dmd->dmd_offset = off * NBBY;
1355 ssize = off + msize;
1356 }
1357 else
1358 {
1359 /* Specified offset in bits. */
1360
1361 dmd->dmd_offset = bit_offset;
1362 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1363 ssize = MAX (ssize, ((signed) bit_offset / NBBY) + msize);
1364 }
1365 }
1366 else
1367 {
1368 dmd->dmd_offset = 0;
1369 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1370 ssize = MAX (ssize, msize);
1371 }
1372
1373 if ((size_t) ssize > CTF_MAX_SIZE)
1374 {
1375 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1376 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1377 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1378 }
1379 else
1380 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1381
1382 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1383 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1384
1385 if (s != NULL)
1386 fp->ctf_dtvstrlen += strlen (s) + 1;
1387
1388 fp->ctf_flags |= LCTF_DIRTY;
1389 return 0;
1390 }
1391
1392 int
1393 ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1394 ctf_id_t type, unsigned long bit_offset,
1395 const ctf_encoding_t encoding)
1396 {
1397 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1398 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1399 int otype = type;
1400
1401 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1402 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1403
1404 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1405 return -1; /* errno is set for us. */
1406
1407 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1408 }
1409
1410 int
1411 ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1412 ctf_id_t type)
1413 {
1414 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1415 }
1416
1417 int
1418 ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1419 {
1420 ctf_dvdef_t *dvd;
1421 ctf_file_t *tmp = fp;
1422
1423 if (!(fp->ctf_flags & LCTF_RDWR))
1424 return (ctf_set_errno (fp, ECTF_RDONLY));
1425
1426 if (ctf_dvd_lookup (fp, name) != NULL)
1427 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1428
1429 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1430 return -1; /* errno is set for us. */
1431
1432 if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL)
1433 return (ctf_set_errno (fp, EAGAIN));
1434
1435 if (name != NULL && (dvd->dvd_name = ctf_strdup (name)) == NULL)
1436 {
1437 ctf_free (dvd);
1438 return (ctf_set_errno (fp, EAGAIN));
1439 }
1440 dvd->dvd_type = ref;
1441 dvd->dvd_snapshots = fp->ctf_snapshots;
1442
1443 ctf_dvd_insert (fp, dvd);
1444
1445 fp->ctf_dtvstrlen += strlen (name) + 1;
1446 fp->ctf_flags |= LCTF_DIRTY;
1447 return 0;
1448 }
1449
1450 static int
1451 enumcmp (const char *name, int value, void *arg)
1452 {
1453 ctf_bundle_t *ctb = arg;
1454 int bvalue;
1455
1456 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
1457 {
1458 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1459 return 1;
1460 }
1461 if (value != bvalue)
1462 {
1463 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1464 value, bvalue);
1465 return 1;
1466 }
1467 return 0;
1468 }
1469
1470 static int
1471 enumadd (const char *name, int value, void *arg)
1472 {
1473 ctf_bundle_t *ctb = arg;
1474
1475 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
1476 name, value) < 0);
1477 }
1478
1479 static int
1480 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1481 void *arg)
1482 {
1483 ctf_bundle_t *ctb = arg;
1484 ctf_membinfo_t ctm;
1485
1486 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
1487 {
1488 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1489 return 1;
1490 }
1491 if (ctm.ctm_offset != offset)
1492 {
1493 ctf_dprintf ("Conflict due to member %s offset change: "
1494 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1495 return 1;
1496 }
1497 return 0;
1498 }
1499
1500 static int
1501 membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1502 {
1503 ctf_bundle_t *ctb = arg;
1504 ctf_dmdef_t *dmd;
1505 char *s = NULL;
1506
1507 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1508 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1509
1510 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1511 {
1512 ctf_free (dmd);
1513 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1514 }
1515
1516 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1517 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1518 dmd->dmd_name = s;
1519 dmd->dmd_type = type;
1520 dmd->dmd_offset = offset;
1521 dmd->dmd_value = -1;
1522
1523 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1524
1525 if (s != NULL)
1526 ctb->ctb_file->ctf_dtvstrlen += strlen (s) + 1;
1527
1528 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1529 return 0;
1530 }
1531
1532 /* The ctf_add_type routine is used to copy a type from a source CTF container
1533 to a dynamic destination container. This routine operates recursively by
1534 following the source type's links and embedded member types. If the
1535 destination container already contains a named type which has the same
1536 attributes, then we succeed and return this type but no changes occur. */
1537 ctf_id_t
1538 ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1539 {
1540 ctf_id_t dst_type = CTF_ERR;
1541 uint32_t dst_kind = CTF_K_UNKNOWN;
1542 ctf_id_t tmp;
1543
1544 const char *name;
1545 uint32_t kind, flag, vlen;
1546
1547 const ctf_type_t *src_tp, *dst_tp;
1548 ctf_bundle_t src, dst;
1549 ctf_encoding_t src_en, dst_en;
1550 ctf_arinfo_t src_ar, dst_ar;
1551
1552 ctf_dtdef_t *dtd;
1553 ctf_funcinfo_t ctc;
1554
1555 ctf_hash_t *hp;
1556
1557 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1558 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1559
1560 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1561 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1562
1563 name = ctf_strptr (src_fp, src_tp->ctt_name);
1564 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1565 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1566 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1567
1568 switch (kind)
1569 {
1570 case CTF_K_STRUCT:
1571 hp = dst_fp->ctf_structs;
1572 break;
1573 case CTF_K_UNION:
1574 hp = dst_fp->ctf_unions;
1575 break;
1576 case CTF_K_ENUM:
1577 hp = dst_fp->ctf_enums;
1578 break;
1579 default:
1580 hp = dst_fp->ctf_names;
1581 break;
1582 }
1583
1584 /* If the source type has a name and is a root type (visible at the
1585 top-level scope), lookup the name in the destination container and
1586 verify that it is of the same kind before we do anything else. */
1587
1588 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1589 && (tmp = ctf_hash_lookup_type (hp, dst_fp, name)) != 0)
1590 {
1591 dst_type = tmp;
1592 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1593 }
1594
1595 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1596 unless dst_type is a forward declaration and src_type is a struct,
1597 union, or enum (i.e. the definition of the previous forward decl). */
1598
1599 if (dst_type != CTF_ERR && dst_kind != kind
1600 && (dst_kind != CTF_K_FORWARD
1601 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1602 && kind != CTF_K_UNION)))
1603 {
1604 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1605 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1606 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1607 }
1608
1609 /* We take special action for an integer, float, or slice since it is
1610 described not only by its name but also its encoding. For integers,
1611 bit-fields exploit this degeneracy. */
1612
1613 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1614 {
1615 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1616 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1617
1618 if (dst_type != CTF_ERR)
1619 {
1620 ctf_file_t *fp = dst_fp;
1621
1622 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1623 return CTF_ERR;
1624
1625 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1626 {
1627 /* The type that we found in the hash is also root-visible. If
1628 the two types match then use the existing one; otherwise,
1629 declare a conflict. Note: slices are not certain to match
1630 even if there is no conflict: we must check the contained type
1631 too. */
1632
1633 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1634 return CTF_ERR; /* errno set for us. */
1635
1636 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1637 {
1638 if (kind != CTF_K_SLICE)
1639 return dst_type;
1640 }
1641 else
1642 {
1643 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1644 }
1645 }
1646 else
1647 {
1648 /* We found a non-root-visible type in the hash. We reset
1649 dst_type to ensure that we continue to look for a possible
1650 conflict in the pending list. */
1651
1652 dst_type = CTF_ERR;
1653 }
1654 }
1655 }
1656
1657 /* If the non-empty name was not found in the appropriate hash, search
1658 the list of pending dynamic definitions that are not yet committed.
1659 If a matching name and kind are found, assume this is the type that
1660 we are looking for. This is necessary to permit ctf_add_type() to
1661 operate recursively on entities such as a struct that contains a
1662 pointer member that refers to the same struct type. */
1663
1664 if (dst_type == CTF_ERR && name[0] != '\0')
1665 {
1666 for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1667 && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1668 dtd = ctf_list_prev (dtd))
1669 {
1670 if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1671 && dtd->dtd_name != NULL && strcmp (dtd->dtd_name, name) == 0)
1672 {
1673 int sroot; /* Is the src root-visible? */
1674 int droot; /* Is the dst root-visible? */
1675 int match; /* Do the encodings match? */
1676
1677 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1678 return dtd->dtd_type;
1679
1680 sroot = (flag & CTF_ADD_ROOT);
1681 droot = (LCTF_INFO_ISROOT (dst_fp,
1682 dtd->dtd_data.
1683 ctt_info) & CTF_ADD_ROOT);
1684
1685 match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1686 sizeof (ctf_encoding_t)) == 0);
1687
1688 /* If the types share the same encoding then return the id of the
1689 first unless one type is root-visible and the other is not; in
1690 that case the new type must get a new id if a match is never
1691 found. Note: slices are not certain to match even if there is
1692 no conflict: we must check the contained type too. */
1693
1694 if (match && sroot == droot)
1695 {
1696 if (kind != CTF_K_SLICE)
1697 return dtd->dtd_type;
1698 }
1699 else if (!match && sroot && droot)
1700 {
1701 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1702 }
1703 }
1704 }
1705 }
1706
1707 src.ctb_file = src_fp;
1708 src.ctb_type = src_type;
1709 src.ctb_dtd = NULL;
1710
1711 dst.ctb_file = dst_fp;
1712 dst.ctb_type = dst_type;
1713 dst.ctb_dtd = NULL;
1714
1715 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1716 we add a new type with the same properties as src_type to dst_fp.
1717 If dst_type is not CTF_ERR, then we verify that dst_type has the
1718 same attributes as src_type. We recurse for embedded references. */
1719 switch (kind)
1720 {
1721 case CTF_K_INTEGER:
1722 /* If we found a match we will have either returned it or declared a
1723 conflict. */
1724 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1725 break;
1726
1727 case CTF_K_FLOAT:
1728 /* If we found a match we will have either returned it or declared a
1729 conflict. */
1730 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1731 break;
1732
1733 case CTF_K_SLICE:
1734 /* We have checked for conflicting encodings: now try to add the
1735 contained type. */
1736 src_type = ctf_type_reference (src_fp, src_type);
1737 dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1738
1739 if (src_type == CTF_ERR)
1740 return CTF_ERR; /* errno is set for us. */
1741
1742 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1743 break;
1744
1745 case CTF_K_POINTER:
1746 case CTF_K_VOLATILE:
1747 case CTF_K_CONST:
1748 case CTF_K_RESTRICT:
1749 src_type = ctf_type_reference (src_fp, src_type);
1750 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1751
1752 if (src_type == CTF_ERR)
1753 return CTF_ERR; /* errno is set for us. */
1754
1755 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1756 break;
1757
1758 case CTF_K_ARRAY:
1759 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1760 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1761
1762 src_ar.ctr_contents =
1763 ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1764 src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1765 src_ar.ctr_nelems = src_ar.ctr_nelems;
1766
1767 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1768 return CTF_ERR; /* errno is set for us. */
1769
1770 if (dst_type != CTF_ERR)
1771 {
1772 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1773 return CTF_ERR; /* errno is set for us. */
1774
1775 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1776 {
1777 ctf_dprintf ("Conflict for type %s against ID %lx: "
1778 "array info differs, old %lx/%lx/%x; "
1779 "new: %lx/%lx/%x\n", name, dst_type,
1780 src_ar.ctr_contents, src_ar.ctr_index,
1781 src_ar.ctr_nelems, dst_ar.ctr_contents,
1782 dst_ar.ctr_index, dst_ar.ctr_nelems);
1783 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1784 }
1785 }
1786 else
1787 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1788 break;
1789
1790 case CTF_K_FUNCTION:
1791 ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1792 ctc.ctc_argc = 0;
1793 ctc.ctc_flags = 0;
1794
1795 if (ctc.ctc_return == CTF_ERR)
1796 return CTF_ERR; /* errno is set for us. */
1797
1798 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1799 break;
1800
1801 case CTF_K_STRUCT:
1802 case CTF_K_UNION:
1803 {
1804 ctf_dmdef_t *dmd;
1805 int errs = 0;
1806 size_t size;
1807 ssize_t ssize;
1808
1809 /* Technically to match a struct or union we need to check both
1810 ways (src members vs. dst, dst members vs. src) but we make
1811 this more optimal by only checking src vs. dst and comparing
1812 the total size of the structure (which we must do anyway)
1813 which covers the possibility of dst members not in src.
1814 This optimization can be defeated for unions, but is so
1815 pathological as to render it irrelevant for our purposes. */
1816
1817 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1818 {
1819 if (ctf_type_size (src_fp, src_type) !=
1820 ctf_type_size (dst_fp, dst_type))
1821 {
1822 ctf_dprintf ("Conflict for type %s against ID %lx: "
1823 "union size differs, old %zi, new %zi\n",
1824 name, dst_type, ctf_type_size (src_fp, src_type),
1825 ctf_type_size (dst_fp, dst_type));
1826 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1827 }
1828
1829 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1830 {
1831 ctf_dprintf ("Conflict for type %s against ID %lx: "
1832 "members differ, see above\n", name, dst_type);
1833 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1834 }
1835
1836 break;
1837 }
1838
1839 /* Unlike the other cases, copying structs and unions is done
1840 manually so as to avoid repeated lookups in ctf_add_member
1841 and to ensure the exact same member offsets as in src_type. */
1842
1843 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1844 if (dst_type == CTF_ERR)
1845 return CTF_ERR; /* errno is set for us. */
1846
1847 dst.ctb_type = dst_type;
1848 dst.ctb_dtd = dtd;
1849
1850 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1851 errs++; /* Increment errs and fail at bottom of case. */
1852
1853 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1854 return CTF_ERR; /* errno is set for us. */
1855
1856 size = (size_t) ssize;
1857 if (size > CTF_MAX_SIZE)
1858 {
1859 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1860 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1861 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1862 }
1863 else
1864 dtd->dtd_data.ctt_size = (uint32_t) size;
1865
1866 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1867
1868 /* Make a final pass through the members changing each dmd_type (a
1869 src_fp type) to an equivalent type in dst_fp. We pass through all
1870 members, leaving any that fail set to CTF_ERR. */
1871 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1872 dmd != NULL; dmd = ctf_list_next (dmd))
1873 {
1874 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1875 dmd->dmd_type)) == CTF_ERR)
1876 errs++;
1877 }
1878
1879 if (errs)
1880 return CTF_ERR; /* errno is set for us. */
1881 break;
1882 }
1883
1884 case CTF_K_ENUM:
1885 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1886 {
1887 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1888 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1889 {
1890 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1891 "members differ, see above\n", name, dst_type);
1892 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1893 }
1894 }
1895 else
1896 {
1897 dst_type = ctf_add_enum (dst_fp, flag, name);
1898 if ((dst.ctb_type = dst_type) == CTF_ERR
1899 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1900 return CTF_ERR; /* errno is set for us */
1901 }
1902 break;
1903
1904 case CTF_K_FORWARD:
1905 if (dst_type == CTF_ERR)
1906 {
1907 dst_type = ctf_add_forward (dst_fp, flag,
1908 name, CTF_K_STRUCT); /* Assume STRUCT. */
1909 }
1910 break;
1911
1912 case CTF_K_TYPEDEF:
1913 src_type = ctf_type_reference (src_fp, src_type);
1914 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1915
1916 if (src_type == CTF_ERR)
1917 return CTF_ERR; /* errno is set for us. */
1918
1919 /* If dst_type is not CTF_ERR at this point, we should check if
1920 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1921 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1922 that vary based on things like if 32-bit then pid_t is int otherwise
1923 long. We therefore omit this check and assume that if the identically
1924 named typedef already exists in dst_fp, it is correct or
1925 equivalent. */
1926
1927 if (dst_type == CTF_ERR)
1928 {
1929 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1930 }
1931 break;
1932
1933 default:
1934 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1935 }
1936
1937 return dst_type;
1938 }
1939
1940 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1941 This is useful for saving the results of dynamic CTF containers. */
1942 int
1943 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1944 {
1945 const unsigned char *buf = fp->ctf_base;
1946 ssize_t resid = fp->ctf_size;
1947 ssize_t len;
1948
1949 while (resid != 0)
1950 {
1951 if ((len = gzwrite (fd, buf, resid)) <= 0)
1952 return (ctf_set_errno (fp, errno));
1953 resid -= len;
1954 buf += len;
1955 }
1956
1957 return 0;
1958 }
1959
1960 /* Compress the specified CTF data stream and write it to the specified file
1961 descriptor. */
1962 int
1963 ctf_compress_write (ctf_file_t *fp, int fd)
1964 {
1965 unsigned char *buf;
1966 unsigned char *bp;
1967 ctf_header_t h;
1968 ctf_header_t *hp = &h;
1969 ssize_t header_len = sizeof (ctf_header_t);
1970 ssize_t compress_len;
1971 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1972 ssize_t len;
1973 int rc;
1974 int err = 0;
1975
1976 memcpy (hp, fp->ctf_base, header_len);
1977 hp->cth_flags |= CTF_F_COMPRESS;
1978
1979 if ((buf = ctf_data_alloc (max_compress_len)) == NULL)
1980 return (ctf_set_errno (fp, ECTF_ZALLOC));
1981
1982 compress_len = max_compress_len;
1983 if ((rc = compress (buf, (uLongf *) & compress_len,
1984 fp->ctf_base + header_len,
1985 fp->ctf_size - header_len)) != Z_OK)
1986 {
1987 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
1988 err = ctf_set_errno (fp, ECTF_COMPRESS);
1989 goto ret;
1990 }
1991
1992 while (header_len > 0)
1993 {
1994 if ((len = write (fd, hp, header_len)) < 0)
1995 {
1996 err = ctf_set_errno (fp, errno);
1997 goto ret;
1998 }
1999 header_len -= len;
2000 hp += len;
2001 }
2002
2003 bp = buf;
2004 while (compress_len > 0)
2005 {
2006 if ((len = write (fd, bp, compress_len)) < 0)
2007 {
2008 err = ctf_set_errno (fp, errno);
2009 goto ret;
2010 }
2011 compress_len -= len;
2012 bp += len;
2013 }
2014
2015 ret:
2016 ctf_data_free (buf, max_compress_len);
2017 return err;
2018 }
2019
2020 /* Write the uncompressed CTF data stream to the specified file descriptor.
2021 This is useful for saving the results of dynamic CTF containers. */
2022 int
2023 ctf_write (ctf_file_t *fp, int fd)
2024 {
2025 const unsigned char *buf = fp->ctf_base;
2026 ssize_t resid = fp->ctf_size;
2027 ssize_t len;
2028
2029 while (resid != 0)
2030 {
2031 if ((len = write (fd, buf, resid)) < 0)
2032 return (ctf_set_errno (fp, errno));
2033 resid -= len;
2034 buf += len;
2035 }
2036
2037 return 0;
2038 }