2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
21 #include <sys/param.h>
27 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
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. */
36 ctf_create (int *errp
)
38 static const ctf_header_t hdr
= { .cth_preamble
= { CTF_MAGIC
, CTF_VERSION
, 0 } };
40 ctf_dynhash_t
*dthash
;
41 ctf_dynhash_t
*dvhash
;
42 ctf_dynhash_t
*dtbyname
;
47 dthash
= ctf_dynhash_create (ctf_hash_integer
, ctf_hash_eq_integer
,
51 ctf_set_open_errno (errp
, EAGAIN
);
55 dvhash
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
59 ctf_set_open_errno (errp
, EAGAIN
);
63 dtbyname
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
67 ctf_set_open_errno (errp
, EAGAIN
);
71 cts
.cts_name
= _CTF_SECTION
;
73 cts
.cts_size
= sizeof (hdr
);
76 if ((fp
= ctf_bufopen (&cts
, NULL
, NULL
, errp
)) == NULL
)
79 fp
->ctf_flags
|= LCTF_RDWR
;
80 fp
->ctf_dtbyname
= dtbyname
;
81 fp
->ctf_dthash
= dthash
;
82 fp
->ctf_dvhash
= dvhash
;
85 fp
->ctf_snapshots
= 1;
86 fp
->ctf_snapshot_lu
= 0;
91 ctf_dynhash_destroy (dtbyname
);
93 ctf_dynhash_destroy (dvhash
);
95 ctf_dynhash_destroy (dthash
);
100 static unsigned char *
101 ctf_copy_smembers (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
103 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
106 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
108 ctf_member_t
*copied
;
111 ctm
.ctm_type
= (uint32_t) dmd
->dmd_type
;
112 ctm
.ctm_offset
= (uint32_t) dmd
->dmd_offset
;
114 memcpy (t
, &ctm
, sizeof (ctm
));
115 copied
= (ctf_member_t
*) t
;
117 ctf_str_add_ref (fp
, dmd
->dmd_name
, &copied
->ctm_name
);
125 static unsigned char *
126 ctf_copy_lmembers (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
128 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
131 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
133 ctf_lmember_t
*copied
;
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
);
140 memcpy (t
, &ctlm
, sizeof (ctlm
));
141 copied
= (ctf_lmember_t
*) t
;
143 ctf_str_add_ref (fp
, dmd
->dmd_name
, &copied
->ctlm_name
);
151 static unsigned char *
152 ctf_copy_emembers (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
154 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
157 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
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
);
171 /* Sort a newly-constructed static variable array. */
173 typedef struct ctf_sort_var_arg_cb
177 } ctf_sort_var_arg_cb_t
;
180 ctf_sort_var (const void *one_
, const void *two_
, void *arg_
)
182 const ctf_varent_t
*one
= one_
;
183 const ctf_varent_t
*two
= two_
;
184 ctf_sort_var_arg_cb_t
*arg
= arg_
;
186 return (strcmp (ctf_strraw_explicit (arg
->fp
, one
->ctv_name
, arg
->strtab
),
187 ctf_strraw_explicit (arg
->fp
, two
->ctv_name
, arg
->strtab
)));
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
205 ctf_update (ctf_file_t
*fp
)
207 ctf_file_t ofp
, *nfp
;
208 ctf_header_t hdr
, *hdrp
;
211 ctf_varent_t
*dvarents
;
212 ctf_strs_writable_t strtab
;
216 size_t buf_size
, type_size
, nvars
;
217 unsigned char *buf
, *newbuf
;
220 if (!(fp
->ctf_flags
& LCTF_RDWR
))
221 return (ctf_set_errno (fp
, ECTF_RDONLY
));
223 /* Update required? */
224 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
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). */
232 memset (&hdr
, 0, sizeof (hdr
));
233 hdr
.cth_magic
= CTF_MAGIC
;
234 hdr
.cth_version
= CTF_VERSION
;
236 /* Iterate through the dynamic type definition list and compute the
237 size of the CTF type section we will need to generate. */
239 for (type_size
= 0, dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
240 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
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
);
245 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
246 type_size
+= sizeof (ctf_stype_t
);
248 type_size
+= sizeof (ctf_type_t
);
254 type_size
+= sizeof (uint32_t);
257 type_size
+= sizeof (ctf_array_t
);
260 type_size
+= sizeof (ctf_slice_t
);
263 type_size
+= sizeof (uint32_t) * (vlen
+ (vlen
& 1));
267 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
268 type_size
+= sizeof (ctf_member_t
) * vlen
;
270 type_size
+= sizeof (ctf_lmember_t
) * vlen
;
273 type_size
+= sizeof (ctf_enum_t
) * vlen
;
278 /* Computing the number of entries in the CTF variable section is much
281 for (nvars
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
282 dvd
!= NULL
; dvd
= ctf_list_next (dvd
), nvars
++);
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.) */
288 hdr
.cth_typeoff
= hdr
.cth_varoff
+ (nvars
* sizeof (ctf_varent_t
));
289 hdr
.cth_stroff
= hdr
.cth_typeoff
+ type_size
;
292 buf_size
= sizeof (ctf_header_t
) + hdr
.cth_stroff
+ hdr
.cth_strlen
;
294 if ((buf
= malloc (buf_size
)) == NULL
)
295 return (ctf_set_errno (fp
, EAGAIN
));
297 memcpy (buf
, &hdr
, sizeof (ctf_header_t
));
298 t
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_varoff
;
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
);
306 /* Work over the variable list, translating everything into ctf_varent_t's and
307 prepping the string table. */
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
++)
313 ctf_varent_t
*var
= &dvarents
[i
];
315 ctf_str_add_ref (fp
, dvd
->dvd_name
, &var
->ctv_name
);
316 var
->ctv_type
= dvd
->dvd_type
;
320 t
+= sizeof (ctf_varent_t
) * nvars
;
322 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_typeoff
);
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
328 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
329 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
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
);
339 dtd
->dtd_data
.ctt_name
= 0;
341 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
342 len
= sizeof (ctf_stype_t
);
344 len
= sizeof (ctf_type_t
);
346 memcpy (t
, &dtd
->dtd_data
, len
);
347 copied
= (ctf_stype_t
*) t
; /* name is at the start: constant offset. */
349 ctf_str_add_ref (fp
, dtd
->dtd_name
, &copied
->ctt_name
);
356 if (kind
== CTF_K_INTEGER
)
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
);
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
);
368 memcpy (t
, &encoding
, sizeof (encoding
));
369 t
+= sizeof (encoding
);
373 memcpy (t
, &dtd
->dtd_u
.dtu_slice
, sizeof (struct ctf_slice
));
374 t
+= sizeof (struct ctf_slice
);
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
));
387 uint32_t *argv
= (uint32_t *) (uintptr_t) t
;
390 for (argc
= 0; argc
< vlen
; argc
++)
391 *argv
++ = (uint32_t) dtd
->dtd_u
.dtu_argv
[argc
];
394 *argv
++ = 0; /* Pad to 4-byte boundary. */
396 t
= (unsigned char *) argv
;
402 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
403 t
= ctf_copy_smembers (fp
, dtd
, t
);
405 t
= ctf_copy_lmembers (fp
, dtd
, t
);
409 t
= ctf_copy_emembers (fp
, dtd
, t
);
413 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
);
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
);
421 if (strtab
.cts_strs
== NULL
)
424 return (ctf_set_errno (fp
, EAGAIN
));
427 /* Now the string table is constructed, we can sort the buffer of
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
,
433 if ((newbuf
= ctf_realloc (fp
, buf
, buf_size
+ strtab
.cts_len
)) == NULL
)
436 ctf_free (strtab
.cts_strs
);
437 return (ctf_set_errno (fp
, EAGAIN
));
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
);
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. */
449 if ((nfp
= ctf_simple_open_internal ((char *) buf
, buf_size
, NULL
, 0,
450 0, NULL
, 0, fp
->ctf_syn_ext_strtab
,
454 return (ctf_set_errno (fp
, err
));
457 (void) ctf_setmodel (nfp
, ctf_getmodel (fp
));
458 (void) ctf_import (nfp
, fp
->ctf_parent
);
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
;
481 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
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
;
495 fp
->ctf_dvhash
= NULL
;
496 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
498 memcpy (&ofp
, fp
, sizeof (ctf_file_t
));
499 memcpy (fp
, nfp
, sizeof (ctf_file_t
));
500 memcpy (nfp
, &ofp
, sizeof (ctf_file_t
));
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(). */
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
;
511 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
512 ctf_file_close (nfp
);
518 ctf_prefixed_name (int kind
, const char *name
)
525 prefixed
= ctf_strdup ("struct ");
528 prefixed
= ctf_strdup ("union ");
531 prefixed
= ctf_strdup ("enum ");
534 prefixed
= ctf_strdup ("");
537 prefixed
= ctf_str_append (prefixed
, name
);
542 ctf_dtd_insert (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
544 if (ctf_dynhash_insert (fp
->ctf_dthash
, (void *) dtd
->dtd_type
, dtd
) < 0)
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
),
555 ctf_list_append (&fp
->ctf_dtdefs
, dtd
);
560 ctf_dtd_delete (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
562 ctf_dmdef_t
*dmd
, *nmd
;
563 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
565 ctf_dynhash_remove (fp
->ctf_dthash
, (void *) dtd
->dtd_type
);
572 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
573 dmd
!= NULL
; dmd
= nmd
)
575 if (dmd
->dmd_name
!= NULL
)
576 ctf_free (dmd
->dmd_name
);
577 nmd
= ctf_list_next (dmd
);
582 ctf_free (dtd
->dtd_u
.dtu_argv
);
590 name
= ctf_prefixed_name (kind
, dtd
->dtd_name
);
591 ctf_dynhash_remove (fp
->ctf_dtbyname
, name
);
593 ctf_free (dtd
->dtd_name
);
596 ctf_list_delete (&fp
->ctf_dtdefs
, dtd
);
601 ctf_dtd_lookup (const ctf_file_t
*fp
, ctf_id_t type
)
603 return (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dthash
, (void *) type
);
607 ctf_dtd_lookup_type_by_name (ctf_file_t
*fp
, int kind
, const char *name
)
610 char *decorated
= ctf_prefixed_name (kind
, name
);
612 dtd
= (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dtbyname
, decorated
);
616 return dtd
->dtd_type
;
622 ctf_dynamic_type (const ctf_file_t
*fp
, ctf_id_t id
)
626 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, id
))
629 idx
= LCTF_TYPE_TO_INDEX(fp
, id
);
631 if (((unsigned long) idx
> fp
->ctf_typemax
) &&
632 ((unsigned long) idx
< fp
->ctf_dtnextid
))
633 return ctf_dtd_lookup (fp
, id
);
638 ctf_dvd_insert (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
640 if (ctf_dynhash_insert (fp
->ctf_dvhash
, dvd
->dvd_name
, dvd
) < 0)
642 ctf_list_append (&fp
->ctf_dvdefs
, dvd
);
647 ctf_dvd_delete (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
649 ctf_dynhash_remove (fp
->ctf_dvhash
, dvd
->dvd_name
);
650 ctf_free (dvd
->dvd_name
);
652 ctf_list_delete (&fp
->ctf_dvdefs
, dvd
);
657 ctf_dvd_lookup (const ctf_file_t
*fp
, const char *name
)
659 return (ctf_dvdef_t
*) ctf_dynhash_lookup (fp
->ctf_dvhash
, name
);
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()). */
670 ctf_discard (ctf_file_t
*fp
)
672 ctf_snapshot_id_t last_update
=
674 fp
->ctf_snapshot_lu
+ 1 };
676 /* Update required? */
677 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
680 return (ctf_rollback (fp
, last_update
));
684 ctf_snapshot (ctf_file_t
*fp
)
686 ctf_snapshot_id_t snapid
;
687 snapid
.dtd_id
= fp
->ctf_dtnextid
- 1;
688 snapid
.snapshot_id
= fp
->ctf_snapshots
++;
692 /* Like ctf_discard(), only discards everything after a particular ID. */
694 ctf_rollback (ctf_file_t
*fp
, ctf_snapshot_id_t id
)
696 ctf_dtdef_t
*dtd
, *ntd
;
697 ctf_dvdef_t
*dvd
, *nvd
;
699 if (!(fp
->ctf_flags
& LCTF_RDWR
))
700 return (ctf_set_errno (fp
, ECTF_RDONLY
));
702 if (fp
->ctf_dtoldid
> id
.dtd_id
)
703 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
705 if (fp
->ctf_snapshot_lu
>= id
.snapshot_id
)
706 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
708 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
); dtd
!= NULL
; dtd
= ntd
)
710 ntd
= ctf_list_next (dtd
);
712 if (LCTF_TYPE_TO_INDEX (fp
, dtd
->dtd_type
) <= id
.dtd_id
)
715 ctf_dtd_delete (fp
, dtd
);
718 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
720 nvd
= ctf_list_next (dvd
);
722 if (dvd
->dvd_snapshots
<= id
.snapshot_id
)
725 ctf_dvd_delete (fp
, dvd
);
728 fp
->ctf_dtnextid
= id
.dtd_id
+ 1;
729 fp
->ctf_snapshots
= id
.snapshot_id
;
731 if (fp
->ctf_snapshots
== fp
->ctf_snapshot_lu
)
732 fp
->ctf_flags
&= ~LCTF_DIRTY
;
738 ctf_add_generic (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
745 if (flag
!= CTF_ADD_NONROOT
&& flag
!= CTF_ADD_ROOT
)
746 return (ctf_set_errno (fp
, EINVAL
));
748 if (!(fp
->ctf_flags
& LCTF_RDWR
))
749 return (ctf_set_errno (fp
, ECTF_RDONLY
));
751 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) > CTF_MAX_TYPE
)
752 return (ctf_set_errno (fp
, ECTF_FULL
));
754 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) == CTF_MAX_PTYPE
)
755 return (ctf_set_errno (fp
, ECTF_FULL
));
757 if ((dtd
= ctf_alloc (sizeof (ctf_dtdef_t
))) == NULL
)
758 return (ctf_set_errno (fp
, EAGAIN
));
760 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
763 return (ctf_set_errno (fp
, EAGAIN
));
766 type
= fp
->ctf_dtnextid
++;
767 type
= LCTF_INDEX_TO_TYPE (fp
, type
, (fp
->ctf_flags
& LCTF_CHILD
));
769 memset (dtd
, 0, sizeof (ctf_dtdef_t
));
771 dtd
->dtd_type
= type
;
773 if (ctf_dtd_insert (fp
, dtd
) < 0)
776 return CTF_ERR
; /* errno is set for us. */
778 fp
->ctf_flags
|= LCTF_DIRTY
;
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. */
802 ctf_add_encoded (ctf_file_t
*fp
, uint32_t flag
,
803 const char *name
, const ctf_encoding_t
*ep
, uint32_t kind
)
809 return (ctf_set_errno (fp
, EINVAL
));
811 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
812 return CTF_ERR
; /* errno is set for us. */
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
)
817 dtd
->dtd_u
.dtu_enc
= *ep
;
823 ctf_add_reftype (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
, uint32_t kind
)
827 ctf_file_t
*tmp
= fp
;
829 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
830 return (ctf_set_errno (fp
, EINVAL
));
832 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
833 return CTF_ERR
; /* errno is set for us. */
835 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
836 return CTF_ERR
; /* errno is set for us. */
838 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
839 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
845 ctf_add_slice (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
,
846 const ctf_encoding_t
*ep
)
851 const ctf_type_t
*tp
;
852 ctf_file_t
*tmp
= fp
;
855 return (ctf_set_errno (fp
, EINVAL
));
857 if ((ep
->cte_bits
> 255) || (ep
->cte_offset
> 255))
858 return (ctf_set_errno (fp
, ECTF_SLICEOVERFLOW
));
860 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
861 return (ctf_set_errno (fp
, EINVAL
));
863 if ((tp
= ctf_lookup_by_id (&tmp
, ref
)) == NULL
)
864 return CTF_ERR
; /* errno is set for us. */
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
));
871 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
872 return CTF_ERR
; /* errno is set for us. */
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
)
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
;
885 ctf_add_integer (ctf_file_t
*fp
, uint32_t flag
,
886 const char *name
, const ctf_encoding_t
*ep
)
888 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_INTEGER
));
892 ctf_add_float (ctf_file_t
*fp
, uint32_t flag
,
893 const char *name
, const ctf_encoding_t
*ep
)
895 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_FLOAT
));
899 ctf_add_pointer (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
901 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_POINTER
));
905 ctf_add_array (ctf_file_t
*fp
, uint32_t flag
, const ctf_arinfo_t
*arp
)
909 ctf_file_t
*tmp
= fp
;
912 return (ctf_set_errno (fp
, EINVAL
));
914 if (ctf_lookup_by_id (&tmp
, arp
->ctr_contents
) == NULL
)
915 return CTF_ERR
; /* errno is set for us. */
918 if (ctf_lookup_by_id (&tmp
, arp
->ctr_index
) == NULL
)
919 return CTF_ERR
; /* errno is set for us. */
921 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
922 return CTF_ERR
; /* errno is set for us. */
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
;
932 ctf_set_array (ctf_file_t
*fp
, ctf_id_t type
, const ctf_arinfo_t
*arp
)
934 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
936 if (!(fp
->ctf_flags
& LCTF_RDWR
))
937 return (ctf_set_errno (fp
, ECTF_RDONLY
));
940 || LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
) != CTF_K_ARRAY
)
941 return (ctf_set_errno (fp
, ECTF_BADID
));
943 fp
->ctf_flags
|= LCTF_DIRTY
;
944 dtd
->dtd_u
.dtu_arr
= *arp
;
950 ctf_add_function (ctf_file_t
*fp
, uint32_t flag
,
951 const ctf_funcinfo_t
*ctc
, const ctf_id_t
*argv
)
956 ctf_id_t
*vdat
= NULL
;
957 ctf_file_t
*tmp
= fp
;
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
));
964 vlen
= ctc
->ctc_argc
;
965 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
966 vlen
++; /* Add trailing zero to indicate varargs (see below). */
968 if (ctf_lookup_by_id (&tmp
, ctc
->ctc_return
) == NULL
)
969 return CTF_ERR
; /* errno is set for us. */
971 for (i
= 0; i
< ctc
->ctc_argc
; i
++)
974 if (ctf_lookup_by_id (&tmp
, argv
[i
]) == NULL
)
975 return CTF_ERR
; /* errno is set for us. */
978 if (vlen
> CTF_MAX_VLEN
)
979 return (ctf_set_errno (fp
, EOVERFLOW
));
981 if (vlen
!= 0 && (vdat
= ctf_alloc (sizeof (ctf_id_t
) * vlen
)) == NULL
)
982 return (ctf_set_errno (fp
, EAGAIN
));
984 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
987 return CTF_ERR
; /* errno is set for us. */
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
;
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
;
1002 ctf_add_struct_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1005 ctf_hash_t
*hp
= fp
->ctf_structs
;
1009 /* Promote forwards to structs. */
1013 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1015 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_STRUCT
, name
);
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. */
1023 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_STRUCT
, flag
, 0);
1025 if (size
> CTF_MAX_SIZE
)
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
);
1032 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1038 ctf_add_struct (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1040 return (ctf_add_struct_sized (fp
, flag
, name
, 0));
1044 ctf_add_union_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1047 ctf_hash_t
*hp
= fp
->ctf_unions
;
1051 /* Promote forwards to unions. */
1054 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1056 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_UNION
, name
);
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 */
1064 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_UNION
, flag
, 0);
1066 if (size
> CTF_MAX_SIZE
)
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
);
1073 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1079 ctf_add_union (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1081 return (ctf_add_union_sized (fp
, flag
, name
, 0));
1085 ctf_add_enum (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1087 ctf_hash_t
*hp
= fp
->ctf_enums
;
1091 /* Promote forwards to enums. */
1094 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1096 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
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. */
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
;
1111 ctf_add_enum_encoded (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1112 const ctf_encoding_t
*ep
)
1114 ctf_hash_t
*hp
= fp
->ctf_enums
;
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.) */
1124 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1126 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
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
));
1135 else if ((type
= ctf_add_enum (fp
, flag
, name
)) == CTF_ERR
)
1136 return CTF_ERR
; /* errno is set for us. */
1138 /* Now attach a suitable slice to it. */
1140 return ctf_add_slice (fp
, flag
, type
, ep
);
1144 ctf_add_forward (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1154 hp
= fp
->ctf_structs
;
1157 hp
= fp
->ctf_unions
;
1163 return (ctf_set_errno (fp
, ECTF_NOTSUE
));
1166 /* If the type is already defined or exists as a forward tag, just
1167 return the ctf_id_t of the existing definition. */
1171 if (((type
= ctf_hash_lookup_type (hp
, fp
, name
)) != 0)
1172 || (type
= ctf_dtd_lookup_type_by_name (fp
, kind
, name
)) != 0)
1176 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1177 return CTF_ERR
; /* errno is set for us. */
1179 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FORWARD
, flag
, 0);
1180 dtd
->dtd_data
.ctt_type
= kind
;
1186 ctf_add_typedef (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1191 ctf_file_t
*tmp
= fp
;
1193 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
1194 return (ctf_set_errno (fp
, EINVAL
));
1196 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1197 return CTF_ERR
; /* errno is set for us. */
1199 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1200 return CTF_ERR
; /* errno is set for us. */
1202 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_TYPEDEF
, flag
, 0);
1203 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
1209 ctf_add_volatile (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1211 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_VOLATILE
));
1215 ctf_add_const (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1217 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_CONST
));
1221 ctf_add_restrict (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1223 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_RESTRICT
));
1227 ctf_add_enumerator (ctf_file_t
*fp
, ctf_id_t enid
, const char *name
,
1230 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, enid
);
1233 uint32_t kind
, vlen
, root
;
1237 return (ctf_set_errno (fp
, EINVAL
));
1239 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1240 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1243 return (ctf_set_errno (fp
, ECTF_BADID
));
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
);
1249 if (kind
!= CTF_K_ENUM
)
1250 return (ctf_set_errno (fp
, ECTF_NOTENUM
));
1252 if (vlen
== CTF_MAX_VLEN
)
1253 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1255 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1256 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1258 if (strcmp (dmd
->dmd_name
, name
) == 0)
1259 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1262 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1263 return (ctf_set_errno (fp
, EAGAIN
));
1265 if ((s
= ctf_strdup (name
)) == NULL
)
1268 return (ctf_set_errno (fp
, EAGAIN
));
1272 dmd
->dmd_type
= CTF_ERR
;
1273 dmd
->dmd_offset
= 0;
1274 dmd
->dmd_value
= value
;
1276 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1277 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1279 fp
->ctf_flags
|= LCTF_DIRTY
;
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
)
1288 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, souid
);
1291 ssize_t msize
, malign
, ssize
;
1292 uint32_t kind
, vlen
, root
;
1295 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1296 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1299 return (ctf_set_errno (fp
, ECTF_BADID
));
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
);
1305 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1306 return (ctf_set_errno (fp
, ECTF_NOTSOU
));
1308 if (vlen
== CTF_MAX_VLEN
)
1309 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1313 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1314 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1316 if (dmd
->dmd_name
!= NULL
&& strcmp (dmd
->dmd_name
, name
) == 0)
1317 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
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. */
1325 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1326 return (ctf_set_errno (fp
, EAGAIN
));
1328 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1331 return (ctf_set_errno (fp
, EAGAIN
));
1335 dmd
->dmd_type
= type
;
1336 dmd
->dmd_value
= -1;
1338 if (kind
== CTF_K_STRUCT
&& vlen
!= 0)
1340 if (bit_offset
== (unsigned long) - 1)
1342 /* Natural alignment. */
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
;
1348 ctf_encoding_t linfo
;
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
;
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. */
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
;
1372 /* Specified offset in bits. */
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
);
1381 dmd
->dmd_offset
= 0;
1382 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1383 ssize
= MAX (ssize
, msize
);
1386 if ((size_t) ssize
> CTF_MAX_SIZE
)
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
);
1393 dtd
->dtd_data
.ctt_size
= (uint32_t) ssize
;
1395 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1396 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1398 fp
->ctf_flags
|= LCTF_DIRTY
;
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
)
1407 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
1408 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1411 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) && (kind
!= CTF_K_ENUM
))
1412 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1414 if ((type
= ctf_add_slice (fp
, CTF_ADD_NONROOT
, otype
, &encoding
)) == CTF_ERR
)
1415 return -1; /* errno is set for us. */
1417 return ctf_add_member_offset (fp
, souid
, name
, type
, bit_offset
);
1421 ctf_add_member (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1424 return ctf_add_member_offset (fp
, souid
, name
, type
, (unsigned long) - 1);
1428 ctf_add_variable (ctf_file_t
*fp
, const char *name
, ctf_id_t ref
)
1431 ctf_file_t
*tmp
= fp
;
1433 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1434 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1436 if (ctf_dvd_lookup (fp
, name
) != NULL
)
1437 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1439 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1440 return -1; /* errno is set for us. */
1442 /* Make sure this type is representable. */
1443 if ((ctf_type_resolve (fp
, ref
) == CTF_ERR
)
1444 && (ctf_errno (fp
) == ECTF_NONREPRESENTABLE
))
1447 if ((dvd
= ctf_alloc (sizeof (ctf_dvdef_t
))) == NULL
)
1448 return (ctf_set_errno (fp
, EAGAIN
));
1450 if (name
!= NULL
&& (dvd
->dvd_name
= ctf_strdup (name
)) == NULL
)
1453 return (ctf_set_errno (fp
, EAGAIN
));
1455 dvd
->dvd_type
= ref
;
1456 dvd
->dvd_snapshots
= fp
->ctf_snapshots
;
1458 if (ctf_dvd_insert (fp
, dvd
) < 0)
1461 return -1; /* errno is set for us. */
1464 fp
->ctf_flags
|= LCTF_DIRTY
;
1469 enumcmp (const char *name
, int value
, void *arg
)
1471 ctf_bundle_t
*ctb
= arg
;
1474 if (ctf_enum_value (ctb
->ctb_file
, ctb
->ctb_type
, name
, &bvalue
) < 0)
1476 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1479 if (value
!= bvalue
)
1481 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1489 enumadd (const char *name
, int value
, void *arg
)
1491 ctf_bundle_t
*ctb
= arg
;
1493 return (ctf_add_enumerator (ctb
->ctb_file
, ctb
->ctb_type
,
1498 membcmp (const char *name
, ctf_id_t type _libctf_unused_
, unsigned long offset
,
1501 ctf_bundle_t
*ctb
= arg
;
1504 if (ctf_member_info (ctb
->ctb_file
, ctb
->ctb_type
, name
, &ctm
) < 0)
1506 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1509 if (ctm
.ctm_offset
!= offset
)
1511 ctf_dprintf ("Conflict due to member %s offset change: "
1512 "%lx versus %lx\n", name
, ctm
.ctm_offset
, offset
);
1519 membadd (const char *name
, ctf_id_t type
, unsigned long offset
, void *arg
)
1521 ctf_bundle_t
*ctb
= arg
;
1525 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1526 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1528 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1531 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1534 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1535 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1537 dmd
->dmd_type
= type
;
1538 dmd
->dmd_offset
= offset
;
1539 dmd
->dmd_value
= -1;
1541 ctf_list_append (&ctb
->ctb_dtd
->dtd_u
.dtu_members
, dmd
);
1543 ctb
->ctb_file
->ctf_flags
|= LCTF_DIRTY
;
1547 /* The ctf_add_type routine is used to copy a type from a source CTF container
1548 to a dynamic destination container. This routine operates recursively by
1549 following the source type's links and embedded member types. If the
1550 destination container already contains a named type which has the same
1551 attributes, then we succeed and return this type but no changes occur. */
1553 ctf_add_type (ctf_file_t
*dst_fp
, ctf_file_t
*src_fp
, ctf_id_t src_type
)
1555 ctf_id_t dst_type
= CTF_ERR
;
1556 uint32_t dst_kind
= CTF_K_UNKNOWN
;
1560 uint32_t kind
, forward_kind
, flag
, vlen
;
1562 const ctf_type_t
*src_tp
, *dst_tp
;
1563 ctf_bundle_t src
, dst
;
1564 ctf_encoding_t src_en
, dst_en
;
1565 ctf_arinfo_t src_ar
, dst_ar
;
1571 ctf_id_t orig_src_type
= src_type
;
1573 if (!(dst_fp
->ctf_flags
& LCTF_RDWR
))
1574 return (ctf_set_errno (dst_fp
, ECTF_RDONLY
));
1576 if ((src_tp
= ctf_lookup_by_id (&src_fp
, src_type
)) == NULL
)
1577 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1579 if ((ctf_type_resolve (src_fp
, src_type
) == CTF_ERR
)
1580 && (ctf_errno (src_fp
) == ECTF_NONREPRESENTABLE
))
1581 return (ctf_set_errno (dst_fp
, ECTF_NONREPRESENTABLE
));
1583 name
= ctf_strptr (src_fp
, src_tp
->ctt_name
);
1584 kind
= LCTF_INFO_KIND (src_fp
, src_tp
->ctt_info
);
1585 flag
= LCTF_INFO_ISROOT (src_fp
, src_tp
->ctt_info
);
1586 vlen
= LCTF_INFO_VLEN (src_fp
, src_tp
->ctt_info
);
1588 forward_kind
= kind
;
1589 if (kind
== CTF_K_FORWARD
)
1590 forward_kind
= src_tp
->ctt_type
;
1592 switch (forward_kind
)
1595 hp
= dst_fp
->ctf_structs
;
1598 hp
= dst_fp
->ctf_unions
;
1601 hp
= dst_fp
->ctf_enums
;
1604 hp
= dst_fp
->ctf_names
;
1608 /* If the source type has a name and is a root type (visible at the
1609 top-level scope), lookup the name in the destination container and
1610 verify that it is of the same kind before we do anything else. */
1612 if ((flag
& CTF_ADD_ROOT
) && name
[0] != '\0'
1613 && (tmp
= ctf_hash_lookup_type (hp
, dst_fp
, name
)) != 0)
1616 dst_kind
= ctf_type_kind_unsliced (dst_fp
, dst_type
);
1619 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1620 unless dst_type is a forward declaration and src_type is a struct,
1621 union, or enum (i.e. the definition of the previous forward decl).
1623 We also allow addition in the opposite order (addition of a forward when a
1624 struct, union, or enum already exists), which is a NOP and returns the
1625 already-present struct, union, or enum. */
1627 if (dst_type
!= CTF_ERR
&& dst_kind
!= kind
)
1629 if (kind
== CTF_K_FORWARD
1630 && (dst_kind
== CTF_K_ENUM
|| dst_kind
== CTF_K_STRUCT
1631 || dst_kind
== CTF_K_UNION
))
1633 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dst_type
);
1637 if (dst_kind
!= CTF_K_FORWARD
1638 || (kind
!= CTF_K_ENUM
&& kind
!= CTF_K_STRUCT
1639 && kind
!= CTF_K_UNION
))
1641 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1642 "old (ID %lx): %i\n", name
, kind
, dst_type
, dst_kind
);
1643 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1647 /* We take special action for an integer, float, or slice since it is
1648 described not only by its name but also its encoding. For integers,
1649 bit-fields exploit this degeneracy. */
1651 if (kind
== CTF_K_INTEGER
|| kind
== CTF_K_FLOAT
|| kind
== CTF_K_SLICE
)
1653 if (ctf_type_encoding (src_fp
, src_type
, &src_en
) != 0)
1654 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1656 if (dst_type
!= CTF_ERR
)
1658 ctf_file_t
*fp
= dst_fp
;
1660 if ((dst_tp
= ctf_lookup_by_id (&fp
, dst_type
)) == NULL
)
1663 if (LCTF_INFO_ISROOT (fp
, dst_tp
->ctt_info
) & CTF_ADD_ROOT
)
1665 /* The type that we found in the hash is also root-visible. If
1666 the two types match then use the existing one; otherwise,
1667 declare a conflict. Note: slices are not certain to match
1668 even if there is no conflict: we must check the contained type
1671 if (ctf_type_encoding (dst_fp
, dst_type
, &dst_en
) != 0)
1672 return CTF_ERR
; /* errno set for us. */
1674 if (memcmp (&src_en
, &dst_en
, sizeof (ctf_encoding_t
)) == 0)
1676 if (kind
!= CTF_K_SLICE
)
1678 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dst_type
);
1684 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1689 /* We found a non-root-visible type in the hash. We reset
1690 dst_type to ensure that we continue to look for a possible
1691 conflict in the pending list. */
1698 /* If the non-empty name was not found in the appropriate hash, search
1699 the list of pending dynamic definitions that are not yet committed.
1700 If a matching name and kind are found, assume this is the type that
1701 we are looking for. This is necessary to permit ctf_add_type() to
1702 operate recursively on entities such as a struct that contains a
1703 pointer member that refers to the same struct type. */
1705 if (dst_type
== CTF_ERR
&& name
[0] != '\0')
1707 for (dtd
= ctf_list_prev (&dst_fp
->ctf_dtdefs
); dtd
!= NULL
1708 && LCTF_TYPE_TO_INDEX (src_fp
, dtd
->dtd_type
) > dst_fp
->ctf_dtoldid
;
1709 dtd
= ctf_list_prev (dtd
))
1711 if (LCTF_INFO_KIND (src_fp
, dtd
->dtd_data
.ctt_info
) == kind
1712 && dtd
->dtd_name
!= NULL
&& strcmp (dtd
->dtd_name
, name
) == 0)
1714 int sroot
; /* Is the src root-visible? */
1715 int droot
; /* Is the dst root-visible? */
1716 int match
; /* Do the encodings match? */
1718 if (kind
!= CTF_K_INTEGER
&& kind
!= CTF_K_FLOAT
&& kind
!= CTF_K_SLICE
)
1720 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dtd
->dtd_type
);
1721 return dtd
->dtd_type
;
1724 sroot
= (flag
& CTF_ADD_ROOT
);
1725 droot
= (LCTF_INFO_ISROOT (dst_fp
,
1727 ctt_info
) & CTF_ADD_ROOT
);
1729 match
= (memcmp (&src_en
, &dtd
->dtd_u
.dtu_enc
,
1730 sizeof (ctf_encoding_t
)) == 0);
1732 /* If the types share the same encoding then return the id of the
1733 first unless one type is root-visible and the other is not; in
1734 that case the new type must get a new id if a match is never
1735 found. Note: slices are not certain to match even if there is
1736 no conflict: we must check the contained type too. */
1738 if (match
&& sroot
== droot
)
1740 if (kind
!= CTF_K_SLICE
)
1742 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dtd
->dtd_type
);
1743 return dtd
->dtd_type
;
1746 else if (!match
&& sroot
&& droot
)
1748 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1754 src
.ctb_file
= src_fp
;
1755 src
.ctb_type
= src_type
;
1758 dst
.ctb_file
= dst_fp
;
1759 dst
.ctb_type
= dst_type
;
1762 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1763 we add a new type with the same properties as src_type to dst_fp.
1764 If dst_type is not CTF_ERR, then we verify that dst_type has the
1765 same attributes as src_type. We recurse for embedded references. */
1769 /* If we found a match we will have either returned it or declared a
1771 dst_type
= ctf_add_integer (dst_fp
, flag
, name
, &src_en
);
1775 /* If we found a match we will have either returned it or declared a
1777 dst_type
= ctf_add_float (dst_fp
, flag
, name
, &src_en
);
1781 /* We have checked for conflicting encodings: now try to add the
1783 src_type
= ctf_type_reference (src_fp
, src_type
);
1784 dst_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1786 if (src_type
== CTF_ERR
)
1787 return CTF_ERR
; /* errno is set for us. */
1789 dst_type
= ctf_add_slice (dst_fp
, flag
, src_type
, &src_en
);
1793 case CTF_K_VOLATILE
:
1795 case CTF_K_RESTRICT
:
1796 src_type
= ctf_type_reference (src_fp
, src_type
);
1797 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1799 if (src_type
== CTF_ERR
)
1800 return CTF_ERR
; /* errno is set for us. */
1802 dst_type
= ctf_add_reftype (dst_fp
, flag
, src_type
, kind
);
1806 if (ctf_array_info (src_fp
, src_type
, &src_ar
) != 0)
1807 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1809 src_ar
.ctr_contents
=
1810 ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_contents
);
1811 src_ar
.ctr_index
= ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_index
);
1812 src_ar
.ctr_nelems
= src_ar
.ctr_nelems
;
1814 if (src_ar
.ctr_contents
== CTF_ERR
|| src_ar
.ctr_index
== CTF_ERR
)
1815 return CTF_ERR
; /* errno is set for us. */
1817 if (dst_type
!= CTF_ERR
)
1819 if (ctf_array_info (dst_fp
, dst_type
, &dst_ar
) != 0)
1820 return CTF_ERR
; /* errno is set for us. */
1822 if (memcmp (&src_ar
, &dst_ar
, sizeof (ctf_arinfo_t
)))
1824 ctf_dprintf ("Conflict for type %s against ID %lx: "
1825 "array info differs, old %lx/%lx/%x; "
1826 "new: %lx/%lx/%x\n", name
, dst_type
,
1827 src_ar
.ctr_contents
, src_ar
.ctr_index
,
1828 src_ar
.ctr_nelems
, dst_ar
.ctr_contents
,
1829 dst_ar
.ctr_index
, dst_ar
.ctr_nelems
);
1830 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1834 dst_type
= ctf_add_array (dst_fp
, flag
, &src_ar
);
1837 case CTF_K_FUNCTION
:
1838 ctc
.ctc_return
= ctf_add_type (dst_fp
, src_fp
, src_tp
->ctt_type
);
1842 if (ctc
.ctc_return
== CTF_ERR
)
1843 return CTF_ERR
; /* errno is set for us. */
1845 dst_type
= ctf_add_function (dst_fp
, flag
, &ctc
, NULL
);
1856 /* Technically to match a struct or union we need to check both
1857 ways (src members vs. dst, dst members vs. src) but we make
1858 this more optimal by only checking src vs. dst and comparing
1859 the total size of the structure (which we must do anyway)
1860 which covers the possibility of dst members not in src.
1861 This optimization can be defeated for unions, but is so
1862 pathological as to render it irrelevant for our purposes. */
1864 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1866 if (ctf_type_size (src_fp
, src_type
) !=
1867 ctf_type_size (dst_fp
, dst_type
))
1869 ctf_dprintf ("Conflict for type %s against ID %lx: "
1870 "union size differs, old %li, new %li\n",
1872 (long) ctf_type_size (src_fp
, src_type
),
1873 (long) ctf_type_size (dst_fp
, dst_type
));
1874 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1877 if (ctf_member_iter (src_fp
, src_type
, membcmp
, &dst
))
1879 ctf_dprintf ("Conflict for type %s against ID %lx: "
1880 "members differ, see above\n", name
, dst_type
);
1881 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1887 /* Unlike the other cases, copying structs and unions is done
1888 manually so as to avoid repeated lookups in ctf_add_member
1889 and to ensure the exact same member offsets as in src_type. */
1891 dst_type
= ctf_add_generic (dst_fp
, flag
, name
, &dtd
);
1892 if (dst_type
== CTF_ERR
)
1893 return CTF_ERR
; /* errno is set for us. */
1895 dst
.ctb_type
= dst_type
;
1898 if (ctf_member_iter (src_fp
, src_type
, membadd
, &dst
) != 0)
1899 errs
++; /* Increment errs and fail at bottom of case. */
1901 if ((ssize
= ctf_type_size (src_fp
, src_type
)) < 0)
1902 return CTF_ERR
; /* errno is set for us. */
1904 size
= (size_t) ssize
;
1905 if (size
> CTF_MAX_SIZE
)
1907 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1908 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1909 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1912 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1914 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, vlen
);
1916 /* Make a final pass through the members changing each dmd_type (a
1917 src_fp type) to an equivalent type in dst_fp. We pass through all
1918 members, leaving any that fail set to CTF_ERR, unless they fail
1919 because they are marking a member of type not representable in this
1920 version of CTF, in which case we just want to silently omit them:
1921 no consumer can do anything with them anyway. */
1922 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1923 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1925 if ((dmd
->dmd_type
= ctf_add_type (dst_fp
, src_fp
,
1926 dmd
->dmd_type
)) == CTF_ERR
)
1928 if (ctf_errno (dst_fp
) != ECTF_NONREPRESENTABLE
)
1934 return CTF_ERR
; /* errno is set for us. */
1939 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1941 if (ctf_enum_iter (src_fp
, src_type
, enumcmp
, &dst
)
1942 || ctf_enum_iter (dst_fp
, dst_type
, enumcmp
, &src
))
1944 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1945 "members differ, see above\n", name
, dst_type
);
1946 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1951 dst_type
= ctf_add_enum (dst_fp
, flag
, name
);
1952 if ((dst
.ctb_type
= dst_type
) == CTF_ERR
1953 || ctf_enum_iter (src_fp
, src_type
, enumadd
, &dst
))
1954 return CTF_ERR
; /* errno is set for us */
1959 if (dst_type
== CTF_ERR
)
1960 dst_type
= ctf_add_forward (dst_fp
, flag
, name
, forward_kind
);
1964 src_type
= ctf_type_reference (src_fp
, src_type
);
1965 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1967 if (src_type
== CTF_ERR
)
1968 return CTF_ERR
; /* errno is set for us. */
1970 /* If dst_type is not CTF_ERR at this point, we should check if
1971 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1972 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1973 that vary based on things like if 32-bit then pid_t is int otherwise
1974 long. We therefore omit this check and assume that if the identically
1975 named typedef already exists in dst_fp, it is correct or
1978 if (dst_type
== CTF_ERR
)
1980 dst_type
= ctf_add_typedef (dst_fp
, flag
, name
, src_type
);
1985 return (ctf_set_errno (dst_fp
, ECTF_CORRUPT
));
1988 if (dst_type
!= CTF_ERR
)
1989 ctf_add_type_mapping (src_fp
, orig_src_type
, dst_fp
, dst_type
);
1993 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1995 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1997 const unsigned char *buf
;
2001 resid
= sizeof (ctf_header_t
);
2002 buf
= (unsigned char *) fp
->ctf_header
;
2005 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
2006 return (ctf_set_errno (fp
, errno
));
2011 resid
= fp
->ctf_size
;
2015 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
2016 return (ctf_set_errno (fp
, errno
));
2024 /* Compress the specified CTF data stream and write it to the specified file
2027 ctf_compress_write (ctf_file_t
*fp
, int fd
)
2032 ctf_header_t
*hp
= &h
;
2033 ssize_t header_len
= sizeof (ctf_header_t
);
2034 ssize_t compress_len
;
2035 size_t max_compress_len
= compressBound (fp
->ctf_size
);
2040 memcpy (hp
, fp
->ctf_header
, header_len
);
2041 hp
->cth_flags
|= CTF_F_COMPRESS
;
2043 if ((buf
= ctf_alloc (max_compress_len
)) == NULL
)
2044 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
2046 compress_len
= max_compress_len
;
2047 if ((rc
= compress (buf
, (uLongf
*) &compress_len
,
2048 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2050 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2051 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
2055 while (header_len
> 0)
2057 if ((len
= write (fd
, hp
, header_len
)) < 0)
2059 err
= ctf_set_errno (fp
, errno
);
2067 while (compress_len
> 0)
2069 if ((len
= write (fd
, bp
, compress_len
)) < 0)
2071 err
= ctf_set_errno (fp
, errno
);
2074 compress_len
-= len
;
2083 /* Optionally compress the specified CTF data stream and return it as a new
2084 dynamically-allocated string. */
2086 ctf_write_mem (ctf_file_t
*fp
, size_t *size
, size_t threshold
)
2091 ssize_t header_len
= sizeof (ctf_header_t
);
2092 ssize_t compress_len
;
2093 size_t max_compress_len
= compressBound (fp
->ctf_size
);
2096 if (fp
->ctf_size
< threshold
)
2097 max_compress_len
= fp
->ctf_size
;
2098 if ((buf
= malloc (max_compress_len
2099 + sizeof (struct ctf_header
))) == NULL
)
2101 ctf_set_errno (fp
, ENOMEM
);
2105 hp
= (ctf_header_t
*) buf
;
2106 memcpy (hp
, fp
->ctf_header
, header_len
);
2107 bp
= buf
+ sizeof (struct ctf_header
);
2108 *size
= sizeof (struct ctf_header
);
2110 compress_len
= max_compress_len
;
2112 if (fp
->ctf_size
< threshold
)
2114 hp
->cth_flags
&= ~CTF_F_COMPRESS
;
2115 memcpy (bp
, fp
->ctf_buf
, fp
->ctf_size
);
2116 *size
+= fp
->ctf_size
;
2120 hp
->cth_flags
|= CTF_F_COMPRESS
;
2121 if ((rc
= compress (bp
, (uLongf
*) &compress_len
,
2122 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2124 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2125 ctf_set_errno (fp
, ECTF_COMPRESS
);
2129 *size
+= compress_len
;
2134 /* Write the uncompressed CTF data stream to the specified file descriptor. */
2136 ctf_write (ctf_file_t
*fp
, int fd
)
2138 const unsigned char *buf
;
2142 resid
= sizeof (ctf_header_t
);
2143 buf
= (unsigned char *) fp
->ctf_header
;
2146 if ((len
= write (fd
, buf
, resid
)) <= 0)
2147 return (ctf_set_errno (fp
, errno
));
2152 resid
= fp
->ctf_size
;
2156 if ((len
= write (fd
, buf
, resid
)) <= 0)
2157 return (ctf_set_errno (fp
, errno
));