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