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
;
477 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
479 fp
->ctf_dtbyname
= NULL
;
480 fp
->ctf_dthash
= NULL
;
481 ctf_str_free_atoms (nfp
);
482 nfp
->ctf_str_atoms
= fp
->ctf_str_atoms
;
483 fp
->ctf_str_atoms
= NULL
;
484 memset (&fp
->ctf_dtdefs
, 0, sizeof (ctf_list_t
));
485 fp
->ctf_link_inputs
= NULL
;
486 fp
->ctf_link_outputs
= NULL
;
487 fp
->ctf_syn_ext_strtab
= NULL
;
489 fp
->ctf_dvhash
= NULL
;
490 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
492 memcpy (&ofp
, fp
, sizeof (ctf_file_t
));
493 memcpy (fp
, nfp
, sizeof (ctf_file_t
));
494 memcpy (nfp
, &ofp
, sizeof (ctf_file_t
));
496 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
497 array of type name prefixes and the corresponding ctf_dynhash to use.
498 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
500 fp
->ctf_lookups
[0].ctl_hash
= fp
->ctf_structs
;
501 fp
->ctf_lookups
[1].ctl_hash
= fp
->ctf_unions
;
502 fp
->ctf_lookups
[2].ctl_hash
= fp
->ctf_enums
;
503 fp
->ctf_lookups
[3].ctl_hash
= fp
->ctf_names
;
505 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
506 ctf_file_close (nfp
);
512 ctf_prefixed_name (int kind
, const char *name
)
519 prefixed
= ctf_strdup ("struct ");
522 prefixed
= ctf_strdup ("union ");
525 prefixed
= ctf_strdup ("enum ");
528 prefixed
= ctf_strdup ("");
531 prefixed
= ctf_str_append (prefixed
, name
);
536 ctf_dtd_insert (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
538 if (ctf_dynhash_insert (fp
->ctf_dthash
, (void *) dtd
->dtd_type
, dtd
) < 0)
543 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
544 if (ctf_dynhash_insert (fp
->ctf_dtbyname
,
545 ctf_prefixed_name (kind
, dtd
->dtd_name
),
549 ctf_list_append (&fp
->ctf_dtdefs
, dtd
);
554 ctf_dtd_delete (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
556 ctf_dmdef_t
*dmd
, *nmd
;
557 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
559 ctf_dynhash_remove (fp
->ctf_dthash
, (void *) dtd
->dtd_type
);
566 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
567 dmd
!= NULL
; dmd
= nmd
)
569 if (dmd
->dmd_name
!= NULL
)
570 ctf_free (dmd
->dmd_name
);
571 nmd
= ctf_list_next (dmd
);
576 ctf_free (dtd
->dtd_u
.dtu_argv
);
584 name
= ctf_prefixed_name (kind
, dtd
->dtd_name
);
585 ctf_dynhash_remove (fp
->ctf_dtbyname
, name
);
587 ctf_free (dtd
->dtd_name
);
590 ctf_list_delete (&fp
->ctf_dtdefs
, dtd
);
595 ctf_dtd_lookup (const ctf_file_t
*fp
, ctf_id_t type
)
597 return (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dthash
, (void *) type
);
601 ctf_dtd_lookup_type_by_name (ctf_file_t
*fp
, int kind
, const char *name
)
604 char *decorated
= ctf_prefixed_name (kind
, name
);
606 dtd
= (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dtbyname
, decorated
);
610 return dtd
->dtd_type
;
616 ctf_dynamic_type (const ctf_file_t
*fp
, ctf_id_t id
)
620 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, id
))
623 idx
= LCTF_TYPE_TO_INDEX(fp
, id
);
625 if (((unsigned long) idx
> fp
->ctf_typemax
) &&
626 ((unsigned long) idx
< fp
->ctf_dtnextid
))
627 return ctf_dtd_lookup (fp
, id
);
632 ctf_dvd_insert (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
634 if (ctf_dynhash_insert (fp
->ctf_dvhash
, dvd
->dvd_name
, dvd
) < 0)
636 ctf_list_append (&fp
->ctf_dvdefs
, dvd
);
641 ctf_dvd_delete (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
643 ctf_dynhash_remove (fp
->ctf_dvhash
, dvd
->dvd_name
);
644 ctf_free (dvd
->dvd_name
);
646 ctf_list_delete (&fp
->ctf_dvdefs
, dvd
);
651 ctf_dvd_lookup (const ctf_file_t
*fp
, const char *name
)
653 return (ctf_dvdef_t
*) ctf_dynhash_lookup (fp
->ctf_dvhash
, name
);
656 /* Discard all of the dynamic type definitions and variable definitions that
657 have been added to the container since the last call to ctf_update(). We
658 locate such types by scanning the dtd list and deleting elements that have
659 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
660 by scanning the variable list and deleting elements that have update IDs
661 equal to the current value of the last-update snapshot count (indicating that
662 they were added after the most recent call to ctf_update()). */
664 ctf_discard (ctf_file_t
*fp
)
666 ctf_snapshot_id_t last_update
=
668 fp
->ctf_snapshot_lu
+ 1 };
670 /* Update required? */
671 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
674 return (ctf_rollback (fp
, last_update
));
678 ctf_snapshot (ctf_file_t
*fp
)
680 ctf_snapshot_id_t snapid
;
681 snapid
.dtd_id
= fp
->ctf_dtnextid
- 1;
682 snapid
.snapshot_id
= fp
->ctf_snapshots
++;
686 /* Like ctf_discard(), only discards everything after a particular ID. */
688 ctf_rollback (ctf_file_t
*fp
, ctf_snapshot_id_t id
)
690 ctf_dtdef_t
*dtd
, *ntd
;
691 ctf_dvdef_t
*dvd
, *nvd
;
693 if (!(fp
->ctf_flags
& LCTF_RDWR
))
694 return (ctf_set_errno (fp
, ECTF_RDONLY
));
696 if (fp
->ctf_dtoldid
> id
.dtd_id
)
697 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
699 if (fp
->ctf_snapshot_lu
>= id
.snapshot_id
)
700 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
702 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
); dtd
!= NULL
; dtd
= ntd
)
704 ntd
= ctf_list_next (dtd
);
706 if (LCTF_TYPE_TO_INDEX (fp
, dtd
->dtd_type
) <= id
.dtd_id
)
709 ctf_dtd_delete (fp
, dtd
);
712 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
714 nvd
= ctf_list_next (dvd
);
716 if (dvd
->dvd_snapshots
<= id
.snapshot_id
)
719 ctf_dvd_delete (fp
, dvd
);
722 fp
->ctf_dtnextid
= id
.dtd_id
+ 1;
723 fp
->ctf_snapshots
= id
.snapshot_id
;
725 if (fp
->ctf_snapshots
== fp
->ctf_snapshot_lu
)
726 fp
->ctf_flags
&= ~LCTF_DIRTY
;
732 ctf_add_generic (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
739 if (flag
!= CTF_ADD_NONROOT
&& flag
!= CTF_ADD_ROOT
)
740 return (ctf_set_errno (fp
, EINVAL
));
742 if (!(fp
->ctf_flags
& LCTF_RDWR
))
743 return (ctf_set_errno (fp
, ECTF_RDONLY
));
745 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) > CTF_MAX_TYPE
)
746 return (ctf_set_errno (fp
, ECTF_FULL
));
748 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) == CTF_MAX_PTYPE
)
749 return (ctf_set_errno (fp
, ECTF_FULL
));
751 if ((dtd
= ctf_alloc (sizeof (ctf_dtdef_t
))) == NULL
)
752 return (ctf_set_errno (fp
, EAGAIN
));
754 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
757 return (ctf_set_errno (fp
, EAGAIN
));
760 type
= fp
->ctf_dtnextid
++;
761 type
= LCTF_INDEX_TO_TYPE (fp
, type
, (fp
->ctf_flags
& LCTF_CHILD
));
763 memset (dtd
, 0, sizeof (ctf_dtdef_t
));
765 dtd
->dtd_type
= type
;
767 if (ctf_dtd_insert (fp
, dtd
) < 0)
770 return CTF_ERR
; /* errno is set for us. */
772 fp
->ctf_flags
|= LCTF_DIRTY
;
778 /* When encoding integer sizes, we want to convert a byte count in the range
779 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
780 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
796 ctf_add_encoded (ctf_file_t
*fp
, uint32_t flag
,
797 const char *name
, const ctf_encoding_t
*ep
, uint32_t kind
)
803 return (ctf_set_errno (fp
, EINVAL
));
805 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
806 return CTF_ERR
; /* errno is set for us. */
808 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
809 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
811 dtd
->dtd_u
.dtu_enc
= *ep
;
817 ctf_add_reftype (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
, uint32_t kind
)
821 ctf_file_t
*tmp
= fp
;
823 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
824 return (ctf_set_errno (fp
, EINVAL
));
826 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
827 return CTF_ERR
; /* errno is set for us. */
829 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
830 return CTF_ERR
; /* errno is set for us. */
832 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
833 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
839 ctf_add_slice (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
,
840 const ctf_encoding_t
*ep
)
845 const ctf_type_t
*tp
;
846 ctf_file_t
*tmp
= fp
;
849 return (ctf_set_errno (fp
, EINVAL
));
851 if ((ep
->cte_bits
> 255) || (ep
->cte_offset
> 255))
852 return (ctf_set_errno (fp
, ECTF_SLICEOVERFLOW
));
854 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
855 return (ctf_set_errno (fp
, EINVAL
));
857 if ((tp
= ctf_lookup_by_id (&tmp
, ref
)) == NULL
)
858 return CTF_ERR
; /* errno is set for us. */
860 kind
= ctf_type_kind_unsliced (tmp
, ref
);
861 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) &&
862 (kind
!= CTF_K_ENUM
))
863 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
865 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
866 return CTF_ERR
; /* errno is set for us. */
868 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_SLICE
, flag
, 0);
869 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
871 dtd
->dtd_u
.dtu_slice
.cts_type
= ref
;
872 dtd
->dtd_u
.dtu_slice
.cts_bits
= ep
->cte_bits
;
873 dtd
->dtd_u
.dtu_slice
.cts_offset
= ep
->cte_offset
;
879 ctf_add_integer (ctf_file_t
*fp
, uint32_t flag
,
880 const char *name
, const ctf_encoding_t
*ep
)
882 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_INTEGER
));
886 ctf_add_float (ctf_file_t
*fp
, uint32_t flag
,
887 const char *name
, const ctf_encoding_t
*ep
)
889 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_FLOAT
));
893 ctf_add_pointer (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
895 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_POINTER
));
899 ctf_add_array (ctf_file_t
*fp
, uint32_t flag
, const ctf_arinfo_t
*arp
)
903 ctf_file_t
*tmp
= fp
;
906 return (ctf_set_errno (fp
, EINVAL
));
908 if (ctf_lookup_by_id (&tmp
, arp
->ctr_contents
) == NULL
)
909 return CTF_ERR
; /* errno is set for us. */
912 if (ctf_lookup_by_id (&tmp
, arp
->ctr_index
) == NULL
)
913 return CTF_ERR
; /* errno is set for us. */
915 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
916 return CTF_ERR
; /* errno is set for us. */
918 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ARRAY
, flag
, 0);
919 dtd
->dtd_data
.ctt_size
= 0;
920 dtd
->dtd_u
.dtu_arr
= *arp
;
926 ctf_set_array (ctf_file_t
*fp
, ctf_id_t type
, const ctf_arinfo_t
*arp
)
928 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
930 if (!(fp
->ctf_flags
& LCTF_RDWR
))
931 return (ctf_set_errno (fp
, ECTF_RDONLY
));
934 || LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
) != CTF_K_ARRAY
)
935 return (ctf_set_errno (fp
, ECTF_BADID
));
937 fp
->ctf_flags
|= LCTF_DIRTY
;
938 dtd
->dtd_u
.dtu_arr
= *arp
;
944 ctf_add_function (ctf_file_t
*fp
, uint32_t flag
,
945 const ctf_funcinfo_t
*ctc
, const ctf_id_t
*argv
)
950 ctf_id_t
*vdat
= NULL
;
951 ctf_file_t
*tmp
= fp
;
954 if (ctc
== NULL
|| (ctc
->ctc_flags
& ~CTF_FUNC_VARARG
) != 0
955 || (ctc
->ctc_argc
!= 0 && argv
== NULL
))
956 return (ctf_set_errno (fp
, EINVAL
));
958 vlen
= ctc
->ctc_argc
;
959 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
960 vlen
++; /* Add trailing zero to indicate varargs (see below). */
962 if (ctf_lookup_by_id (&tmp
, ctc
->ctc_return
) == NULL
)
963 return CTF_ERR
; /* errno is set for us. */
965 for (i
= 0; i
< ctc
->ctc_argc
; i
++)
968 if (ctf_lookup_by_id (&tmp
, argv
[i
]) == NULL
)
969 return CTF_ERR
; /* errno is set for us. */
972 if (vlen
> CTF_MAX_VLEN
)
973 return (ctf_set_errno (fp
, EOVERFLOW
));
975 if (vlen
!= 0 && (vdat
= ctf_alloc (sizeof (ctf_id_t
) * vlen
)) == NULL
)
976 return (ctf_set_errno (fp
, EAGAIN
));
978 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
981 return CTF_ERR
; /* errno is set for us. */
984 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FUNCTION
, flag
, vlen
);
985 dtd
->dtd_data
.ctt_type
= (uint32_t) ctc
->ctc_return
;
987 memcpy (vdat
, argv
, sizeof (ctf_id_t
) * ctc
->ctc_argc
);
988 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
989 vdat
[vlen
- 1] = 0; /* Add trailing zero to indicate varargs. */
990 dtd
->dtd_u
.dtu_argv
= vdat
;
996 ctf_add_struct_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
999 ctf_hash_t
*hp
= fp
->ctf_structs
;
1003 /* Promote forwards to structs. */
1007 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1009 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_STRUCT
, name
);
1012 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1013 dtd
= ctf_dtd_lookup (fp
, type
);
1014 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1015 return CTF_ERR
; /* errno is set for us. */
1017 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_STRUCT
, flag
, 0);
1019 if (size
> CTF_MAX_SIZE
)
1021 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1022 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1023 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1026 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1032 ctf_add_struct (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1034 return (ctf_add_struct_sized (fp
, flag
, name
, 0));
1038 ctf_add_union_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1041 ctf_hash_t
*hp
= fp
->ctf_unions
;
1045 /* Promote forwards to unions. */
1048 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1050 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_UNION
, name
);
1053 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1054 dtd
= ctf_dtd_lookup (fp
, type
);
1055 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1056 return CTF_ERR
; /* errno is set for us */
1058 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_UNION
, flag
, 0);
1060 if (size
> CTF_MAX_SIZE
)
1062 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1063 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1064 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1067 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1073 ctf_add_union (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1075 return (ctf_add_union_sized (fp
, flag
, name
, 0));
1079 ctf_add_enum (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1081 ctf_hash_t
*hp
= fp
->ctf_enums
;
1085 /* Promote forwards to enums. */
1088 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1090 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1093 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1094 dtd
= ctf_dtd_lookup (fp
, type
);
1095 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1096 return CTF_ERR
; /* errno is set for us. */
1098 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ENUM
, flag
, 0);
1099 dtd
->dtd_data
.ctt_size
= fp
->ctf_dmodel
->ctd_int
;
1105 ctf_add_enum_encoded (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1106 const ctf_encoding_t
*ep
)
1108 ctf_hash_t
*hp
= fp
->ctf_enums
;
1111 /* First, create the enum if need be, using most of the same machinery as
1112 ctf_add_enum(), to ensure that we do not allow things past that are not
1113 enums or forwards to them. (This includes other slices: you cannot slice a
1114 slice, which would be a useless thing to do anyway.) */
1118 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1120 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1125 if ((ctf_type_kind (fp
, type
) != CTF_K_FORWARD
) &&
1126 (ctf_type_kind_unsliced (fp
, type
) != CTF_K_ENUM
))
1127 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1129 else if ((type
= ctf_add_enum (fp
, flag
, name
)) == CTF_ERR
)
1130 return CTF_ERR
; /* errno is set for us. */
1132 /* Now attach a suitable slice to it. */
1134 return ctf_add_slice (fp
, flag
, type
, ep
);
1138 ctf_add_forward (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1148 hp
= fp
->ctf_structs
;
1151 hp
= fp
->ctf_unions
;
1157 return (ctf_set_errno (fp
, ECTF_NOTSUE
));
1160 /* If the type is already defined or exists as a forward tag, just
1161 return the ctf_id_t of the existing definition. */
1165 if (((type
= ctf_hash_lookup_type (hp
, fp
, name
)) != 0)
1166 || (type
= ctf_dtd_lookup_type_by_name (fp
, kind
, name
)) != 0)
1170 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1171 return CTF_ERR
; /* errno is set for us. */
1173 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FORWARD
, flag
, 0);
1174 dtd
->dtd_data
.ctt_type
= kind
;
1180 ctf_add_typedef (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1185 ctf_file_t
*tmp
= fp
;
1187 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
1188 return (ctf_set_errno (fp
, EINVAL
));
1190 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1191 return CTF_ERR
; /* errno is set for us. */
1193 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1194 return CTF_ERR
; /* errno is set for us. */
1196 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_TYPEDEF
, flag
, 0);
1197 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
1203 ctf_add_volatile (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1205 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_VOLATILE
));
1209 ctf_add_const (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1211 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_CONST
));
1215 ctf_add_restrict (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1217 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_RESTRICT
));
1221 ctf_add_enumerator (ctf_file_t
*fp
, ctf_id_t enid
, const char *name
,
1224 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, enid
);
1227 uint32_t kind
, vlen
, root
;
1231 return (ctf_set_errno (fp
, EINVAL
));
1233 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1234 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1237 return (ctf_set_errno (fp
, ECTF_BADID
));
1239 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1240 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1241 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1243 if (kind
!= CTF_K_ENUM
)
1244 return (ctf_set_errno (fp
, ECTF_NOTENUM
));
1246 if (vlen
== CTF_MAX_VLEN
)
1247 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1249 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1250 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1252 if (strcmp (dmd
->dmd_name
, name
) == 0)
1253 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1256 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1257 return (ctf_set_errno (fp
, EAGAIN
));
1259 if ((s
= ctf_strdup (name
)) == NULL
)
1262 return (ctf_set_errno (fp
, EAGAIN
));
1266 dmd
->dmd_type
= CTF_ERR
;
1267 dmd
->dmd_offset
= 0;
1268 dmd
->dmd_value
= value
;
1270 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1271 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1273 fp
->ctf_flags
|= LCTF_DIRTY
;
1279 ctf_add_member_offset (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1280 ctf_id_t type
, unsigned long bit_offset
)
1282 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, souid
);
1285 ssize_t msize
, malign
, ssize
;
1286 uint32_t kind
, vlen
, root
;
1289 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1290 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1293 return (ctf_set_errno (fp
, ECTF_BADID
));
1295 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1296 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1297 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1299 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1300 return (ctf_set_errno (fp
, ECTF_NOTSOU
));
1302 if (vlen
== CTF_MAX_VLEN
)
1303 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1307 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1308 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1310 if (dmd
->dmd_name
!= NULL
&& strcmp (dmd
->dmd_name
, name
) == 0)
1311 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1315 if ((msize
= ctf_type_size (fp
, type
)) < 0 ||
1316 (malign
= ctf_type_align (fp
, type
)) < 0)
1317 return -1; /* errno is set for us. */
1319 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1320 return (ctf_set_errno (fp
, EAGAIN
));
1322 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1325 return (ctf_set_errno (fp
, EAGAIN
));
1329 dmd
->dmd_type
= type
;
1330 dmd
->dmd_value
= -1;
1332 if (kind
== CTF_K_STRUCT
&& vlen
!= 0)
1334 if (bit_offset
== (unsigned long) - 1)
1336 /* Natural alignment. */
1338 ctf_dmdef_t
*lmd
= ctf_list_prev (&dtd
->dtd_u
.dtu_members
);
1339 ctf_id_t ltype
= ctf_type_resolve (fp
, lmd
->dmd_type
);
1340 size_t off
= lmd
->dmd_offset
;
1342 ctf_encoding_t linfo
;
1345 if (ctf_type_encoding (fp
, ltype
, &linfo
) == 0)
1346 off
+= linfo
.cte_bits
;
1347 else if ((lsize
= ctf_type_size (fp
, ltype
)) > 0)
1348 off
+= lsize
* CHAR_BIT
;
1350 /* Round up the offset of the end of the last member to
1351 the next byte boundary, convert 'off' to bytes, and
1352 then round it up again to the next multiple of the
1353 alignment required by the new member. Finally,
1354 convert back to bits and store the result in
1355 dmd_offset. Technically we could do more efficient
1356 packing if the new member is a bit-field, but we're
1357 the "compiler" and ANSI says we can do as we choose. */
1359 off
= roundup (off
, CHAR_BIT
) / CHAR_BIT
;
1360 off
= roundup (off
, MAX (malign
, 1));
1361 dmd
->dmd_offset
= off
* CHAR_BIT
;
1362 ssize
= off
+ msize
;
1366 /* Specified offset in bits. */
1368 dmd
->dmd_offset
= bit_offset
;
1369 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1370 ssize
= MAX (ssize
, ((signed) bit_offset
/ CHAR_BIT
) + msize
);
1375 dmd
->dmd_offset
= 0;
1376 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1377 ssize
= MAX (ssize
, msize
);
1380 if ((size_t) ssize
> CTF_MAX_SIZE
)
1382 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1383 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (ssize
);
1384 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (ssize
);
1387 dtd
->dtd_data
.ctt_size
= (uint32_t) ssize
;
1389 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1390 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1392 fp
->ctf_flags
|= LCTF_DIRTY
;
1397 ctf_add_member_encoded (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1398 ctf_id_t type
, unsigned long bit_offset
,
1399 const ctf_encoding_t encoding
)
1401 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
1402 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1405 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) && (kind
!= CTF_K_ENUM
))
1406 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1408 if ((type
= ctf_add_slice (fp
, CTF_ADD_NONROOT
, otype
, &encoding
)) == CTF_ERR
)
1409 return -1; /* errno is set for us. */
1411 return ctf_add_member_offset (fp
, souid
, name
, type
, bit_offset
);
1415 ctf_add_member (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1418 return ctf_add_member_offset (fp
, souid
, name
, type
, (unsigned long) - 1);
1422 ctf_add_variable (ctf_file_t
*fp
, const char *name
, ctf_id_t ref
)
1425 ctf_file_t
*tmp
= fp
;
1427 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1428 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1430 if (ctf_dvd_lookup (fp
, name
) != NULL
)
1431 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1433 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1434 return -1; /* errno is set for us. */
1436 if ((dvd
= ctf_alloc (sizeof (ctf_dvdef_t
))) == NULL
)
1437 return (ctf_set_errno (fp
, EAGAIN
));
1439 if (name
!= NULL
&& (dvd
->dvd_name
= ctf_strdup (name
)) == NULL
)
1442 return (ctf_set_errno (fp
, EAGAIN
));
1444 dvd
->dvd_type
= ref
;
1445 dvd
->dvd_snapshots
= fp
->ctf_snapshots
;
1447 if (ctf_dvd_insert (fp
, dvd
) < 0)
1450 return -1; /* errno is set for us. */
1453 fp
->ctf_flags
|= LCTF_DIRTY
;
1458 enumcmp (const char *name
, int value
, void *arg
)
1460 ctf_bundle_t
*ctb
= arg
;
1463 if (ctf_enum_value (ctb
->ctb_file
, ctb
->ctb_type
, name
, &bvalue
) < 0)
1465 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1468 if (value
!= bvalue
)
1470 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1478 enumadd (const char *name
, int value
, void *arg
)
1480 ctf_bundle_t
*ctb
= arg
;
1482 return (ctf_add_enumerator (ctb
->ctb_file
, ctb
->ctb_type
,
1487 membcmp (const char *name
, ctf_id_t type _libctf_unused_
, unsigned long offset
,
1490 ctf_bundle_t
*ctb
= arg
;
1493 if (ctf_member_info (ctb
->ctb_file
, ctb
->ctb_type
, name
, &ctm
) < 0)
1495 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1498 if (ctm
.ctm_offset
!= offset
)
1500 ctf_dprintf ("Conflict due to member %s offset change: "
1501 "%lx versus %lx\n", name
, ctm
.ctm_offset
, offset
);
1508 membadd (const char *name
, ctf_id_t type
, unsigned long offset
, void *arg
)
1510 ctf_bundle_t
*ctb
= arg
;
1514 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1515 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1517 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1520 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1523 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1524 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1526 dmd
->dmd_type
= type
;
1527 dmd
->dmd_offset
= offset
;
1528 dmd
->dmd_value
= -1;
1530 ctf_list_append (&ctb
->ctb_dtd
->dtd_u
.dtu_members
, dmd
);
1532 ctb
->ctb_file
->ctf_flags
|= LCTF_DIRTY
;
1536 /* The ctf_add_type routine is used to copy a type from a source CTF container
1537 to a dynamic destination container. This routine operates recursively by
1538 following the source type's links and embedded member types. If the
1539 destination container already contains a named type which has the same
1540 attributes, then we succeed and return this type but no changes occur. */
1542 ctf_add_type (ctf_file_t
*dst_fp
, ctf_file_t
*src_fp
, ctf_id_t src_type
)
1544 ctf_id_t dst_type
= CTF_ERR
;
1545 uint32_t dst_kind
= CTF_K_UNKNOWN
;
1549 uint32_t kind
, flag
, vlen
;
1551 const ctf_type_t
*src_tp
, *dst_tp
;
1552 ctf_bundle_t src
, dst
;
1553 ctf_encoding_t src_en
, dst_en
;
1554 ctf_arinfo_t src_ar
, dst_ar
;
1561 if (!(dst_fp
->ctf_flags
& LCTF_RDWR
))
1562 return (ctf_set_errno (dst_fp
, ECTF_RDONLY
));
1564 if ((src_tp
= ctf_lookup_by_id (&src_fp
, src_type
)) == NULL
)
1565 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1567 name
= ctf_strptr (src_fp
, src_tp
->ctt_name
);
1568 kind
= LCTF_INFO_KIND (src_fp
, src_tp
->ctt_info
);
1569 flag
= LCTF_INFO_ISROOT (src_fp
, src_tp
->ctt_info
);
1570 vlen
= LCTF_INFO_VLEN (src_fp
, src_tp
->ctt_info
);
1575 hp
= dst_fp
->ctf_structs
;
1578 hp
= dst_fp
->ctf_unions
;
1581 hp
= dst_fp
->ctf_enums
;
1584 hp
= dst_fp
->ctf_names
;
1588 /* If the source type has a name and is a root type (visible at the
1589 top-level scope), lookup the name in the destination container and
1590 verify that it is of the same kind before we do anything else. */
1592 if ((flag
& CTF_ADD_ROOT
) && name
[0] != '\0'
1593 && (tmp
= ctf_hash_lookup_type (hp
, dst_fp
, name
)) != 0)
1596 dst_kind
= ctf_type_kind_unsliced (dst_fp
, dst_type
);
1599 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1600 unless dst_type is a forward declaration and src_type is a struct,
1601 union, or enum (i.e. the definition of the previous forward decl). */
1603 if (dst_type
!= CTF_ERR
&& dst_kind
!= kind
1604 && (dst_kind
!= CTF_K_FORWARD
1605 || (kind
!= CTF_K_ENUM
&& kind
!= CTF_K_STRUCT
1606 && kind
!= CTF_K_UNION
)))
1608 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1609 "old (ID %lx): %i\n", name
, kind
, dst_type
, dst_kind
);
1610 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1613 /* We take special action for an integer, float, or slice since it is
1614 described not only by its name but also its encoding. For integers,
1615 bit-fields exploit this degeneracy. */
1617 if (kind
== CTF_K_INTEGER
|| kind
== CTF_K_FLOAT
|| kind
== CTF_K_SLICE
)
1619 if (ctf_type_encoding (src_fp
, src_type
, &src_en
) != 0)
1620 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1622 if (dst_type
!= CTF_ERR
)
1624 ctf_file_t
*fp
= dst_fp
;
1626 if ((dst_tp
= ctf_lookup_by_id (&fp
, dst_type
)) == NULL
)
1629 if (LCTF_INFO_ISROOT (fp
, dst_tp
->ctt_info
) & CTF_ADD_ROOT
)
1631 /* The type that we found in the hash is also root-visible. If
1632 the two types match then use the existing one; otherwise,
1633 declare a conflict. Note: slices are not certain to match
1634 even if there is no conflict: we must check the contained type
1637 if (ctf_type_encoding (dst_fp
, dst_type
, &dst_en
) != 0)
1638 return CTF_ERR
; /* errno set for us. */
1640 if (memcmp (&src_en
, &dst_en
, sizeof (ctf_encoding_t
)) == 0)
1642 if (kind
!= CTF_K_SLICE
)
1647 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1652 /* We found a non-root-visible type in the hash. We reset
1653 dst_type to ensure that we continue to look for a possible
1654 conflict in the pending list. */
1661 /* If the non-empty name was not found in the appropriate hash, search
1662 the list of pending dynamic definitions that are not yet committed.
1663 If a matching name and kind are found, assume this is the type that
1664 we are looking for. This is necessary to permit ctf_add_type() to
1665 operate recursively on entities such as a struct that contains a
1666 pointer member that refers to the same struct type. */
1668 if (dst_type
== CTF_ERR
&& name
[0] != '\0')
1670 for (dtd
= ctf_list_prev (&dst_fp
->ctf_dtdefs
); dtd
!= NULL
1671 && LCTF_TYPE_TO_INDEX (src_fp
, dtd
->dtd_type
) > dst_fp
->ctf_dtoldid
;
1672 dtd
= ctf_list_prev (dtd
))
1674 if (LCTF_INFO_KIND (src_fp
, dtd
->dtd_data
.ctt_info
) == kind
1675 && dtd
->dtd_name
!= NULL
&& strcmp (dtd
->dtd_name
, name
) == 0)
1677 int sroot
; /* Is the src root-visible? */
1678 int droot
; /* Is the dst root-visible? */
1679 int match
; /* Do the encodings match? */
1681 if (kind
!= CTF_K_INTEGER
&& kind
!= CTF_K_FLOAT
&& kind
!= CTF_K_SLICE
)
1682 return dtd
->dtd_type
;
1684 sroot
= (flag
& CTF_ADD_ROOT
);
1685 droot
= (LCTF_INFO_ISROOT (dst_fp
,
1687 ctt_info
) & CTF_ADD_ROOT
);
1689 match
= (memcmp (&src_en
, &dtd
->dtd_u
.dtu_enc
,
1690 sizeof (ctf_encoding_t
)) == 0);
1692 /* If the types share the same encoding then return the id of the
1693 first unless one type is root-visible and the other is not; in
1694 that case the new type must get a new id if a match is never
1695 found. Note: slices are not certain to match even if there is
1696 no conflict: we must check the contained type too. */
1698 if (match
&& sroot
== droot
)
1700 if (kind
!= CTF_K_SLICE
)
1701 return dtd
->dtd_type
;
1703 else if (!match
&& sroot
&& droot
)
1705 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1711 src
.ctb_file
= src_fp
;
1712 src
.ctb_type
= src_type
;
1715 dst
.ctb_file
= dst_fp
;
1716 dst
.ctb_type
= dst_type
;
1719 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1720 we add a new type with the same properties as src_type to dst_fp.
1721 If dst_type is not CTF_ERR, then we verify that dst_type has the
1722 same attributes as src_type. We recurse for embedded references. */
1726 /* If we found a match we will have either returned it or declared a
1728 dst_type
= ctf_add_integer (dst_fp
, flag
, name
, &src_en
);
1732 /* If we found a match we will have either returned it or declared a
1734 dst_type
= ctf_add_float (dst_fp
, flag
, name
, &src_en
);
1738 /* We have checked for conflicting encodings: now try to add the
1740 src_type
= ctf_type_reference (src_fp
, src_type
);
1741 dst_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1743 if (src_type
== CTF_ERR
)
1744 return CTF_ERR
; /* errno is set for us. */
1746 dst_type
= ctf_add_slice (dst_fp
, flag
, src_type
, &src_en
);
1750 case CTF_K_VOLATILE
:
1752 case CTF_K_RESTRICT
:
1753 src_type
= ctf_type_reference (src_fp
, src_type
);
1754 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1756 if (src_type
== CTF_ERR
)
1757 return CTF_ERR
; /* errno is set for us. */
1759 dst_type
= ctf_add_reftype (dst_fp
, flag
, src_type
, kind
);
1763 if (ctf_array_info (src_fp
, src_type
, &src_ar
) != 0)
1764 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1766 src_ar
.ctr_contents
=
1767 ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_contents
);
1768 src_ar
.ctr_index
= ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_index
);
1769 src_ar
.ctr_nelems
= src_ar
.ctr_nelems
;
1771 if (src_ar
.ctr_contents
== CTF_ERR
|| src_ar
.ctr_index
== CTF_ERR
)
1772 return CTF_ERR
; /* errno is set for us. */
1774 if (dst_type
!= CTF_ERR
)
1776 if (ctf_array_info (dst_fp
, dst_type
, &dst_ar
) != 0)
1777 return CTF_ERR
; /* errno is set for us. */
1779 if (memcmp (&src_ar
, &dst_ar
, sizeof (ctf_arinfo_t
)))
1781 ctf_dprintf ("Conflict for type %s against ID %lx: "
1782 "array info differs, old %lx/%lx/%x; "
1783 "new: %lx/%lx/%x\n", name
, dst_type
,
1784 src_ar
.ctr_contents
, src_ar
.ctr_index
,
1785 src_ar
.ctr_nelems
, dst_ar
.ctr_contents
,
1786 dst_ar
.ctr_index
, dst_ar
.ctr_nelems
);
1787 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1791 dst_type
= ctf_add_array (dst_fp
, flag
, &src_ar
);
1794 case CTF_K_FUNCTION
:
1795 ctc
.ctc_return
= ctf_add_type (dst_fp
, src_fp
, src_tp
->ctt_type
);
1799 if (ctc
.ctc_return
== CTF_ERR
)
1800 return CTF_ERR
; /* errno is set for us. */
1802 dst_type
= ctf_add_function (dst_fp
, flag
, &ctc
, NULL
);
1813 /* Technically to match a struct or union we need to check both
1814 ways (src members vs. dst, dst members vs. src) but we make
1815 this more optimal by only checking src vs. dst and comparing
1816 the total size of the structure (which we must do anyway)
1817 which covers the possibility of dst members not in src.
1818 This optimization can be defeated for unions, but is so
1819 pathological as to render it irrelevant for our purposes. */
1821 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1823 if (ctf_type_size (src_fp
, src_type
) !=
1824 ctf_type_size (dst_fp
, dst_type
))
1826 ctf_dprintf ("Conflict for type %s against ID %lx: "
1827 "union size differs, old %li, new %li\n",
1829 (long) ctf_type_size (src_fp
, src_type
),
1830 (long) ctf_type_size (dst_fp
, dst_type
));
1831 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1834 if (ctf_member_iter (src_fp
, src_type
, membcmp
, &dst
))
1836 ctf_dprintf ("Conflict for type %s against ID %lx: "
1837 "members differ, see above\n", name
, dst_type
);
1838 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1844 /* Unlike the other cases, copying structs and unions is done
1845 manually so as to avoid repeated lookups in ctf_add_member
1846 and to ensure the exact same member offsets as in src_type. */
1848 dst_type
= ctf_add_generic (dst_fp
, flag
, name
, &dtd
);
1849 if (dst_type
== CTF_ERR
)
1850 return CTF_ERR
; /* errno is set for us. */
1852 dst
.ctb_type
= dst_type
;
1855 if (ctf_member_iter (src_fp
, src_type
, membadd
, &dst
) != 0)
1856 errs
++; /* Increment errs and fail at bottom of case. */
1858 if ((ssize
= ctf_type_size (src_fp
, src_type
)) < 0)
1859 return CTF_ERR
; /* errno is set for us. */
1861 size
= (size_t) ssize
;
1862 if (size
> CTF_MAX_SIZE
)
1864 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1865 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1866 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1869 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1871 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, vlen
);
1873 /* Make a final pass through the members changing each dmd_type (a
1874 src_fp type) to an equivalent type in dst_fp. We pass through all
1875 members, leaving any that fail set to CTF_ERR. */
1876 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1877 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1879 if ((dmd
->dmd_type
= ctf_add_type (dst_fp
, src_fp
,
1880 dmd
->dmd_type
)) == CTF_ERR
)
1885 return CTF_ERR
; /* errno is set for us. */
1890 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1892 if (ctf_enum_iter (src_fp
, src_type
, enumcmp
, &dst
)
1893 || ctf_enum_iter (dst_fp
, dst_type
, enumcmp
, &src
))
1895 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1896 "members differ, see above\n", name
, dst_type
);
1897 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1902 dst_type
= ctf_add_enum (dst_fp
, flag
, name
);
1903 if ((dst
.ctb_type
= dst_type
) == CTF_ERR
1904 || ctf_enum_iter (src_fp
, src_type
, enumadd
, &dst
))
1905 return CTF_ERR
; /* errno is set for us */
1910 if (dst_type
== CTF_ERR
)
1912 dst_type
= ctf_add_forward (dst_fp
, flag
,
1913 name
, CTF_K_STRUCT
); /* Assume STRUCT. */
1918 src_type
= ctf_type_reference (src_fp
, src_type
);
1919 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1921 if (src_type
== CTF_ERR
)
1922 return CTF_ERR
; /* errno is set for us. */
1924 /* If dst_type is not CTF_ERR at this point, we should check if
1925 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1926 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1927 that vary based on things like if 32-bit then pid_t is int otherwise
1928 long. We therefore omit this check and assume that if the identically
1929 named typedef already exists in dst_fp, it is correct or
1932 if (dst_type
== CTF_ERR
)
1934 dst_type
= ctf_add_typedef (dst_fp
, flag
, name
, src_type
);
1939 return (ctf_set_errno (dst_fp
, ECTF_CORRUPT
));
1945 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1947 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1949 const unsigned char *buf
;
1953 resid
= sizeof (ctf_header_t
);
1954 buf
= (unsigned char *) fp
->ctf_header
;
1957 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1958 return (ctf_set_errno (fp
, errno
));
1963 resid
= fp
->ctf_size
;
1967 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1968 return (ctf_set_errno (fp
, errno
));
1976 /* Compress the specified CTF data stream and write it to the specified file
1979 ctf_compress_write (ctf_file_t
*fp
, int fd
)
1984 ctf_header_t
*hp
= &h
;
1985 ssize_t header_len
= sizeof (ctf_header_t
);
1986 ssize_t compress_len
;
1987 size_t max_compress_len
= compressBound (fp
->ctf_size
);
1992 memcpy (hp
, fp
->ctf_header
, header_len
);
1993 hp
->cth_flags
|= CTF_F_COMPRESS
;
1995 if ((buf
= ctf_alloc (max_compress_len
)) == NULL
)
1996 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
1998 compress_len
= max_compress_len
;
1999 if ((rc
= compress (buf
, (uLongf
*) &compress_len
,
2000 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2002 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2003 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
2007 while (header_len
> 0)
2009 if ((len
= write (fd
, hp
, header_len
)) < 0)
2011 err
= ctf_set_errno (fp
, errno
);
2019 while (compress_len
> 0)
2021 if ((len
= write (fd
, bp
, compress_len
)) < 0)
2023 err
= ctf_set_errno (fp
, errno
);
2026 compress_len
-= len
;
2035 /* Optionally compress the specified CTF data stream and return it as a new
2036 dynamically-allocated string. */
2038 ctf_write_mem (ctf_file_t
*fp
, size_t *size
, size_t threshold
)
2043 ssize_t header_len
= sizeof (ctf_header_t
);
2044 ssize_t compress_len
;
2045 size_t max_compress_len
= compressBound (fp
->ctf_size
);
2048 if (fp
->ctf_size
< threshold
)
2049 max_compress_len
= fp
->ctf_size
;
2050 if ((buf
= malloc (max_compress_len
2051 + sizeof (struct ctf_header
))) == NULL
)
2053 ctf_set_errno (fp
, ENOMEM
);
2057 hp
= (ctf_header_t
*) buf
;
2058 memcpy (hp
, fp
->ctf_header
, header_len
);
2059 bp
= buf
+ sizeof (struct ctf_header
);
2060 *size
= sizeof (struct ctf_header
);
2062 compress_len
= max_compress_len
;
2064 if (fp
->ctf_size
< threshold
)
2066 hp
->cth_flags
&= ~CTF_F_COMPRESS
;
2067 memcpy (bp
, fp
->ctf_buf
, fp
->ctf_size
);
2068 *size
+= fp
->ctf_size
;
2072 hp
->cth_flags
|= CTF_F_COMPRESS
;
2073 if ((rc
= compress (bp
, (uLongf
*) &compress_len
,
2074 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
2076 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2077 ctf_set_errno (fp
, ECTF_COMPRESS
);
2081 *size
+= compress_len
;
2086 /* Write the uncompressed CTF data stream to the specified file descriptor. */
2088 ctf_write (ctf_file_t
*fp
, int fd
)
2090 const unsigned char *buf
;
2094 resid
= sizeof (ctf_header_t
);
2095 buf
= (unsigned char *) fp
->ctf_header
;
2098 if ((len
= write (fd
, buf
, resid
)) <= 0)
2099 return (ctf_set_errno (fp
, errno
));
2104 resid
= fp
->ctf_size
;
2108 if ((len
= write (fd
, buf
, resid
)) <= 0)
2109 return (ctf_set_errno (fp
, errno
));