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_type_mapping
= fp
->ctf_link_type_mapping
;
478 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
480 fp
->ctf_dtbyname
= NULL
;
481 fp
->ctf_dthash
= NULL
;
482 ctf_str_free_atoms (nfp
);
483 nfp
->ctf_str_atoms
= fp
->ctf_str_atoms
;
484 fp
->ctf_str_atoms
= NULL
;
485 memset (&fp
->ctf_dtdefs
, 0, sizeof (ctf_list_t
));
486 fp
->ctf_link_inputs
= NULL
;
487 fp
->ctf_link_outputs
= NULL
;
488 fp
->ctf_syn_ext_strtab
= NULL
;
489 fp
->ctf_link_type_mapping
= NULL
;
491 fp
->ctf_dvhash
= NULL
;
492 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
494 memcpy (&ofp
, fp
, sizeof (ctf_file_t
));
495 memcpy (fp
, nfp
, sizeof (ctf_file_t
));
496 memcpy (nfp
, &ofp
, sizeof (ctf_file_t
));
498 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
499 array of type name prefixes and the corresponding ctf_dynhash to use.
500 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
502 fp
->ctf_lookups
[0].ctl_hash
= fp
->ctf_structs
;
503 fp
->ctf_lookups
[1].ctl_hash
= fp
->ctf_unions
;
504 fp
->ctf_lookups
[2].ctl_hash
= fp
->ctf_enums
;
505 fp
->ctf_lookups
[3].ctl_hash
= fp
->ctf_names
;
507 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
508 ctf_file_close (nfp
);
514 ctf_prefixed_name (int kind
, const char *name
)
521 prefixed
= ctf_strdup ("struct ");
524 prefixed
= ctf_strdup ("union ");
527 prefixed
= ctf_strdup ("enum ");
530 prefixed
= ctf_strdup ("");
533 prefixed
= ctf_str_append (prefixed
, name
);
538 ctf_dtd_insert (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
540 if (ctf_dynhash_insert (fp
->ctf_dthash
, (void *) dtd
->dtd_type
, dtd
) < 0)
545 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
546 if (ctf_dynhash_insert (fp
->ctf_dtbyname
,
547 ctf_prefixed_name (kind
, dtd
->dtd_name
),
551 ctf_list_append (&fp
->ctf_dtdefs
, dtd
);
556 ctf_dtd_delete (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
558 ctf_dmdef_t
*dmd
, *nmd
;
559 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
561 ctf_dynhash_remove (fp
->ctf_dthash
, (void *) dtd
->dtd_type
);
568 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
569 dmd
!= NULL
; dmd
= nmd
)
571 if (dmd
->dmd_name
!= NULL
)
572 ctf_free (dmd
->dmd_name
);
573 nmd
= ctf_list_next (dmd
);
578 ctf_free (dtd
->dtd_u
.dtu_argv
);
586 name
= ctf_prefixed_name (kind
, dtd
->dtd_name
);
587 ctf_dynhash_remove (fp
->ctf_dtbyname
, name
);
589 ctf_free (dtd
->dtd_name
);
592 ctf_list_delete (&fp
->ctf_dtdefs
, dtd
);
597 ctf_dtd_lookup (const ctf_file_t
*fp
, ctf_id_t type
)
599 return (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dthash
, (void *) type
);
603 ctf_dtd_lookup_type_by_name (ctf_file_t
*fp
, int kind
, const char *name
)
606 char *decorated
= ctf_prefixed_name (kind
, name
);
608 dtd
= (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dtbyname
, decorated
);
612 return dtd
->dtd_type
;
618 ctf_dynamic_type (const ctf_file_t
*fp
, ctf_id_t id
)
622 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, id
))
625 idx
= LCTF_TYPE_TO_INDEX(fp
, id
);
627 if (((unsigned long) idx
> fp
->ctf_typemax
) &&
628 ((unsigned long) idx
< fp
->ctf_dtnextid
))
629 return ctf_dtd_lookup (fp
, id
);
634 ctf_dvd_insert (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
636 if (ctf_dynhash_insert (fp
->ctf_dvhash
, dvd
->dvd_name
, dvd
) < 0)
638 ctf_list_append (&fp
->ctf_dvdefs
, dvd
);
643 ctf_dvd_delete (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
645 ctf_dynhash_remove (fp
->ctf_dvhash
, dvd
->dvd_name
);
646 ctf_free (dvd
->dvd_name
);
648 ctf_list_delete (&fp
->ctf_dvdefs
, dvd
);
653 ctf_dvd_lookup (const ctf_file_t
*fp
, const char *name
)
655 return (ctf_dvdef_t
*) ctf_dynhash_lookup (fp
->ctf_dvhash
, name
);
658 /* Discard all of the dynamic type definitions and variable definitions that
659 have been added to the container since the last call to ctf_update(). We
660 locate such types by scanning the dtd list and deleting elements that have
661 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
662 by scanning the variable list and deleting elements that have update IDs
663 equal to the current value of the last-update snapshot count (indicating that
664 they were added after the most recent call to ctf_update()). */
666 ctf_discard (ctf_file_t
*fp
)
668 ctf_snapshot_id_t last_update
=
670 fp
->ctf_snapshot_lu
+ 1 };
672 /* Update required? */
673 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
676 return (ctf_rollback (fp
, last_update
));
680 ctf_snapshot (ctf_file_t
*fp
)
682 ctf_snapshot_id_t snapid
;
683 snapid
.dtd_id
= fp
->ctf_dtnextid
- 1;
684 snapid
.snapshot_id
= fp
->ctf_snapshots
++;
688 /* Like ctf_discard(), only discards everything after a particular ID. */
690 ctf_rollback (ctf_file_t
*fp
, ctf_snapshot_id_t id
)
692 ctf_dtdef_t
*dtd
, *ntd
;
693 ctf_dvdef_t
*dvd
, *nvd
;
695 if (!(fp
->ctf_flags
& LCTF_RDWR
))
696 return (ctf_set_errno (fp
, ECTF_RDONLY
));
698 if (fp
->ctf_dtoldid
> id
.dtd_id
)
699 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
701 if (fp
->ctf_snapshot_lu
>= id
.snapshot_id
)
702 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
704 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
); dtd
!= NULL
; dtd
= ntd
)
706 ntd
= ctf_list_next (dtd
);
708 if (LCTF_TYPE_TO_INDEX (fp
, dtd
->dtd_type
) <= id
.dtd_id
)
711 ctf_dtd_delete (fp
, dtd
);
714 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
716 nvd
= ctf_list_next (dvd
);
718 if (dvd
->dvd_snapshots
<= id
.snapshot_id
)
721 ctf_dvd_delete (fp
, dvd
);
724 fp
->ctf_dtnextid
= id
.dtd_id
+ 1;
725 fp
->ctf_snapshots
= id
.snapshot_id
;
727 if (fp
->ctf_snapshots
== fp
->ctf_snapshot_lu
)
728 fp
->ctf_flags
&= ~LCTF_DIRTY
;
734 ctf_add_generic (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
741 if (flag
!= CTF_ADD_NONROOT
&& flag
!= CTF_ADD_ROOT
)
742 return (ctf_set_errno (fp
, EINVAL
));
744 if (!(fp
->ctf_flags
& LCTF_RDWR
))
745 return (ctf_set_errno (fp
, ECTF_RDONLY
));
747 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) > CTF_MAX_TYPE
)
748 return (ctf_set_errno (fp
, ECTF_FULL
));
750 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) == CTF_MAX_PTYPE
)
751 return (ctf_set_errno (fp
, ECTF_FULL
));
753 if ((dtd
= ctf_alloc (sizeof (ctf_dtdef_t
))) == NULL
)
754 return (ctf_set_errno (fp
, EAGAIN
));
756 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
759 return (ctf_set_errno (fp
, EAGAIN
));
762 type
= fp
->ctf_dtnextid
++;
763 type
= LCTF_INDEX_TO_TYPE (fp
, type
, (fp
->ctf_flags
& LCTF_CHILD
));
765 memset (dtd
, 0, sizeof (ctf_dtdef_t
));
767 dtd
->dtd_type
= type
;
769 if (ctf_dtd_insert (fp
, dtd
) < 0)
772 return CTF_ERR
; /* errno is set for us. */
774 fp
->ctf_flags
|= LCTF_DIRTY
;
780 /* When encoding integer sizes, we want to convert a byte count in the range
781 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
782 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
798 ctf_add_encoded (ctf_file_t
*fp
, uint32_t flag
,
799 const char *name
, const ctf_encoding_t
*ep
, uint32_t kind
)
805 return (ctf_set_errno (fp
, EINVAL
));
807 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
808 return CTF_ERR
; /* errno is set for us. */
810 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
811 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
813 dtd
->dtd_u
.dtu_enc
= *ep
;
819 ctf_add_reftype (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
, uint32_t kind
)
823 ctf_file_t
*tmp
= fp
;
825 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
826 return (ctf_set_errno (fp
, EINVAL
));
828 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
829 return CTF_ERR
; /* errno is set for us. */
831 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
832 return CTF_ERR
; /* errno is set for us. */
834 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
835 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
841 ctf_add_slice (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
,
842 const ctf_encoding_t
*ep
)
847 const ctf_type_t
*tp
;
848 ctf_file_t
*tmp
= fp
;
851 return (ctf_set_errno (fp
, EINVAL
));
853 if ((ep
->cte_bits
> 255) || (ep
->cte_offset
> 255))
854 return (ctf_set_errno (fp
, ECTF_SLICEOVERFLOW
));
856 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
857 return (ctf_set_errno (fp
, EINVAL
));
859 if ((tp
= ctf_lookup_by_id (&tmp
, ref
)) == NULL
)
860 return CTF_ERR
; /* errno is set for us. */
862 kind
= ctf_type_kind_unsliced (tmp
, ref
);
863 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) &&
864 (kind
!= CTF_K_ENUM
))
865 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
867 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
868 return CTF_ERR
; /* errno is set for us. */
870 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_SLICE
, flag
, 0);
871 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
873 dtd
->dtd_u
.dtu_slice
.cts_type
= ref
;
874 dtd
->dtd_u
.dtu_slice
.cts_bits
= ep
->cte_bits
;
875 dtd
->dtd_u
.dtu_slice
.cts_offset
= ep
->cte_offset
;
881 ctf_add_integer (ctf_file_t
*fp
, uint32_t flag
,
882 const char *name
, const ctf_encoding_t
*ep
)
884 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_INTEGER
));
888 ctf_add_float (ctf_file_t
*fp
, uint32_t flag
,
889 const char *name
, const ctf_encoding_t
*ep
)
891 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_FLOAT
));
895 ctf_add_pointer (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
897 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_POINTER
));
901 ctf_add_array (ctf_file_t
*fp
, uint32_t flag
, const ctf_arinfo_t
*arp
)
905 ctf_file_t
*tmp
= fp
;
908 return (ctf_set_errno (fp
, EINVAL
));
910 if (ctf_lookup_by_id (&tmp
, arp
->ctr_contents
) == NULL
)
911 return CTF_ERR
; /* errno is set for us. */
914 if (ctf_lookup_by_id (&tmp
, arp
->ctr_index
) == NULL
)
915 return CTF_ERR
; /* errno is set for us. */
917 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
918 return CTF_ERR
; /* errno is set for us. */
920 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ARRAY
, flag
, 0);
921 dtd
->dtd_data
.ctt_size
= 0;
922 dtd
->dtd_u
.dtu_arr
= *arp
;
928 ctf_set_array (ctf_file_t
*fp
, ctf_id_t type
, const ctf_arinfo_t
*arp
)
930 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
932 if (!(fp
->ctf_flags
& LCTF_RDWR
))
933 return (ctf_set_errno (fp
, ECTF_RDONLY
));
936 || LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
) != CTF_K_ARRAY
)
937 return (ctf_set_errno (fp
, ECTF_BADID
));
939 fp
->ctf_flags
|= LCTF_DIRTY
;
940 dtd
->dtd_u
.dtu_arr
= *arp
;
946 ctf_add_function (ctf_file_t
*fp
, uint32_t flag
,
947 const ctf_funcinfo_t
*ctc
, const ctf_id_t
*argv
)
952 ctf_id_t
*vdat
= NULL
;
953 ctf_file_t
*tmp
= fp
;
956 if (ctc
== NULL
|| (ctc
->ctc_flags
& ~CTF_FUNC_VARARG
) != 0
957 || (ctc
->ctc_argc
!= 0 && argv
== NULL
))
958 return (ctf_set_errno (fp
, EINVAL
));
960 vlen
= ctc
->ctc_argc
;
961 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
962 vlen
++; /* Add trailing zero to indicate varargs (see below). */
964 if (ctf_lookup_by_id (&tmp
, ctc
->ctc_return
) == NULL
)
965 return CTF_ERR
; /* errno is set for us. */
967 for (i
= 0; i
< ctc
->ctc_argc
; i
++)
970 if (ctf_lookup_by_id (&tmp
, argv
[i
]) == NULL
)
971 return CTF_ERR
; /* errno is set for us. */
974 if (vlen
> CTF_MAX_VLEN
)
975 return (ctf_set_errno (fp
, EOVERFLOW
));
977 if (vlen
!= 0 && (vdat
= ctf_alloc (sizeof (ctf_id_t
) * vlen
)) == NULL
)
978 return (ctf_set_errno (fp
, EAGAIN
));
980 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
983 return CTF_ERR
; /* errno is set for us. */
986 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FUNCTION
, flag
, vlen
);
987 dtd
->dtd_data
.ctt_type
= (uint32_t) ctc
->ctc_return
;
989 memcpy (vdat
, argv
, sizeof (ctf_id_t
) * ctc
->ctc_argc
);
990 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
991 vdat
[vlen
- 1] = 0; /* Add trailing zero to indicate varargs. */
992 dtd
->dtd_u
.dtu_argv
= vdat
;
998 ctf_add_struct_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1001 ctf_hash_t
*hp
= fp
->ctf_structs
;
1005 /* Promote forwards to structs. */
1009 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1011 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_STRUCT
, name
);
1014 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1015 dtd
= ctf_dtd_lookup (fp
, type
);
1016 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1017 return CTF_ERR
; /* errno is set for us. */
1019 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_STRUCT
, flag
, 0);
1021 if (size
> CTF_MAX_SIZE
)
1023 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1024 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1025 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1028 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1034 ctf_add_struct (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1036 return (ctf_add_struct_sized (fp
, flag
, name
, 0));
1040 ctf_add_union_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1043 ctf_hash_t
*hp
= fp
->ctf_unions
;
1047 /* Promote forwards to unions. */
1050 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1052 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_UNION
, name
);
1055 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1056 dtd
= ctf_dtd_lookup (fp
, type
);
1057 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1058 return CTF_ERR
; /* errno is set for us */
1060 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_UNION
, flag
, 0);
1062 if (size
> CTF_MAX_SIZE
)
1064 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1065 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1066 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1069 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1075 ctf_add_union (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1077 return (ctf_add_union_sized (fp
, flag
, name
, 0));
1081 ctf_add_enum (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1083 ctf_hash_t
*hp
= fp
->ctf_enums
;
1087 /* Promote forwards to enums. */
1090 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1092 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1095 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1096 dtd
= ctf_dtd_lookup (fp
, type
);
1097 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1098 return CTF_ERR
; /* errno is set for us. */
1100 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ENUM
, flag
, 0);
1101 dtd
->dtd_data
.ctt_size
= fp
->ctf_dmodel
->ctd_int
;
1107 ctf_add_enum_encoded (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1108 const ctf_encoding_t
*ep
)
1110 ctf_hash_t
*hp
= fp
->ctf_enums
;
1113 /* First, create the enum if need be, using most of the same machinery as
1114 ctf_add_enum(), to ensure that we do not allow things past that are not
1115 enums or forwards to them. (This includes other slices: you cannot slice a
1116 slice, which would be a useless thing to do anyway.) */
1120 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1122 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1127 if ((ctf_type_kind (fp
, type
) != CTF_K_FORWARD
) &&
1128 (ctf_type_kind_unsliced (fp
, type
) != CTF_K_ENUM
))
1129 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1131 else if ((type
= ctf_add_enum (fp
, flag
, name
)) == CTF_ERR
)
1132 return CTF_ERR
; /* errno is set for us. */
1134 /* Now attach a suitable slice to it. */
1136 return ctf_add_slice (fp
, flag
, type
, ep
);
1140 ctf_add_forward (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1150 hp
= fp
->ctf_structs
;
1153 hp
= fp
->ctf_unions
;
1159 return (ctf_set_errno (fp
, ECTF_NOTSUE
));
1162 /* If the type is already defined or exists as a forward tag, just
1163 return the ctf_id_t of the existing definition. */
1167 if (((type
= ctf_hash_lookup_type (hp
, fp
, name
)) != 0)
1168 || (type
= ctf_dtd_lookup_type_by_name (fp
, kind
, name
)) != 0)
1172 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1173 return CTF_ERR
; /* errno is set for us. */
1175 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FORWARD
, flag
, 0);
1176 dtd
->dtd_data
.ctt_type
= kind
;
1182 ctf_add_typedef (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1187 ctf_file_t
*tmp
= fp
;
1189 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
1190 return (ctf_set_errno (fp
, EINVAL
));
1192 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1193 return CTF_ERR
; /* errno is set for us. */
1195 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1196 return CTF_ERR
; /* errno is set for us. */
1198 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_TYPEDEF
, flag
, 0);
1199 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
1205 ctf_add_volatile (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1207 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_VOLATILE
));
1211 ctf_add_const (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1213 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_CONST
));
1217 ctf_add_restrict (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1219 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_RESTRICT
));
1223 ctf_add_enumerator (ctf_file_t
*fp
, ctf_id_t enid
, const char *name
,
1226 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, enid
);
1229 uint32_t kind
, vlen
, root
;
1233 return (ctf_set_errno (fp
, EINVAL
));
1235 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1236 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1239 return (ctf_set_errno (fp
, ECTF_BADID
));
1241 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1242 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1243 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1245 if (kind
!= CTF_K_ENUM
)
1246 return (ctf_set_errno (fp
, ECTF_NOTENUM
));
1248 if (vlen
== CTF_MAX_VLEN
)
1249 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1251 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1252 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1254 if (strcmp (dmd
->dmd_name
, name
) == 0)
1255 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1258 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1259 return (ctf_set_errno (fp
, EAGAIN
));
1261 if ((s
= ctf_strdup (name
)) == NULL
)
1264 return (ctf_set_errno (fp
, EAGAIN
));
1268 dmd
->dmd_type
= CTF_ERR
;
1269 dmd
->dmd_offset
= 0;
1270 dmd
->dmd_value
= value
;
1272 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1273 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1275 fp
->ctf_flags
|= LCTF_DIRTY
;
1281 ctf_add_member_offset (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1282 ctf_id_t type
, unsigned long bit_offset
)
1284 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, souid
);
1287 ssize_t msize
, malign
, ssize
;
1288 uint32_t kind
, vlen
, root
;
1291 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1292 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1295 return (ctf_set_errno (fp
, ECTF_BADID
));
1297 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1298 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1299 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1301 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1302 return (ctf_set_errno (fp
, ECTF_NOTSOU
));
1304 if (vlen
== CTF_MAX_VLEN
)
1305 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1309 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1310 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1312 if (dmd
->dmd_name
!= NULL
&& strcmp (dmd
->dmd_name
, name
) == 0)
1313 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1317 if ((msize
= ctf_type_size (fp
, type
)) < 0 ||
1318 (malign
= ctf_type_align (fp
, type
)) < 0)
1319 return -1; /* errno is set for us. */
1321 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1322 return (ctf_set_errno (fp
, EAGAIN
));
1324 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1327 return (ctf_set_errno (fp
, EAGAIN
));
1331 dmd
->dmd_type
= type
;
1332 dmd
->dmd_value
= -1;
1334 if (kind
== CTF_K_STRUCT
&& vlen
!= 0)
1336 if (bit_offset
== (unsigned long) - 1)
1338 /* Natural alignment. */
1340 ctf_dmdef_t
*lmd
= ctf_list_prev (&dtd
->dtd_u
.dtu_members
);
1341 ctf_id_t ltype
= ctf_type_resolve (fp
, lmd
->dmd_type
);
1342 size_t off
= lmd
->dmd_offset
;
1344 ctf_encoding_t linfo
;
1347 if (ctf_type_encoding (fp
, ltype
, &linfo
) == 0)
1348 off
+= linfo
.cte_bits
;
1349 else if ((lsize
= ctf_type_size (fp
, ltype
)) > 0)
1350 off
+= lsize
* CHAR_BIT
;
1352 /* Round up the offset of the end of the last member to
1353 the next byte boundary, convert 'off' to bytes, and
1354 then round it up again to the next multiple of the
1355 alignment required by the new member. Finally,
1356 convert back to bits and store the result in
1357 dmd_offset. Technically we could do more efficient
1358 packing if the new member is a bit-field, but we're
1359 the "compiler" and ANSI says we can do as we choose. */
1361 off
= roundup (off
, CHAR_BIT
) / CHAR_BIT
;
1362 off
= roundup (off
, MAX (malign
, 1));
1363 dmd
->dmd_offset
= off
* CHAR_BIT
;
1364 ssize
= off
+ msize
;
1368 /* Specified offset in bits. */
1370 dmd
->dmd_offset
= bit_offset
;
1371 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1372 ssize
= MAX (ssize
, ((signed) bit_offset
/ CHAR_BIT
) + msize
);
1377 dmd
->dmd_offset
= 0;
1378 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1379 ssize
= MAX (ssize
, msize
);
1382 if ((size_t) ssize
> CTF_MAX_SIZE
)
1384 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1385 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (ssize
);
1386 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (ssize
);
1389 dtd
->dtd_data
.ctt_size
= (uint32_t) ssize
;
1391 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1392 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1394 fp
->ctf_flags
|= LCTF_DIRTY
;
1399 ctf_add_member_encoded (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1400 ctf_id_t type
, unsigned long bit_offset
,
1401 const ctf_encoding_t encoding
)
1403 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
1404 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1407 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) && (kind
!= CTF_K_ENUM
))
1408 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1410 if ((type
= ctf_add_slice (fp
, CTF_ADD_NONROOT
, otype
, &encoding
)) == CTF_ERR
)
1411 return -1; /* errno is set for us. */
1413 return ctf_add_member_offset (fp
, souid
, name
, type
, bit_offset
);
1417 ctf_add_member (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1420 return ctf_add_member_offset (fp
, souid
, name
, type
, (unsigned long) - 1);
1424 ctf_add_variable (ctf_file_t
*fp
, const char *name
, ctf_id_t ref
)
1427 ctf_file_t
*tmp
= fp
;
1429 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1430 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1432 if (ctf_dvd_lookup (fp
, name
) != NULL
)
1433 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1435 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1436 return -1; /* errno is set for us. */
1438 if ((dvd
= ctf_alloc (sizeof (ctf_dvdef_t
))) == NULL
)
1439 return (ctf_set_errno (fp
, EAGAIN
));
1441 if (name
!= NULL
&& (dvd
->dvd_name
= ctf_strdup (name
)) == NULL
)
1444 return (ctf_set_errno (fp
, EAGAIN
));
1446 dvd
->dvd_type
= ref
;
1447 dvd
->dvd_snapshots
= fp
->ctf_snapshots
;
1449 if (ctf_dvd_insert (fp
, dvd
) < 0)
1452 return -1; /* errno is set for us. */
1455 fp
->ctf_flags
|= LCTF_DIRTY
;
1460 enumcmp (const char *name
, int value
, void *arg
)
1462 ctf_bundle_t
*ctb
= arg
;
1465 if (ctf_enum_value (ctb
->ctb_file
, ctb
->ctb_type
, name
, &bvalue
) < 0)
1467 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1470 if (value
!= bvalue
)
1472 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1480 enumadd (const char *name
, int value
, void *arg
)
1482 ctf_bundle_t
*ctb
= arg
;
1484 return (ctf_add_enumerator (ctb
->ctb_file
, ctb
->ctb_type
,
1489 membcmp (const char *name
, ctf_id_t type _libctf_unused_
, unsigned long offset
,
1492 ctf_bundle_t
*ctb
= arg
;
1495 if (ctf_member_info (ctb
->ctb_file
, ctb
->ctb_type
, name
, &ctm
) < 0)
1497 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1500 if (ctm
.ctm_offset
!= offset
)
1502 ctf_dprintf ("Conflict due to member %s offset change: "
1503 "%lx versus %lx\n", name
, ctm
.ctm_offset
, offset
);
1510 membadd (const char *name
, ctf_id_t type
, unsigned long offset
, void *arg
)
1512 ctf_bundle_t
*ctb
= arg
;
1516 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1517 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1519 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1522 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1525 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1526 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1528 dmd
->dmd_type
= type
;
1529 dmd
->dmd_offset
= offset
;
1530 dmd
->dmd_value
= -1;
1532 ctf_list_append (&ctb
->ctb_dtd
->dtd_u
.dtu_members
, dmd
);
1534 ctb
->ctb_file
->ctf_flags
|= LCTF_DIRTY
;
1538 /* The ctf_add_type routine is used to copy a type from a source CTF container
1539 to a dynamic destination container. This routine operates recursively by
1540 following the source type's links and embedded member types. If the
1541 destination container already contains a named type which has the same
1542 attributes, then we succeed and return this type but no changes occur. */
1544 ctf_add_type (ctf_file_t
*dst_fp
, ctf_file_t
*src_fp
, ctf_id_t src_type
)
1546 ctf_id_t dst_type
= CTF_ERR
;
1547 uint32_t dst_kind
= CTF_K_UNKNOWN
;
1551 uint32_t kind
, flag
, vlen
;
1553 const ctf_type_t
*src_tp
, *dst_tp
;
1554 ctf_bundle_t src
, dst
;
1555 ctf_encoding_t src_en
, dst_en
;
1556 ctf_arinfo_t src_ar
, dst_ar
;
1562 ctf_id_t orig_src_type
= src_type
;
1564 if (!(dst_fp
->ctf_flags
& LCTF_RDWR
))
1565 return (ctf_set_errno (dst_fp
, ECTF_RDONLY
));
1567 if ((src_tp
= ctf_lookup_by_id (&src_fp
, src_type
)) == NULL
)
1568 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1570 name
= ctf_strptr (src_fp
, src_tp
->ctt_name
);
1571 kind
= LCTF_INFO_KIND (src_fp
, src_tp
->ctt_info
);
1572 flag
= LCTF_INFO_ISROOT (src_fp
, src_tp
->ctt_info
);
1573 vlen
= LCTF_INFO_VLEN (src_fp
, src_tp
->ctt_info
);
1578 hp
= dst_fp
->ctf_structs
;
1581 hp
= dst_fp
->ctf_unions
;
1584 hp
= dst_fp
->ctf_enums
;
1587 hp
= dst_fp
->ctf_names
;
1591 /* If the source type has a name and is a root type (visible at the
1592 top-level scope), lookup the name in the destination container and
1593 verify that it is of the same kind before we do anything else. */
1595 if ((flag
& CTF_ADD_ROOT
) && name
[0] != '\0'
1596 && (tmp
= ctf_hash_lookup_type (hp
, dst_fp
, name
)) != 0)
1599 dst_kind
= ctf_type_kind_unsliced (dst_fp
, dst_type
);
1602 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1603 unless dst_type is a forward declaration and src_type is a struct,
1604 union, or enum (i.e. the definition of the previous forward decl). */
1606 if (dst_type
!= CTF_ERR
&& dst_kind
!= kind
1607 && (dst_kind
!= CTF_K_FORWARD
1608 || (kind
!= CTF_K_ENUM
&& kind
!= CTF_K_STRUCT
1609 && kind
!= CTF_K_UNION
)))
1611 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1612 "old (ID %lx): %i\n", name
, kind
, dst_type
, dst_kind
);
1613 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1616 /* We take special action for an integer, float, or slice since it is
1617 described not only by its name but also its encoding. For integers,
1618 bit-fields exploit this degeneracy. */
1620 if (kind
== CTF_K_INTEGER
|| kind
== CTF_K_FLOAT
|| kind
== CTF_K_SLICE
)
1622 if (ctf_type_encoding (src_fp
, src_type
, &src_en
) != 0)
1623 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1625 if (dst_type
!= CTF_ERR
)
1627 ctf_file_t
*fp
= dst_fp
;
1629 if ((dst_tp
= ctf_lookup_by_id (&fp
, dst_type
)) == NULL
)
1632 if (LCTF_INFO_ISROOT (fp
, dst_tp
->ctt_info
) & CTF_ADD_ROOT
)
1634 /* The type that we found in the hash is also root-visible. If
1635 the two types match then use the existing one; otherwise,
1636 declare a conflict. Note: slices are not certain to match
1637 even if there is no conflict: we must check the contained type
1640 if (ctf_type_encoding (dst_fp
, dst_type
, &dst_en
) != 0)
1641 return CTF_ERR
; /* errno set for us. */
1643 if (memcmp (&src_en
, &dst_en
, sizeof (ctf_encoding_t
)) == 0)
1645 if (kind
!= CTF_K_SLICE
)
1647 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dst_type
);
1653 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1658 /* We found a non-root-visible type in the hash. We reset
1659 dst_type to ensure that we continue to look for a possible
1660 conflict in the pending list. */
1667 /* If the non-empty name was not found in the appropriate hash, search
1668 the list of pending dynamic definitions that are not yet committed.
1669 If a matching name and kind are found, assume this is the type that
1670 we are looking for. This is necessary to permit ctf_add_type() to
1671 operate recursively on entities such as a struct that contains a
1672 pointer member that refers to the same struct type. */
1674 if (dst_type
== CTF_ERR
&& name
[0] != '\0')
1676 for (dtd
= ctf_list_prev (&dst_fp
->ctf_dtdefs
); dtd
!= NULL
1677 && LCTF_TYPE_TO_INDEX (src_fp
, dtd
->dtd_type
) > dst_fp
->ctf_dtoldid
;
1678 dtd
= ctf_list_prev (dtd
))
1680 if (LCTF_INFO_KIND (src_fp
, dtd
->dtd_data
.ctt_info
) == kind
1681 && dtd
->dtd_name
!= NULL
&& strcmp (dtd
->dtd_name
, name
) == 0)
1683 int sroot
; /* Is the src root-visible? */
1684 int droot
; /* Is the dst root-visible? */
1685 int match
; /* Do the encodings match? */
1687 if (kind
!= CTF_K_INTEGER
&& kind
!= CTF_K_FLOAT
&& kind
!= CTF_K_SLICE
)
1689 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dtd
->dtd_type
);
1690 return dtd
->dtd_type
;
1693 sroot
= (flag
& CTF_ADD_ROOT
);
1694 droot
= (LCTF_INFO_ISROOT (dst_fp
,
1696 ctt_info
) & CTF_ADD_ROOT
);
1698 match
= (memcmp (&src_en
, &dtd
->dtd_u
.dtu_enc
,
1699 sizeof (ctf_encoding_t
)) == 0);
1701 /* If the types share the same encoding then return the id of the
1702 first unless one type is root-visible and the other is not; in
1703 that case the new type must get a new id if a match is never
1704 found. Note: slices are not certain to match even if there is
1705 no conflict: we must check the contained type too. */
1707 if (match
&& sroot
== droot
)
1709 if (kind
!= CTF_K_SLICE
)
1711 ctf_add_type_mapping (src_fp
, src_type
, dst_fp
, dtd
->dtd_type
);
1712 return dtd
->dtd_type
;
1715 else if (!match
&& sroot
&& droot
)
1717 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1723 src
.ctb_file
= src_fp
;
1724 src
.ctb_type
= src_type
;
1727 dst
.ctb_file
= dst_fp
;
1728 dst
.ctb_type
= dst_type
;
1731 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1732 we add a new type with the same properties as src_type to dst_fp.
1733 If dst_type is not CTF_ERR, then we verify that dst_type has the
1734 same attributes as src_type. We recurse for embedded references. */
1738 /* If we found a match we will have either returned it or declared a
1740 dst_type
= ctf_add_integer (dst_fp
, flag
, name
, &src_en
);
1744 /* If we found a match we will have either returned it or declared a
1746 dst_type
= ctf_add_float (dst_fp
, flag
, name
, &src_en
);
1750 /* We have checked for conflicting encodings: now try to add the
1752 src_type
= ctf_type_reference (src_fp
, src_type
);
1753 dst_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1755 if (src_type
== CTF_ERR
)
1756 return CTF_ERR
; /* errno is set for us. */
1758 dst_type
= ctf_add_slice (dst_fp
, flag
, src_type
, &src_en
);
1762 case CTF_K_VOLATILE
:
1764 case CTF_K_RESTRICT
:
1765 src_type
= ctf_type_reference (src_fp
, src_type
);
1766 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1768 if (src_type
== CTF_ERR
)
1769 return CTF_ERR
; /* errno is set for us. */
1771 dst_type
= ctf_add_reftype (dst_fp
, flag
, src_type
, kind
);
1775 if (ctf_array_info (src_fp
, src_type
, &src_ar
) != 0)
1776 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1778 src_ar
.ctr_contents
=
1779 ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_contents
);
1780 src_ar
.ctr_index
= ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_index
);
1781 src_ar
.ctr_nelems
= src_ar
.ctr_nelems
;
1783 if (src_ar
.ctr_contents
== CTF_ERR
|| src_ar
.ctr_index
== CTF_ERR
)
1784 return CTF_ERR
; /* errno is set for us. */
1786 if (dst_type
!= CTF_ERR
)
1788 if (ctf_array_info (dst_fp
, dst_type
, &dst_ar
) != 0)
1789 return CTF_ERR
; /* errno is set for us. */
1791 if (memcmp (&src_ar
, &dst_ar
, sizeof (ctf_arinfo_t
)))
1793 ctf_dprintf ("Conflict for type %s against ID %lx: "
1794 "array info differs, old %lx/%lx/%x; "
1795 "new: %lx/%lx/%x\n", name
, dst_type
,
1796 src_ar
.ctr_contents
, src_ar
.ctr_index
,
1797 src_ar
.ctr_nelems
, dst_ar
.ctr_contents
,
1798 dst_ar
.ctr_index
, dst_ar
.ctr_nelems
);
1799 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1803 dst_type
= ctf_add_array (dst_fp
, flag
, &src_ar
);
1806 case CTF_K_FUNCTION
:
1807 ctc
.ctc_return
= ctf_add_type (dst_fp
, src_fp
, src_tp
->ctt_type
);
1811 if (ctc
.ctc_return
== CTF_ERR
)
1812 return CTF_ERR
; /* errno is set for us. */
1814 dst_type
= ctf_add_function (dst_fp
, flag
, &ctc
, NULL
);
1825 /* Technically to match a struct or union we need to check both
1826 ways (src members vs. dst, dst members vs. src) but we make
1827 this more optimal by only checking src vs. dst and comparing
1828 the total size of the structure (which we must do anyway)
1829 which covers the possibility of dst members not in src.
1830 This optimization can be defeated for unions, but is so
1831 pathological as to render it irrelevant for our purposes. */
1833 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1835 if (ctf_type_size (src_fp
, src_type
) !=
1836 ctf_type_size (dst_fp
, dst_type
))
1838 ctf_dprintf ("Conflict for type %s against ID %lx: "
1839 "union size differs, old %li, new %li\n",
1841 (long) ctf_type_size (src_fp
, src_type
),
1842 (long) ctf_type_size (dst_fp
, dst_type
));
1843 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1846 if (ctf_member_iter (src_fp
, src_type
, membcmp
, &dst
))
1848 ctf_dprintf ("Conflict for type %s against ID %lx: "
1849 "members differ, see above\n", name
, dst_type
);
1850 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1856 /* Unlike the other cases, copying structs and unions is done
1857 manually so as to avoid repeated lookups in ctf_add_member
1858 and to ensure the exact same member offsets as in src_type. */
1860 dst_type
= ctf_add_generic (dst_fp
, flag
, name
, &dtd
);
1861 if (dst_type
== CTF_ERR
)
1862 return CTF_ERR
; /* errno is set for us. */
1864 dst
.ctb_type
= dst_type
;
1867 if (ctf_member_iter (src_fp
, src_type
, membadd
, &dst
) != 0)
1868 errs
++; /* Increment errs and fail at bottom of case. */
1870 if ((ssize
= ctf_type_size (src_fp
, src_type
)) < 0)
1871 return CTF_ERR
; /* errno is set for us. */
1873 size
= (size_t) ssize
;
1874 if (size
> CTF_MAX_SIZE
)
1876 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1877 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1878 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1881 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1883 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, vlen
);
1885 /* Make a final pass through the members changing each dmd_type (a
1886 src_fp type) to an equivalent type in dst_fp. We pass through all
1887 members, leaving any that fail set to CTF_ERR. */
1888 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1889 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1891 if ((dmd
->dmd_type
= ctf_add_type (dst_fp
, src_fp
,
1892 dmd
->dmd_type
)) == CTF_ERR
)
1897 return CTF_ERR
; /* errno is set for us. */
1902 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1904 if (ctf_enum_iter (src_fp
, src_type
, enumcmp
, &dst
)
1905 || ctf_enum_iter (dst_fp
, dst_type
, enumcmp
, &src
))
1907 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1908 "members differ, see above\n", name
, dst_type
);
1909 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1914 dst_type
= ctf_add_enum (dst_fp
, flag
, name
);
1915 if ((dst
.ctb_type
= dst_type
) == CTF_ERR
1916 || ctf_enum_iter (src_fp
, src_type
, enumadd
, &dst
))
1917 return CTF_ERR
; /* errno is set for us */
1922 if (dst_type
== CTF_ERR
)
1924 dst_type
= ctf_add_forward (dst_fp
, flag
,
1925 name
, CTF_K_STRUCT
); /* Assume STRUCT. */
1930 src_type
= ctf_type_reference (src_fp
, src_type
);
1931 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1933 if (src_type
== CTF_ERR
)
1934 return CTF_ERR
; /* errno is set for us. */
1936 /* If dst_type is not CTF_ERR at this point, we should check if
1937 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1938 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1939 that vary based on things like if 32-bit then pid_t is int otherwise
1940 long. We therefore omit this check and assume that if the identically
1941 named typedef already exists in dst_fp, it is correct or
1944 if (dst_type
== CTF_ERR
)
1946 dst_type
= ctf_add_typedef (dst_fp
, flag
, name
, src_type
);
1951 return (ctf_set_errno (dst_fp
, ECTF_CORRUPT
));
1954 if (dst_type
!= CTF_ERR
)
1955 ctf_add_type_mapping (src_fp
, orig_src_type
, dst_fp
, dst_type
);
1959 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1961 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1963 const unsigned char *buf
;
1967 resid
= sizeof (ctf_header_t
);
1968 buf
= (unsigned char *) fp
->ctf_header
;
1971 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1972 return (ctf_set_errno (fp
, errno
));
1977 resid
= fp
->ctf_size
;
1981 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1982 return (ctf_set_errno (fp
, errno
));
1990 /* Compress the specified CTF data stream and write it to the specified file
1993 ctf_compress_write (ctf_file_t
*fp
, int fd
)
1998 ctf_header_t
*hp
= &h
;
1999 ssize_t header_len
= sizeof (ctf_header_t
);
2000 ssize_t compress_len
;
2001 size_t max_compress_len
= compressBound (fp
->ctf_size
);
2006 memcpy (hp
, fp
->ctf_header
, header_len
);
2007 hp
->cth_flags
|= CTF_F_COMPRESS
;
2009 if ((buf
= ctf_alloc (max_compress_len
)) == NULL
)
2010 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
2012 compress_len
= max_compress_len
;
2013 if ((rc
= compress (buf
, (uLongf
*) &compress_len
,
2014 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2016 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2017 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
2021 while (header_len
> 0)
2023 if ((len
= write (fd
, hp
, header_len
)) < 0)
2025 err
= ctf_set_errno (fp
, errno
);
2033 while (compress_len
> 0)
2035 if ((len
= write (fd
, bp
, compress_len
)) < 0)
2037 err
= ctf_set_errno (fp
, errno
);
2040 compress_len
-= len
;
2049 /* Optionally compress the specified CTF data stream and return it as a new
2050 dynamically-allocated string. */
2052 ctf_write_mem (ctf_file_t
*fp
, size_t *size
, size_t threshold
)
2057 ssize_t header_len
= sizeof (ctf_header_t
);
2058 ssize_t compress_len
;
2059 size_t max_compress_len
= compressBound (fp
->ctf_size
);
2062 if (fp
->ctf_size
< threshold
)
2063 max_compress_len
= fp
->ctf_size
;
2064 if ((buf
= malloc (max_compress_len
2065 + sizeof (struct ctf_header
))) == NULL
)
2067 ctf_set_errno (fp
, ENOMEM
);
2071 hp
= (ctf_header_t
*) buf
;
2072 memcpy (hp
, fp
->ctf_header
, header_len
);
2073 bp
= buf
+ sizeof (struct ctf_header
);
2074 *size
= sizeof (struct ctf_header
);
2076 compress_len
= max_compress_len
;
2078 if (fp
->ctf_size
< threshold
)
2080 hp
->cth_flags
&= ~CTF_F_COMPRESS
;
2081 memcpy (bp
, fp
->ctf_buf
, fp
->ctf_size
);
2082 *size
+= fp
->ctf_size
;
2086 hp
->cth_flags
|= CTF_F_COMPRESS
;
2087 if ((rc
= compress (bp
, (uLongf
*) &compress_len
,
2088 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2090 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2091 ctf_set_errno (fp
, ECTF_COMPRESS
);
2095 *size
+= compress_len
;
2100 /* Write the uncompressed CTF data stream to the specified file descriptor. */
2102 ctf_write (ctf_file_t
*fp
, int fd
)
2104 const unsigned char *buf
;
2108 resid
= sizeof (ctf_header_t
);
2109 buf
= (unsigned char *) fp
->ctf_header
;
2112 if ((len
= write (fd
, buf
, resid
)) <= 0)
2113 return (ctf_set_errno (fp
, errno
));
2118 resid
= fp
->ctf_size
;
2122 if ((len
= write (fd
, buf
, resid
)) <= 0)
2123 return (ctf_set_errno (fp
, errno
));