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