09cd8d57a52daceb1de91ef5ea8ed69239428132
[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 start assigning type IDs at 1 because
33 type ID 0 is used as a sentinel and a not-found indicator. */
34
35 ctf_file_t *
36 ctf_create (int *errp)
37 {
38 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
39
40 ctf_dynhash_t *dthash;
41 ctf_dynhash_t *dvhash;
42 ctf_dynhash_t *dtbyname;
43 ctf_sect_t cts;
44 ctf_file_t *fp;
45
46 libctf_init_debug();
47 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
48 NULL, NULL);
49 if (dthash == NULL)
50 {
51 ctf_set_open_errno (errp, EAGAIN);
52 goto err;
53 }
54
55 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
56 NULL, NULL);
57 if (dvhash == NULL)
58 {
59 ctf_set_open_errno (errp, EAGAIN);
60 goto err_dt;
61 }
62
63 dtbyname = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
64 free, NULL);
65 if (dtbyname == NULL)
66 {
67 ctf_set_open_errno (errp, EAGAIN);
68 goto err_dv;
69 }
70
71 cts.cts_name = _CTF_SECTION;
72 cts.cts_data = &hdr;
73 cts.cts_size = sizeof (hdr);
74 cts.cts_entsize = 1;
75
76 if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
77 goto err_dtbyname;
78
79 fp->ctf_flags |= LCTF_RDWR;
80 fp->ctf_dtbyname = dtbyname;
81 fp->ctf_dthash = dthash;
82 fp->ctf_dvhash = dvhash;
83 fp->ctf_dtnextid = 1;
84 fp->ctf_dtoldid = 0;
85 fp->ctf_snapshots = 1;
86 fp->ctf_snapshot_lu = 0;
87
88 return fp;
89
90 err_dtbyname:
91 ctf_dynhash_destroy (dtbyname);
92 err_dv:
93 ctf_dynhash_destroy (dvhash);
94 err_dt:
95 ctf_dynhash_destroy (dthash);
96 err:
97 return NULL;
98 }
99
100 static unsigned char *
101 ctf_copy_smembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
102 {
103 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
104 ctf_member_t ctm;
105
106 for (; dmd != NULL; dmd = ctf_list_next (dmd))
107 {
108 ctf_member_t *copied;
109
110 ctm.ctm_name = 0;
111 ctm.ctm_type = (uint32_t) dmd->dmd_type;
112 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
113
114 memcpy (t, &ctm, sizeof (ctm));
115 copied = (ctf_member_t *) t;
116 if (dmd->dmd_name)
117 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctm_name);
118
119 t += sizeof (ctm);
120 }
121
122 return t;
123 }
124
125 static unsigned char *
126 ctf_copy_lmembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
127 {
128 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
129 ctf_lmember_t ctlm;
130
131 for (; dmd != NULL; dmd = ctf_list_next (dmd))
132 {
133 ctf_lmember_t *copied;
134
135 ctlm.ctlm_name = 0;
136 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
137 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
138 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
139
140 memcpy (t, &ctlm, sizeof (ctlm));
141 copied = (ctf_lmember_t *) t;
142 if (dmd->dmd_name)
143 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctlm_name);
144
145 t += sizeof (ctlm);
146 }
147
148 return t;
149 }
150
151 static unsigned char *
152 ctf_copy_emembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
153 {
154 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
155 ctf_enum_t cte;
156
157 for (; dmd != NULL; dmd = ctf_list_next (dmd))
158 {
159 ctf_enum_t *copied;
160
161 cte.cte_value = dmd->dmd_value;
162 memcpy (t, &cte, sizeof (cte));
163 copied = (ctf_enum_t *) t;
164 ctf_str_add_ref (fp, dmd->dmd_name, &copied->cte_name);
165 t += sizeof (cte);
166 }
167
168 return t;
169 }
170
171 /* Sort a newly-constructed static variable array. */
172
173 typedef struct ctf_sort_var_arg_cb
174 {
175 ctf_file_t *fp;
176 ctf_strs_t *strtab;
177 } ctf_sort_var_arg_cb_t;
178
179 static int
180 ctf_sort_var (const void *one_, const void *two_, void *arg_)
181 {
182 const ctf_varent_t *one = one_;
183 const ctf_varent_t *two = two_;
184 ctf_sort_var_arg_cb_t *arg = arg_;
185
186 return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
187 ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
188 }
189
190 /* If the specified CTF container is writable and has been modified, reload this
191 container with the updated type definitions. In order to make this code and
192 the rest of libctf as simple as possible, we perform updates by taking the
193 dynamic type definitions and creating an in-memory CTF file containing the
194 definitions, and then call ctf_simple_open_internal() on it. This not only
195 leverages ctf_simple_open(), but also avoids having to bifurcate the rest of
196 the library code with different lookup paths for static and dynamic type
197 definitions. We are therefore optimizing greatly for lookup over update,
198 which we assume will be an uncommon operation. We perform one extra trick
199 here for the benefit of callers and to keep our code simple:
200 ctf_simple_open_internal() will return a new ctf_file_t, but we want to keep
201 the fp constant for the caller, so after ctf_simple_open_internal() returns,
202 we use memcpy to swap the interior of the old and new ctf_file_t's, and then
203 free the old. */
204 int
205 ctf_update (ctf_file_t *fp)
206 {
207 ctf_file_t ofp, *nfp;
208 ctf_header_t hdr, *hdrp;
209 ctf_dtdef_t *dtd;
210 ctf_dvdef_t *dvd;
211 ctf_varent_t *dvarents;
212 ctf_strs_writable_t strtab;
213
214 unsigned char *t;
215 unsigned long i;
216 size_t buf_size, type_size, nvars;
217 unsigned char *buf, *newbuf;
218 int err;
219
220 if (!(fp->ctf_flags & LCTF_RDWR))
221 return (ctf_set_errno (fp, ECTF_RDONLY));
222
223 /* Update required? */
224 if (!(fp->ctf_flags & LCTF_DIRTY))
225 return 0;
226
227 /* Fill in an initial CTF header. We will leave the label, object,
228 and function sections empty and only output a header, type section,
229 and string table. The type section begins at a 4-byte aligned
230 boundary past the CTF header itself (at relative offset zero). */
231
232 memset (&hdr, 0, sizeof (hdr));
233 hdr.cth_magic = CTF_MAGIC;
234 hdr.cth_version = CTF_VERSION;
235
236 /* Iterate through the dynamic type definition list and compute the
237 size of the CTF type section we will need to generate. */
238
239 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
240 dtd != NULL; dtd = ctf_list_next (dtd))
241 {
242 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
243 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
244
245 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
246 type_size += sizeof (ctf_stype_t);
247 else
248 type_size += sizeof (ctf_type_t);
249
250 switch (kind)
251 {
252 case CTF_K_INTEGER:
253 case CTF_K_FLOAT:
254 type_size += sizeof (uint32_t);
255 break;
256 case CTF_K_ARRAY:
257 type_size += sizeof (ctf_array_t);
258 break;
259 case CTF_K_SLICE:
260 type_size += sizeof (ctf_slice_t);
261 break;
262 case CTF_K_FUNCTION:
263 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
264 break;
265 case CTF_K_STRUCT:
266 case CTF_K_UNION:
267 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
268 type_size += sizeof (ctf_member_t) * vlen;
269 else
270 type_size += sizeof (ctf_lmember_t) * vlen;
271 break;
272 case CTF_K_ENUM:
273 type_size += sizeof (ctf_enum_t) * vlen;
274 break;
275 }
276 }
277
278 /* Computing the number of entries in the CTF variable section is much
279 simpler. */
280
281 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
282 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
283
284 /* Compute the size of the CTF buffer we need, sans only the string table,
285 then allocate a new buffer and memcpy the finished header to the start of
286 the buffer. (We will adjust this later with strtab length info.) */
287
288 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
289 hdr.cth_stroff = hdr.cth_typeoff + type_size;
290 hdr.cth_strlen = 0;
291
292 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
293
294 if ((buf = malloc (buf_size)) == NULL)
295 return (ctf_set_errno (fp, EAGAIN));
296
297 memcpy (buf, &hdr, sizeof (ctf_header_t));
298 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff;
299
300 hdrp = (ctf_header_t *) buf;
301 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
302 ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
303 if (fp->ctf_cuname != NULL)
304 ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);
305
306 /* Work over the variable list, translating everything into ctf_varent_t's and
307 prepping the string table. */
308
309 dvarents = (ctf_varent_t *) t;
310 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
311 dvd = ctf_list_next (dvd), i++)
312 {
313 ctf_varent_t *var = &dvarents[i];
314
315 ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
316 var->ctv_type = dvd->dvd_type;
317 }
318 assert (i == nvars);
319
320 t += sizeof (ctf_varent_t) * nvars;
321
322 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
323
324 /* We now take a final lap through the dynamic type definition list and copy
325 the appropriate type records to the output buffer, noting down the
326 strings as we go. */
327
328 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
329 dtd != NULL; dtd = ctf_list_next (dtd))
330 {
331 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
332 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
333
334 ctf_array_t cta;
335 uint32_t encoding;
336 size_t len;
337 ctf_stype_t *copied;
338
339 dtd->dtd_data.ctt_name = 0;
340
341 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
342 len = sizeof (ctf_stype_t);
343 else
344 len = sizeof (ctf_type_t);
345
346 memcpy (t, &dtd->dtd_data, len);
347 copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */
348 if (dtd->dtd_name)
349 ctf_str_add_ref (fp, dtd->dtd_name, &copied->ctt_name);
350 t += len;
351
352 switch (kind)
353 {
354 case CTF_K_INTEGER:
355 case CTF_K_FLOAT:
356 if (kind == CTF_K_INTEGER)
357 {
358 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
359 dtd->dtd_u.dtu_enc.cte_offset,
360 dtd->dtd_u.dtu_enc.cte_bits);
361 }
362 else
363 {
364 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
365 dtd->dtd_u.dtu_enc.cte_offset,
366 dtd->dtd_u.dtu_enc.cte_bits);
367 }
368 memcpy (t, &encoding, sizeof (encoding));
369 t += sizeof (encoding);
370 break;
371
372 case CTF_K_SLICE:
373 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
374 t += sizeof (struct ctf_slice);
375 break;
376
377 case CTF_K_ARRAY:
378 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
379 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
380 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
381 memcpy (t, &cta, sizeof (cta));
382 t += sizeof (cta);
383 break;
384
385 case CTF_K_FUNCTION:
386 {
387 uint32_t *argv = (uint32_t *) (uintptr_t) t;
388 uint32_t argc;
389
390 for (argc = 0; argc < vlen; argc++)
391 *argv++ = (uint32_t) dtd->dtd_u.dtu_argv[argc];
392
393 if (vlen & 1)
394 *argv++ = 0; /* Pad to 4-byte boundary. */
395
396 t = (unsigned char *) argv;
397 break;
398 }
399
400 case CTF_K_STRUCT:
401 case CTF_K_UNION:
402 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
403 t = ctf_copy_smembers (fp, dtd, t);
404 else
405 t = ctf_copy_lmembers (fp, dtd, t);
406 break;
407
408 case CTF_K_ENUM:
409 t = ctf_copy_emembers (fp, dtd, t);
410 break;
411 }
412 }
413 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
414
415 /* Construct the final string table and fill out all the string refs with the
416 final offsets. Then purge the refs list, because we're about to move this
417 strtab onto the end of the buf, invalidating all the offsets. */
418 strtab = ctf_str_write_strtab (fp);
419 ctf_str_purge_refs (fp);
420
421 if (strtab.cts_strs == NULL)
422 {
423 ctf_free (buf);
424 return (ctf_set_errno (fp, EAGAIN));
425 }
426
427 /* Now the string table is constructed, we can sort the buffer of
428 ctf_varent_t's. */
429 ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) &strtab };
430 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
431 &sort_var_arg);
432
433 if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
434 {
435 ctf_free (buf);
436 ctf_free (strtab.cts_strs);
437 return (ctf_set_errno (fp, EAGAIN));
438 }
439 buf = newbuf;
440 memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
441 hdrp = (ctf_header_t *) buf;
442 hdrp->cth_strlen = strtab.cts_len;
443 buf_size += hdrp->cth_strlen;
444 ctf_free (strtab.cts_strs);
445
446 /* Finally, we are ready to ctf_simple_open() the new container. If this
447 is successful, we then switch nfp and fp and free the old container. */
448
449 if ((nfp = ctf_simple_open_internal ((char *) buf, buf_size, NULL, 0,
450 0, NULL, 0, fp->ctf_syn_ext_strtab,
451 &err)) == NULL)
452 {
453 ctf_free (buf);
454 return (ctf_set_errno (fp, err));
455 }
456
457 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
458 (void) ctf_import (nfp, fp->ctf_parent);
459
460 nfp->ctf_refcnt = fp->ctf_refcnt;
461 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
462 if (nfp->ctf_dynbase == NULL)
463 nfp->ctf_dynbase = buf; /* Make sure buf is freed 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_dtnextid = fp->ctf_dtnextid;
470 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
471 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
472 nfp->ctf_specific = fp->ctf_specific;
473 nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
474
475 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
476
477 fp->ctf_dtbyname = NULL;
478 fp->ctf_dthash = NULL;
479 ctf_str_free_atoms (nfp);
480 nfp->ctf_str_atoms = fp->ctf_str_atoms;
481 fp->ctf_str_atoms = NULL;
482 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
483 fp->ctf_syn_ext_strtab = NULL;
484
485 fp->ctf_dvhash = NULL;
486 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
487
488 memcpy (&ofp, fp, sizeof (ctf_file_t));
489 memcpy (fp, nfp, sizeof (ctf_file_t));
490 memcpy (nfp, &ofp, sizeof (ctf_file_t));
491
492 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
493 array of type name prefixes and the corresponding ctf_dynhash to use.
494 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
495
496 fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
497 fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
498 fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
499 fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
500
501 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
502 ctf_file_close (nfp);
503
504 return 0;
505 }
506
507 static char *
508 ctf_prefixed_name (int kind, const char *name)
509 {
510 char *prefixed;
511
512 switch (kind)
513 {
514 case CTF_K_STRUCT:
515 prefixed = ctf_strdup ("struct ");
516 break;
517 case CTF_K_UNION:
518 prefixed = ctf_strdup ("union ");
519 break;
520 case CTF_K_ENUM:
521 prefixed = ctf_strdup ("enum ");
522 break;
523 default:
524 prefixed = ctf_strdup ("");
525 }
526
527 prefixed = ctf_str_append (prefixed, name);
528 return prefixed;
529 }
530
531 int
532 ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
533 {
534 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0)
535 return -1;
536
537 if (dtd->dtd_name)
538 {
539 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
540 if (ctf_dynhash_insert (fp->ctf_dtbyname,
541 ctf_prefixed_name (kind, dtd->dtd_name),
542 dtd) < 0)
543 return -1;
544 }
545 ctf_list_append (&fp->ctf_dtdefs, dtd);
546 return 0;
547 }
548
549 void
550 ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
551 {
552 ctf_dmdef_t *dmd, *nmd;
553 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
554
555 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
556
557 switch (kind)
558 {
559 case CTF_K_STRUCT:
560 case CTF_K_UNION:
561 case CTF_K_ENUM:
562 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
563 dmd != NULL; dmd = nmd)
564 {
565 if (dmd->dmd_name != NULL)
566 ctf_free (dmd->dmd_name);
567 nmd = ctf_list_next (dmd);
568 ctf_free (dmd);
569 }
570 break;
571 case CTF_K_FUNCTION:
572 ctf_free (dtd->dtd_u.dtu_argv);
573 break;
574 }
575
576 if (dtd->dtd_name)
577 {
578 char *name;
579
580 name = ctf_prefixed_name (kind, dtd->dtd_name);
581 ctf_dynhash_remove (fp->ctf_dtbyname, name);
582 free (name);
583 ctf_free (dtd->dtd_name);
584 }
585
586 ctf_list_delete (&fp->ctf_dtdefs, dtd);
587 ctf_free (dtd);
588 }
589
590 ctf_dtdef_t *
591 ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
592 {
593 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
594 }
595
596 static ctf_id_t
597 ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
598 {
599 ctf_dtdef_t *dtd;
600 char *decorated = ctf_prefixed_name (kind, name);
601
602 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
603 free (decorated);
604
605 if (dtd)
606 return dtd->dtd_type;
607
608 return 0;
609 }
610
611 ctf_dtdef_t *
612 ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
613 {
614 ctf_id_t idx;
615
616 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
617 fp = fp->ctf_parent;
618
619 idx = LCTF_TYPE_TO_INDEX(fp, id);
620
621 if (((unsigned long) idx > fp->ctf_typemax) &&
622 ((unsigned long) idx < fp->ctf_dtnextid))
623 return ctf_dtd_lookup (fp, id);
624 return NULL;
625 }
626
627 int
628 ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
629 {
630 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
631 return -1;
632 ctf_list_append (&fp->ctf_dvdefs, dvd);
633 return 0;
634 }
635
636 void
637 ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
638 {
639 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
640 ctf_free (dvd->dvd_name);
641
642 ctf_list_delete (&fp->ctf_dvdefs, dvd);
643 ctf_free (dvd);
644 }
645
646 ctf_dvdef_t *
647 ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
648 {
649 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
650 }
651
652 /* Discard all of the dynamic type definitions and variable definitions that
653 have been added to the container since the last call to ctf_update(). We
654 locate such types by scanning the dtd list and deleting elements that have
655 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
656 by scanning the variable list and deleting elements that have update IDs
657 equal to the current value of the last-update snapshot count (indicating that
658 they were added after the most recent call to ctf_update()). */
659 int
660 ctf_discard (ctf_file_t *fp)
661 {
662 ctf_snapshot_id_t last_update =
663 { fp->ctf_dtoldid,
664 fp->ctf_snapshot_lu + 1 };
665
666 /* Update required? */
667 if (!(fp->ctf_flags & LCTF_DIRTY))
668 return 0;
669
670 return (ctf_rollback (fp, last_update));
671 }
672
673 ctf_snapshot_id_t
674 ctf_snapshot (ctf_file_t *fp)
675 {
676 ctf_snapshot_id_t snapid;
677 snapid.dtd_id = fp->ctf_dtnextid - 1;
678 snapid.snapshot_id = fp->ctf_snapshots++;
679 return snapid;
680 }
681
682 /* Like ctf_discard(), only discards everything after a particular ID. */
683 int
684 ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
685 {
686 ctf_dtdef_t *dtd, *ntd;
687 ctf_dvdef_t *dvd, *nvd;
688
689 if (!(fp->ctf_flags & LCTF_RDWR))
690 return (ctf_set_errno (fp, ECTF_RDONLY));
691
692 if (fp->ctf_dtoldid > id.dtd_id)
693 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
694
695 if (fp->ctf_snapshot_lu >= id.snapshot_id)
696 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
697
698 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
699 {
700 ntd = ctf_list_next (dtd);
701
702 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
703 continue;
704
705 ctf_dtd_delete (fp, dtd);
706 }
707
708 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
709 {
710 nvd = ctf_list_next (dvd);
711
712 if (dvd->dvd_snapshots <= id.snapshot_id)
713 continue;
714
715 ctf_dvd_delete (fp, dvd);
716 }
717
718 fp->ctf_dtnextid = id.dtd_id + 1;
719 fp->ctf_snapshots = id.snapshot_id;
720
721 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
722 fp->ctf_flags &= ~LCTF_DIRTY;
723
724 return 0;
725 }
726
727 static ctf_id_t
728 ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
729 ctf_dtdef_t **rp)
730 {
731 ctf_dtdef_t *dtd;
732 ctf_id_t type;
733 char *s = NULL;
734
735 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
736 return (ctf_set_errno (fp, EINVAL));
737
738 if (!(fp->ctf_flags & LCTF_RDWR))
739 return (ctf_set_errno (fp, ECTF_RDONLY));
740
741 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
742 return (ctf_set_errno (fp, ECTF_FULL));
743
744 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
745 return (ctf_set_errno (fp, ECTF_FULL));
746
747 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
748 return (ctf_set_errno (fp, EAGAIN));
749
750 if (name != NULL && (s = ctf_strdup (name)) == NULL)
751 {
752 ctf_free (dtd);
753 return (ctf_set_errno (fp, EAGAIN));
754 }
755
756 type = fp->ctf_dtnextid++;
757 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
758
759 memset (dtd, 0, sizeof (ctf_dtdef_t));
760 dtd->dtd_name = s;
761 dtd->dtd_type = type;
762
763 if (ctf_dtd_insert (fp, dtd) < 0)
764 {
765 ctf_free (dtd);
766 return CTF_ERR; /* errno is set for us. */
767 }
768 fp->ctf_flags |= LCTF_DIRTY;
769
770 *rp = dtd;
771 return type;
772 }
773
774 /* When encoding integer sizes, we want to convert a byte count in the range
775 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
776 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
777 static size_t
778 clp2 (size_t x)
779 {
780 x--;
781
782 x |= (x >> 1);
783 x |= (x >> 2);
784 x |= (x >> 4);
785 x |= (x >> 8);
786 x |= (x >> 16);
787
788 return (x + 1);
789 }
790
791 static ctf_id_t
792 ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
793 const char *name, const ctf_encoding_t *ep, uint32_t kind)
794 {
795 ctf_dtdef_t *dtd;
796 ctf_id_t type;
797
798 if (ep == NULL)
799 return (ctf_set_errno (fp, EINVAL));
800
801 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
802 return CTF_ERR; /* errno is set for us. */
803
804 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
805 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
806 / CHAR_BIT);
807 dtd->dtd_u.dtu_enc = *ep;
808
809 return type;
810 }
811
812 static ctf_id_t
813 ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
814 {
815 ctf_dtdef_t *dtd;
816 ctf_id_t type;
817 ctf_file_t *tmp = fp;
818
819 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
820 return (ctf_set_errno (fp, EINVAL));
821
822 if (ctf_lookup_by_id (&tmp, ref) == NULL)
823 return CTF_ERR; /* errno is set for us. */
824
825 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
826 return CTF_ERR; /* errno is set for us. */
827
828 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
829 dtd->dtd_data.ctt_type = (uint32_t) ref;
830
831 return type;
832 }
833
834 ctf_id_t
835 ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
836 const ctf_encoding_t *ep)
837 {
838 ctf_dtdef_t *dtd;
839 ctf_id_t type;
840 int kind;
841 const ctf_type_t *tp;
842 ctf_file_t *tmp = fp;
843
844 if (ep == NULL)
845 return (ctf_set_errno (fp, EINVAL));
846
847 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
848 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
849
850 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
851 return (ctf_set_errno (fp, EINVAL));
852
853 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
854 return CTF_ERR; /* errno is set for us. */
855
856 kind = ctf_type_kind_unsliced (tmp, ref);
857 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
858 (kind != CTF_K_ENUM))
859 return (ctf_set_errno (fp, ECTF_NOTINTFP));
860
861 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
862 return CTF_ERR; /* errno is set for us. */
863
864 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
865 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
866 / CHAR_BIT);
867 dtd->dtd_u.dtu_slice.cts_type = ref;
868 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
869 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
870
871 return type;
872 }
873
874 ctf_id_t
875 ctf_add_integer (ctf_file_t *fp, uint32_t flag,
876 const char *name, const ctf_encoding_t *ep)
877 {
878 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
879 }
880
881 ctf_id_t
882 ctf_add_float (ctf_file_t *fp, uint32_t flag,
883 const char *name, const ctf_encoding_t *ep)
884 {
885 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
886 }
887
888 ctf_id_t
889 ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
890 {
891 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
892 }
893
894 ctf_id_t
895 ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
896 {
897 ctf_dtdef_t *dtd;
898 ctf_id_t type;
899 ctf_file_t *tmp = fp;
900
901 if (arp == NULL)
902 return (ctf_set_errno (fp, EINVAL));
903
904 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
905 return CTF_ERR; /* errno is set for us. */
906
907 tmp = fp;
908 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
909 return CTF_ERR; /* errno is set for us. */
910
911 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
912 return CTF_ERR; /* errno is set for us. */
913
914 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
915 dtd->dtd_data.ctt_size = 0;
916 dtd->dtd_u.dtu_arr = *arp;
917
918 return type;
919 }
920
921 int
922 ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
923 {
924 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
925
926 if (!(fp->ctf_flags & LCTF_RDWR))
927 return (ctf_set_errno (fp, ECTF_RDONLY));
928
929 if (dtd == NULL
930 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
931 return (ctf_set_errno (fp, ECTF_BADID));
932
933 fp->ctf_flags |= LCTF_DIRTY;
934 dtd->dtd_u.dtu_arr = *arp;
935
936 return 0;
937 }
938
939 ctf_id_t
940 ctf_add_function (ctf_file_t *fp, uint32_t flag,
941 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
942 {
943 ctf_dtdef_t *dtd;
944 ctf_id_t type;
945 uint32_t vlen;
946 ctf_id_t *vdat = NULL;
947 ctf_file_t *tmp = fp;
948 size_t i;
949
950 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
951 || (ctc->ctc_argc != 0 && argv == NULL))
952 return (ctf_set_errno (fp, EINVAL));
953
954 vlen = ctc->ctc_argc;
955 if (ctc->ctc_flags & CTF_FUNC_VARARG)
956 vlen++; /* Add trailing zero to indicate varargs (see below). */
957
958 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
959 return CTF_ERR; /* errno is set for us. */
960
961 for (i = 0; i < ctc->ctc_argc; i++)
962 {
963 tmp = fp;
964 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
965 return CTF_ERR; /* errno is set for us. */
966 }
967
968 if (vlen > CTF_MAX_VLEN)
969 return (ctf_set_errno (fp, EOVERFLOW));
970
971 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
972 return (ctf_set_errno (fp, EAGAIN));
973
974 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
975 {
976 ctf_free (vdat);
977 return CTF_ERR; /* errno is set for us. */
978 }
979
980 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
981 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
982
983 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
984 if (ctc->ctc_flags & CTF_FUNC_VARARG)
985 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
986 dtd->dtd_u.dtu_argv = vdat;
987
988 return type;
989 }
990
991 ctf_id_t
992 ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
993 size_t size)
994 {
995 ctf_hash_t *hp = fp->ctf_structs;
996 ctf_dtdef_t *dtd;
997 ctf_id_t type = 0;
998
999 /* Promote forwards to structs. */
1000
1001 if (name != NULL)
1002 {
1003 type = ctf_hash_lookup_type (hp, fp, name);
1004 if (type == 0)
1005 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
1006 }
1007
1008 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1009 dtd = ctf_dtd_lookup (fp, type);
1010 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1011 return CTF_ERR; /* errno is set for us. */
1012
1013 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1014
1015 if (size > CTF_MAX_SIZE)
1016 {
1017 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1018 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1019 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1020 }
1021 else
1022 dtd->dtd_data.ctt_size = (uint32_t) size;
1023
1024 return type;
1025 }
1026
1027 ctf_id_t
1028 ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1029 {
1030 return (ctf_add_struct_sized (fp, flag, name, 0));
1031 }
1032
1033 ctf_id_t
1034 ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1035 size_t size)
1036 {
1037 ctf_hash_t *hp = fp->ctf_unions;
1038 ctf_dtdef_t *dtd;
1039 ctf_id_t type = 0;
1040
1041 /* Promote forwards to unions. */
1042 if (name != NULL)
1043 {
1044 type = ctf_hash_lookup_type (hp, fp, name);
1045 if (type == 0)
1046 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1047 }
1048
1049 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1050 dtd = ctf_dtd_lookup (fp, type);
1051 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1052 return CTF_ERR; /* errno is set for us */
1053
1054 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1055
1056 if (size > CTF_MAX_SIZE)
1057 {
1058 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1059 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1060 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1061 }
1062 else
1063 dtd->dtd_data.ctt_size = (uint32_t) size;
1064
1065 return type;
1066 }
1067
1068 ctf_id_t
1069 ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1070 {
1071 return (ctf_add_union_sized (fp, flag, name, 0));
1072 }
1073
1074 ctf_id_t
1075 ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1076 {
1077 ctf_hash_t *hp = fp->ctf_enums;
1078 ctf_dtdef_t *dtd;
1079 ctf_id_t type = 0;
1080
1081 /* Promote forwards to enums. */
1082 if (name != NULL)
1083 {
1084 type = ctf_hash_lookup_type (hp, fp, name);
1085 if (type == 0)
1086 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1087 }
1088
1089 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1090 dtd = ctf_dtd_lookup (fp, type);
1091 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1092 return CTF_ERR; /* errno is set for us. */
1093
1094 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1095 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1096
1097 return type;
1098 }
1099
1100 ctf_id_t
1101 ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1102 const ctf_encoding_t *ep)
1103 {
1104 ctf_hash_t *hp = fp->ctf_enums;
1105 ctf_id_t type = 0;
1106
1107 /* First, create the enum if need be, using most of the same machinery as
1108 ctf_add_enum(), to ensure that we do not allow things past that are not
1109 enums or forwards to them. (This includes other slices: you cannot slice a
1110 slice, which would be a useless thing to do anyway.) */
1111
1112 if (name != NULL)
1113 {
1114 type = ctf_hash_lookup_type (hp, fp, name);
1115 if (type == 0)
1116 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1117 }
1118
1119 if (type != 0)
1120 {
1121 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1122 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1123 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1124 }
1125 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1126 return CTF_ERR; /* errno is set for us. */
1127
1128 /* Now attach a suitable slice to it. */
1129
1130 return ctf_add_slice (fp, flag, type, ep);
1131 }
1132
1133 ctf_id_t
1134 ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1135 uint32_t kind)
1136 {
1137 ctf_hash_t *hp;
1138 ctf_dtdef_t *dtd;
1139 ctf_id_t type = 0;
1140
1141 switch (kind)
1142 {
1143 case CTF_K_STRUCT:
1144 hp = fp->ctf_structs;
1145 break;
1146 case CTF_K_UNION:
1147 hp = fp->ctf_unions;
1148 break;
1149 case CTF_K_ENUM:
1150 hp = fp->ctf_enums;
1151 break;
1152 default:
1153 return (ctf_set_errno (fp, ECTF_NOTSUE));
1154 }
1155
1156 /* If the type is already defined or exists as a forward tag, just
1157 return the ctf_id_t of the existing definition. */
1158
1159 if (name != NULL)
1160 {
1161 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1162 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1163 return type;
1164 }
1165
1166 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1167 return CTF_ERR; /* errno is set for us. */
1168
1169 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1170 dtd->dtd_data.ctt_type = kind;
1171
1172 return type;
1173 }
1174
1175 ctf_id_t
1176 ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1177 ctf_id_t ref)
1178 {
1179 ctf_dtdef_t *dtd;
1180 ctf_id_t type;
1181 ctf_file_t *tmp = fp;
1182
1183 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1184 return (ctf_set_errno (fp, EINVAL));
1185
1186 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1187 return CTF_ERR; /* errno is set for us. */
1188
1189 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1190 return CTF_ERR; /* errno is set for us. */
1191
1192 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1193 dtd->dtd_data.ctt_type = (uint32_t) ref;
1194
1195 return type;
1196 }
1197
1198 ctf_id_t
1199 ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1200 {
1201 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1202 }
1203
1204 ctf_id_t
1205 ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1206 {
1207 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1208 }
1209
1210 ctf_id_t
1211 ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1212 {
1213 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1214 }
1215
1216 int
1217 ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1218 int value)
1219 {
1220 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1221 ctf_dmdef_t *dmd;
1222
1223 uint32_t kind, vlen, root;
1224 char *s;
1225
1226 if (name == NULL)
1227 return (ctf_set_errno (fp, EINVAL));
1228
1229 if (!(fp->ctf_flags & LCTF_RDWR))
1230 return (ctf_set_errno (fp, ECTF_RDONLY));
1231
1232 if (dtd == NULL)
1233 return (ctf_set_errno (fp, ECTF_BADID));
1234
1235 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1236 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1237 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1238
1239 if (kind != CTF_K_ENUM)
1240 return (ctf_set_errno (fp, ECTF_NOTENUM));
1241
1242 if (vlen == CTF_MAX_VLEN)
1243 return (ctf_set_errno (fp, ECTF_DTFULL));
1244
1245 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1246 dmd != NULL; dmd = ctf_list_next (dmd))
1247 {
1248 if (strcmp (dmd->dmd_name, name) == 0)
1249 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1250 }
1251
1252 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1253 return (ctf_set_errno (fp, EAGAIN));
1254
1255 if ((s = ctf_strdup (name)) == NULL)
1256 {
1257 ctf_free (dmd);
1258 return (ctf_set_errno (fp, EAGAIN));
1259 }
1260
1261 dmd->dmd_name = s;
1262 dmd->dmd_type = CTF_ERR;
1263 dmd->dmd_offset = 0;
1264 dmd->dmd_value = value;
1265
1266 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1267 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1268
1269 fp->ctf_flags |= LCTF_DIRTY;
1270
1271 return 0;
1272 }
1273
1274 int
1275 ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1276 ctf_id_t type, unsigned long bit_offset)
1277 {
1278 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1279 ctf_dmdef_t *dmd;
1280
1281 ssize_t msize, malign, ssize;
1282 uint32_t kind, vlen, root;
1283 char *s = NULL;
1284
1285 if (!(fp->ctf_flags & LCTF_RDWR))
1286 return (ctf_set_errno (fp, ECTF_RDONLY));
1287
1288 if (dtd == NULL)
1289 return (ctf_set_errno (fp, ECTF_BADID));
1290
1291 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1292 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1293 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1294
1295 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1296 return (ctf_set_errno (fp, ECTF_NOTSOU));
1297
1298 if (vlen == CTF_MAX_VLEN)
1299 return (ctf_set_errno (fp, ECTF_DTFULL));
1300
1301 if (name != NULL)
1302 {
1303 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1304 dmd != NULL; dmd = ctf_list_next (dmd))
1305 {
1306 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1307 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1308 }
1309 }
1310
1311 if ((msize = ctf_type_size (fp, type)) < 0 ||
1312 (malign = ctf_type_align (fp, type)) < 0)
1313 return -1; /* errno is set for us. */
1314
1315 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1316 return (ctf_set_errno (fp, EAGAIN));
1317
1318 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1319 {
1320 ctf_free (dmd);
1321 return (ctf_set_errno (fp, EAGAIN));
1322 }
1323
1324 dmd->dmd_name = s;
1325 dmd->dmd_type = type;
1326 dmd->dmd_value = -1;
1327
1328 if (kind == CTF_K_STRUCT && vlen != 0)
1329 {
1330 if (bit_offset == (unsigned long) - 1)
1331 {
1332 /* Natural alignment. */
1333
1334 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1335 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1336 size_t off = lmd->dmd_offset;
1337
1338 ctf_encoding_t linfo;
1339 ssize_t lsize;
1340
1341 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1342 off += linfo.cte_bits;
1343 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1344 off += lsize * CHAR_BIT;
1345
1346 /* Round up the offset of the end of the last member to
1347 the next byte boundary, convert 'off' to bytes, and
1348 then round it up again to the next multiple of the
1349 alignment required by the new member. Finally,
1350 convert back to bits and store the result in
1351 dmd_offset. Technically we could do more efficient
1352 packing if the new member is a bit-field, but we're
1353 the "compiler" and ANSI says we can do as we choose. */
1354
1355 off = roundup (off, CHAR_BIT) / CHAR_BIT;
1356 off = roundup (off, MAX (malign, 1));
1357 dmd->dmd_offset = off * CHAR_BIT;
1358 ssize = off + msize;
1359 }
1360 else
1361 {
1362 /* Specified offset in bits. */
1363
1364 dmd->dmd_offset = bit_offset;
1365 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1366 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1367 }
1368 }
1369 else
1370 {
1371 dmd->dmd_offset = 0;
1372 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1373 ssize = MAX (ssize, msize);
1374 }
1375
1376 if ((size_t) ssize > CTF_MAX_SIZE)
1377 {
1378 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1379 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1380 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1381 }
1382 else
1383 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1384
1385 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1386 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
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 if (ctf_dvd_insert (fp, dvd) < 0)
1444 {
1445 ctf_free (dvd);
1446 return -1; /* errno is set for us. */
1447 }
1448
1449 fp->ctf_flags |= LCTF_DIRTY;
1450 return 0;
1451 }
1452
1453 static int
1454 enumcmp (const char *name, int value, void *arg)
1455 {
1456 ctf_bundle_t *ctb = arg;
1457 int bvalue;
1458
1459 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
1460 {
1461 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1462 return 1;
1463 }
1464 if (value != bvalue)
1465 {
1466 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1467 value, bvalue);
1468 return 1;
1469 }
1470 return 0;
1471 }
1472
1473 static int
1474 enumadd (const char *name, int value, void *arg)
1475 {
1476 ctf_bundle_t *ctb = arg;
1477
1478 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
1479 name, value) < 0);
1480 }
1481
1482 static int
1483 membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1484 void *arg)
1485 {
1486 ctf_bundle_t *ctb = arg;
1487 ctf_membinfo_t ctm;
1488
1489 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
1490 {
1491 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1492 return 1;
1493 }
1494 if (ctm.ctm_offset != offset)
1495 {
1496 ctf_dprintf ("Conflict due to member %s offset change: "
1497 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1498 return 1;
1499 }
1500 return 0;
1501 }
1502
1503 static int
1504 membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1505 {
1506 ctf_bundle_t *ctb = arg;
1507 ctf_dmdef_t *dmd;
1508 char *s = NULL;
1509
1510 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1511 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1512
1513 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1514 {
1515 ctf_free (dmd);
1516 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1517 }
1518
1519 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1520 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1521 dmd->dmd_name = s;
1522 dmd->dmd_type = type;
1523 dmd->dmd_offset = offset;
1524 dmd->dmd_value = -1;
1525
1526 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
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 %li, new %li\n",
1824 name, dst_type,
1825 (long) ctf_type_size (src_fp, src_type),
1826 (long) ctf_type_size (dst_fp, dst_type));
1827 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1828 }
1829
1830 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1831 {
1832 ctf_dprintf ("Conflict for type %s against ID %lx: "
1833 "members differ, see above\n", name, dst_type);
1834 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1835 }
1836
1837 break;
1838 }
1839
1840 /* Unlike the other cases, copying structs and unions is done
1841 manually so as to avoid repeated lookups in ctf_add_member
1842 and to ensure the exact same member offsets as in src_type. */
1843
1844 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1845 if (dst_type == CTF_ERR)
1846 return CTF_ERR; /* errno is set for us. */
1847
1848 dst.ctb_type = dst_type;
1849 dst.ctb_dtd = dtd;
1850
1851 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1852 errs++; /* Increment errs and fail at bottom of case. */
1853
1854 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1855 return CTF_ERR; /* errno is set for us. */
1856
1857 size = (size_t) ssize;
1858 if (size > CTF_MAX_SIZE)
1859 {
1860 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1861 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1862 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1863 }
1864 else
1865 dtd->dtd_data.ctt_size = (uint32_t) size;
1866
1867 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1868
1869 /* Make a final pass through the members changing each dmd_type (a
1870 src_fp type) to an equivalent type in dst_fp. We pass through all
1871 members, leaving any that fail set to CTF_ERR. */
1872 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1873 dmd != NULL; dmd = ctf_list_next (dmd))
1874 {
1875 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1876 dmd->dmd_type)) == CTF_ERR)
1877 errs++;
1878 }
1879
1880 if (errs)
1881 return CTF_ERR; /* errno is set for us. */
1882 break;
1883 }
1884
1885 case CTF_K_ENUM:
1886 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1887 {
1888 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1889 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1890 {
1891 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1892 "members differ, see above\n", name, dst_type);
1893 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1894 }
1895 }
1896 else
1897 {
1898 dst_type = ctf_add_enum (dst_fp, flag, name);
1899 if ((dst.ctb_type = dst_type) == CTF_ERR
1900 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1901 return CTF_ERR; /* errno is set for us */
1902 }
1903 break;
1904
1905 case CTF_K_FORWARD:
1906 if (dst_type == CTF_ERR)
1907 {
1908 dst_type = ctf_add_forward (dst_fp, flag,
1909 name, CTF_K_STRUCT); /* Assume STRUCT. */
1910 }
1911 break;
1912
1913 case CTF_K_TYPEDEF:
1914 src_type = ctf_type_reference (src_fp, src_type);
1915 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1916
1917 if (src_type == CTF_ERR)
1918 return CTF_ERR; /* errno is set for us. */
1919
1920 /* If dst_type is not CTF_ERR at this point, we should check if
1921 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1922 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1923 that vary based on things like if 32-bit then pid_t is int otherwise
1924 long. We therefore omit this check and assume that if the identically
1925 named typedef already exists in dst_fp, it is correct or
1926 equivalent. */
1927
1928 if (dst_type == CTF_ERR)
1929 {
1930 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1931 }
1932 break;
1933
1934 default:
1935 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1936 }
1937
1938 return dst_type;
1939 }
1940
1941 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1942 int
1943 ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1944 {
1945 const unsigned char *buf;
1946 ssize_t resid;
1947 ssize_t len;
1948
1949 resid = sizeof (ctf_header_t);
1950 buf = (unsigned char *) fp->ctf_header;
1951 while (resid != 0)
1952 {
1953 if ((len = gzwrite (fd, buf, resid)) <= 0)
1954 return (ctf_set_errno (fp, errno));
1955 resid -= len;
1956 buf += len;
1957 }
1958
1959 resid = fp->ctf_size;
1960 buf = fp->ctf_buf;
1961 while (resid != 0)
1962 {
1963 if ((len = gzwrite (fd, buf, resid)) <= 0)
1964 return (ctf_set_errno (fp, errno));
1965 resid -= len;
1966 buf += len;
1967 }
1968
1969 return 0;
1970 }
1971
1972 /* Compress the specified CTF data stream and write it to the specified file
1973 descriptor. */
1974 int
1975 ctf_compress_write (ctf_file_t *fp, int fd)
1976 {
1977 unsigned char *buf;
1978 unsigned char *bp;
1979 ctf_header_t h;
1980 ctf_header_t *hp = &h;
1981 ssize_t header_len = sizeof (ctf_header_t);
1982 ssize_t compress_len;
1983 size_t max_compress_len = compressBound (fp->ctf_size);
1984 ssize_t len;
1985 int rc;
1986 int err = 0;
1987
1988 memcpy (hp, fp->ctf_header, header_len);
1989 hp->cth_flags |= CTF_F_COMPRESS;
1990
1991 if ((buf = ctf_alloc (max_compress_len)) == NULL)
1992 return (ctf_set_errno (fp, ECTF_ZALLOC));
1993
1994 compress_len = max_compress_len;
1995 if ((rc = compress (buf, (uLongf *) &compress_len,
1996 fp->ctf_buf, fp->ctf_size)) != Z_OK)
1997 {
1998 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
1999 err = ctf_set_errno (fp, ECTF_COMPRESS);
2000 ctf_free (buf);
2001 goto ret;
2002 }
2003
2004 while (header_len > 0)
2005 {
2006 if ((len = write (fd, hp, header_len)) < 0)
2007 {
2008 err = ctf_set_errno (fp, errno);
2009 goto ret;
2010 }
2011 header_len -= len;
2012 hp += len;
2013 }
2014
2015 bp = buf;
2016 while (compress_len > 0)
2017 {
2018 if ((len = write (fd, bp, compress_len)) < 0)
2019 {
2020 err = ctf_set_errno (fp, errno);
2021 goto ret;
2022 }
2023 compress_len -= len;
2024 bp += len;
2025 }
2026
2027 ret:
2028 ctf_free (buf);
2029 return err;
2030 }
2031
2032 /* Optionally compress the specified CTF data stream and return it as a new
2033 dynamically-allocated string. */
2034 unsigned char *
2035 ctf_write_mem (ctf_file_t *fp, size_t *size, size_t threshold)
2036 {
2037 unsigned char *buf;
2038 unsigned char *bp;
2039 ctf_header_t *hp;
2040 ssize_t header_len = sizeof (ctf_header_t);
2041 ssize_t compress_len;
2042 size_t max_compress_len = compressBound (fp->ctf_size);
2043 int rc;
2044
2045 if (fp->ctf_size < threshold)
2046 max_compress_len = fp->ctf_size;
2047 if ((buf = malloc (max_compress_len
2048 + sizeof (struct ctf_header))) == NULL)
2049 {
2050 ctf_set_errno (fp, ENOMEM);
2051 return NULL;
2052 }
2053
2054 hp = (ctf_header_t *) buf;
2055 memcpy (hp, fp->ctf_header, header_len);
2056 bp = buf + sizeof (struct ctf_header);
2057 *size = sizeof (struct ctf_header);
2058
2059 compress_len = max_compress_len;
2060
2061 if (fp->ctf_size < threshold)
2062 {
2063 hp->cth_flags &= ~CTF_F_COMPRESS;
2064 memcpy (bp, fp->ctf_buf, fp->ctf_size);
2065 *size += fp->ctf_size;
2066 }
2067 else
2068 {
2069 hp->cth_flags |= CTF_F_COMPRESS;
2070 if ((rc = compress (bp, (uLongf *) &compress_len,
2071 fp->ctf_buf, fp->ctf_size)) != Z_OK)
2072 {
2073 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2074 ctf_set_errno (fp, ECTF_COMPRESS);
2075 ctf_free (buf);
2076 return NULL;
2077 }
2078 *size += compress_len;
2079 }
2080 return buf;
2081 }
2082
2083 /* Write the uncompressed CTF data stream to the specified file descriptor. */
2084 int
2085 ctf_write (ctf_file_t *fp, int fd)
2086 {
2087 const unsigned char *buf;
2088 ssize_t resid;
2089 ssize_t len;
2090
2091 resid = sizeof (ctf_header_t);
2092 buf = (unsigned char *) fp->ctf_header;
2093 while (resid != 0)
2094 {
2095 if ((len = write (fd, buf, resid)) <= 0)
2096 return (ctf_set_errno (fp, errno));
2097 resid -= len;
2098 buf += len;
2099 }
2100
2101 resid = fp->ctf_size;
2102 buf = fp->ctf_buf;
2103 while (resid != 0)
2104 {
2105 if ((len = write (fd, buf, resid)) <= 0)
2106 return (ctf_set_errno (fp, errno));
2107 resid -= len;
2108 buf += len;
2109 }
2110
2111 return 0;
2112 }
This page took 0.069138 seconds and 3 git commands to generate.