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