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>
26 /* To create an empty CTF container, we just declare a zeroed header and call
27 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
28 and initialize the dynamic members. We set dtvstrlen to 1 to reserve the
29 first byte of the string table for a \0 byte, and we start assigning type
30 IDs at 1 because type ID 0 is used as a sentinel and a not-found
34 ctf_create (int *errp
)
36 static const ctf_header_t hdr
= { .cth_preamble
= { CTF_MAGIC
, CTF_VERSION
, 0 } };
38 ctf_dynhash_t
*dthash
;
39 ctf_dynhash_t
*dvhash
;
40 ctf_dynhash_t
*dtbyname
;
45 dthash
= ctf_dynhash_create (ctf_hash_integer
, ctf_hash_eq_integer
,
49 ctf_set_open_errno (errp
, EAGAIN
);
53 dvhash
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
57 ctf_set_open_errno (errp
, EAGAIN
);
61 dtbyname
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
65 ctf_set_open_errno (errp
, EAGAIN
);
69 cts
.cts_name
= _CTF_SECTION
;
70 cts
.cts_type
= SHT_PROGBITS
;
73 cts
.cts_size
= sizeof (hdr
);
77 if ((fp
= ctf_bufopen (&cts
, NULL
, NULL
, errp
)) == NULL
)
80 fp
->ctf_flags
|= LCTF_RDWR
;
81 fp
->ctf_dtbyname
= dtbyname
;
82 fp
->ctf_dthash
= dthash
;
83 fp
->ctf_dvhash
= dvhash
;
84 fp
->ctf_dtvstrlen
= 1;
87 fp
->ctf_snapshots
= 0;
88 fp
->ctf_snapshot_lu
= 0;
93 ctf_dynhash_destroy (dtbyname
);
95 ctf_dynhash_destroy (dvhash
);
97 ctf_dynhash_destroy (dthash
);
102 static unsigned char *
103 ctf_copy_smembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
105 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
108 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
113 soff
+= strlen (dmd
->dmd_name
) + 1;
118 ctm
.ctm_type
= (uint32_t) dmd
->dmd_type
;
119 ctm
.ctm_offset
= (uint32_t) dmd
->dmd_offset
;
121 memcpy (t
, &ctm
, sizeof (ctm
));
128 static unsigned char *
129 ctf_copy_lmembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
131 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
134 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
138 ctlm
.ctlm_name
= soff
;
139 soff
+= strlen (dmd
->dmd_name
) + 1;
144 ctlm
.ctlm_type
= (uint32_t) dmd
->dmd_type
;
145 ctlm
.ctlm_offsethi
= CTF_OFFSET_TO_LMEMHI (dmd
->dmd_offset
);
146 ctlm
.ctlm_offsetlo
= CTF_OFFSET_TO_LMEMLO (dmd
->dmd_offset
);
148 memcpy (t
, &ctlm
, sizeof (ctlm
));
155 static unsigned char *
156 ctf_copy_emembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
158 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
161 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
164 cte
.cte_value
= dmd
->dmd_value
;
165 soff
+= strlen (dmd
->dmd_name
) + 1;
166 memcpy (t
, &cte
, sizeof (cte
));
173 static unsigned char *
174 ctf_copy_membnames (ctf_dtdef_t
*dtd
, unsigned char *s
)
176 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
179 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
181 if (dmd
->dmd_name
== NULL
)
182 continue; /* Skip anonymous members. */
183 len
= strlen (dmd
->dmd_name
) + 1;
184 memcpy (s
, dmd
->dmd_name
, len
);
191 /* Sort a newly-constructed static variable array. */
194 ctf_sort_var (const void *one_
, const void *two_
, void *strtab_
)
196 const ctf_varent_t
*one
= one_
;
197 const ctf_varent_t
*two
= two_
;
198 const char *strtab
= strtab_
;
199 const char *n1
= strtab
+ CTF_NAME_OFFSET (one
->ctv_name
);
200 const char *n2
= strtab
+ CTF_NAME_OFFSET (two
->ctv_name
);
202 return (strcmp (n1
, n2
));
205 /* If the specified CTF container is writable and has been modified, reload this
206 container with the updated type definitions. In order to make this code and
207 the rest of libctf as simple as possible, we perform updates by taking the
208 dynamic type definitions and creating an in-memory CTF file containing the
209 definitions, and then call ctf_simple_open() on it. This not only leverages
210 ctf_simple_open(), but also avoids having to bifurcate the rest of the library
211 code with different lookup paths for static and dynamic type definitions. We
212 are therefore optimizing greatly for lookup over update, which we assume will
213 be an uncommon operation. We perform one extra trick here for the benefit of
214 callers and to keep our code simple: ctf_simple_open() will return a new
215 ctf_file_t, but we want to keep the fp constant for the caller, so after
216 ctf_simple_open() returns, we use memcpy to swap the interior of the old and
217 new ctf_file_t's, and then free the old. */
219 ctf_update (ctf_file_t
*fp
)
221 ctf_file_t ofp
, *nfp
;
225 ctf_varent_t
*dvarents
;
227 unsigned char *s
, *s0
, *t
;
229 size_t buf_size
, type_size
, nvars
;
233 if (!(fp
->ctf_flags
& LCTF_RDWR
))
234 return (ctf_set_errno (fp
, ECTF_RDONLY
));
236 /* Update required? */
237 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
240 /* Fill in an initial CTF header. We will leave the label, object,
241 and function sections empty and only output a header, type section,
242 and string table. The type section begins at a 4-byte aligned
243 boundary past the CTF header itself (at relative offset zero). */
245 memset (&hdr
, 0, sizeof (hdr
));
246 hdr
.cth_magic
= CTF_MAGIC
;
247 hdr
.cth_version
= CTF_VERSION
;
249 if (fp
->ctf_flags
& LCTF_CHILD
)
250 hdr
.cth_parname
= 1; /* parname added just below. */
252 /* Iterate through the dynamic type definition list and compute the
253 size of the CTF type section we will need to generate. */
255 for (type_size
= 0, dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
256 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
258 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
259 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
261 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
262 type_size
+= sizeof (ctf_stype_t
);
264 type_size
+= sizeof (ctf_type_t
);
270 type_size
+= sizeof (uint32_t);
273 type_size
+= sizeof (ctf_array_t
);
276 type_size
+= sizeof (ctf_slice_t
);
279 type_size
+= sizeof (uint32_t) * (vlen
+ (vlen
& 1));
283 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
284 type_size
+= sizeof (ctf_member_t
) * vlen
;
286 type_size
+= sizeof (ctf_lmember_t
) * vlen
;
289 type_size
+= sizeof (ctf_enum_t
) * vlen
;
294 /* Computing the number of entries in the CTF variable section is much
297 for (nvars
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
298 dvd
!= NULL
; dvd
= ctf_list_next (dvd
), nvars
++);
300 /* Fill in the string table and type offset and size, compute the size
301 of the entire CTF buffer we need, and then allocate a new buffer and
302 memcpy the finished header to the start of the buffer. */
304 hdr
.cth_typeoff
= hdr
.cth_varoff
+ (nvars
* sizeof (ctf_varent_t
));
305 hdr
.cth_stroff
= hdr
.cth_typeoff
+ type_size
;
306 hdr
.cth_strlen
= fp
->ctf_dtvstrlen
;
307 if (fp
->ctf_parname
!= NULL
)
308 hdr
.cth_strlen
+= strlen (fp
->ctf_parname
) + 1;
310 buf_size
= sizeof (ctf_header_t
) + hdr
.cth_stroff
+ hdr
.cth_strlen
;
312 if ((buf
= ctf_data_alloc (buf_size
)) == NULL
)
313 return (ctf_set_errno (fp
, EAGAIN
));
315 memcpy (buf
, &hdr
, sizeof (ctf_header_t
));
316 t
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_varoff
;
317 s
= s0
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
;
322 if (fp
->ctf_parname
!= NULL
)
324 memcpy (s
, fp
->ctf_parname
, strlen (fp
->ctf_parname
) + 1);
325 s
+= strlen (fp
->ctf_parname
) + 1;
328 /* Work over the variable list, translating everything into
329 ctf_varent_t's and filling out the string table, then sort the buffer
330 of ctf_varent_t's. */
332 dvarents
= (ctf_varent_t
*) t
;
333 for (i
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
334 dvd
= ctf_list_next (dvd
), i
++)
336 ctf_varent_t
*var
= &dvarents
[i
];
337 size_t len
= strlen (dvd
->dvd_name
) + 1;
339 var
->ctv_name
= (uint32_t) (s
- s0
);
340 var
->ctv_type
= dvd
->dvd_type
;
341 memcpy (s
, dvd
->dvd_name
, len
);
346 qsort_r (dvarents
, nvars
, sizeof (ctf_varent_t
), ctf_sort_var
, s0
);
347 t
+= sizeof (ctf_varent_t
) * nvars
;
349 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_typeoff
);
351 /* We now take a final lap through the dynamic type definition list and
352 copy the appropriate type records and strings to the output buffer. */
354 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
355 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
358 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
359 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
365 if (dtd
->dtd_name
!= NULL
)
367 dtd
->dtd_data
.ctt_name
= (uint32_t) (s
- s0
);
368 len
= strlen (dtd
->dtd_name
) + 1;
369 memcpy (s
, dtd
->dtd_name
, len
);
373 dtd
->dtd_data
.ctt_name
= 0;
375 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
376 len
= sizeof (ctf_stype_t
);
378 len
= sizeof (ctf_type_t
);
380 memcpy (t
, &dtd
->dtd_data
, len
);
387 if (kind
== CTF_K_INTEGER
)
389 encoding
= CTF_INT_DATA (dtd
->dtd_u
.dtu_enc
.cte_format
,
390 dtd
->dtd_u
.dtu_enc
.cte_offset
,
391 dtd
->dtd_u
.dtu_enc
.cte_bits
);
395 encoding
= CTF_FP_DATA (dtd
->dtd_u
.dtu_enc
.cte_format
,
396 dtd
->dtd_u
.dtu_enc
.cte_offset
,
397 dtd
->dtd_u
.dtu_enc
.cte_bits
);
399 memcpy (t
, &encoding
, sizeof (encoding
));
400 t
+= sizeof (encoding
);
404 memcpy (t
, &dtd
->dtd_u
.dtu_slice
, sizeof (struct ctf_slice
));
405 t
+= sizeof (struct ctf_slice
);
409 cta
.cta_contents
= (uint32_t) dtd
->dtd_u
.dtu_arr
.ctr_contents
;
410 cta
.cta_index
= (uint32_t) dtd
->dtd_u
.dtu_arr
.ctr_index
;
411 cta
.cta_nelems
= dtd
->dtd_u
.dtu_arr
.ctr_nelems
;
412 memcpy (t
, &cta
, sizeof (cta
));
418 uint32_t *argv
= (uint32_t *) (uintptr_t) t
;
421 for (argc
= 0; argc
< vlen
; argc
++)
422 *argv
++ = (uint32_t) dtd
->dtd_u
.dtu_argv
[argc
];
425 *argv
++ = 0; /* Pad to 4-byte boundary. */
427 t
= (unsigned char *) argv
;
433 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
434 t
= ctf_copy_smembers (dtd
, (uint32_t) (s
- s0
), t
);
436 t
= ctf_copy_lmembers (dtd
, (uint32_t) (s
- s0
), t
);
437 s
= ctf_copy_membnames (dtd
, s
);
441 t
= ctf_copy_emembers (dtd
, (uint32_t) (s
- s0
), t
);
442 s
= ctf_copy_membnames (dtd
, s
);
446 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
);
448 /* Finally, we are ready to ctf_simple_open() the new container. If this
449 is successful, we then switch nfp and fp and free the old container. */
451 ctf_data_protect (buf
, buf_size
);
453 if ((nfp
= ctf_simple_open (buf
, buf_size
, NULL
, 0, 0, NULL
, 0, &err
)) == NULL
)
455 ctf_data_free (buf
, buf_size
);
456 return (ctf_set_errno (fp
, err
));
459 (void) ctf_setmodel (nfp
, ctf_getmodel (fp
));
460 (void) ctf_import (nfp
, fp
->ctf_parent
);
462 nfp
->ctf_refcnt
= fp
->ctf_refcnt
;
463 nfp
->ctf_flags
|= fp
->ctf_flags
& ~LCTF_DIRTY
;
464 nfp
->ctf_data
.cts_data
= NULL
; /* Force ctf_data_free() on close. */
465 nfp
->ctf_dthash
= fp
->ctf_dthash
;
466 nfp
->ctf_dtdefs
= fp
->ctf_dtdefs
;
467 nfp
->ctf_dtbyname
= fp
->ctf_dtbyname
;
468 nfp
->ctf_dvhash
= fp
->ctf_dvhash
;
469 nfp
->ctf_dvdefs
= fp
->ctf_dvdefs
;
470 nfp
->ctf_dtvstrlen
= fp
->ctf_dtvstrlen
;
471 nfp
->ctf_dtnextid
= fp
->ctf_dtnextid
;
472 nfp
->ctf_dtoldid
= fp
->ctf_dtnextid
- 1;
473 nfp
->ctf_snapshots
= fp
->ctf_snapshots
+ 1;
474 nfp
->ctf_specific
= fp
->ctf_specific
;
476 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
478 fp
->ctf_dtbyname
= NULL
;
479 fp
->ctf_dthash
= NULL
;
480 memset (&fp
->ctf_dtdefs
, 0, sizeof (ctf_list_t
));
482 fp
->ctf_dvhash
= NULL
;
483 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
485 memcpy (&ofp
, fp
, sizeof (ctf_file_t
));
486 memcpy (fp
, nfp
, sizeof (ctf_file_t
));
487 memcpy (nfp
, &ofp
, sizeof (ctf_file_t
));
489 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
490 array of type name prefixes and the corresponding ctf_dynhash to use.
491 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
493 fp
->ctf_lookups
[0].ctl_hash
= fp
->ctf_structs
;
494 fp
->ctf_lookups
[1].ctl_hash
= fp
->ctf_unions
;
495 fp
->ctf_lookups
[2].ctl_hash
= fp
->ctf_enums
;
496 fp
->ctf_lookups
[3].ctl_hash
= fp
->ctf_names
;
498 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
499 ctf_file_close (nfp
);
505 ctf_prefixed_name (int kind
, const char *name
)
512 prefixed
= ctf_strdup ("struct ");
515 prefixed
= ctf_strdup ("union ");
518 prefixed
= ctf_strdup ("enum ");
521 prefixed
= ctf_strdup ("");
524 prefixed
= ctf_str_append (prefixed
, name
);
529 ctf_dtd_insert (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
531 ctf_dynhash_insert (fp
->ctf_dthash
, (void *) dtd
->dtd_type
, dtd
);
532 ctf_list_append (&fp
->ctf_dtdefs
, dtd
);
535 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
536 ctf_dynhash_insert (fp
->ctf_dtbyname
, ctf_prefixed_name (kind
,
543 ctf_dtd_delete (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
545 ctf_dmdef_t
*dmd
, *nmd
;
546 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
548 ctf_dynhash_remove (fp
->ctf_dthash
, (void *) dtd
->dtd_type
);
555 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
556 dmd
!= NULL
; dmd
= nmd
)
558 if (dmd
->dmd_name
!= NULL
)
560 fp
->ctf_dtvstrlen
-= strlen (dmd
->dmd_name
) + 1;
561 ctf_free (dmd
->dmd_name
);
563 nmd
= ctf_list_next (dmd
);
568 ctf_free (dtd
->dtd_u
.dtu_argv
);
576 name
= ctf_prefixed_name (kind
, dtd
->dtd_name
);
577 ctf_dynhash_remove (fp
->ctf_dtbyname
, name
);
580 fp
->ctf_dtvstrlen
-= strlen (dtd
->dtd_name
) + 1;
581 ctf_free (dtd
->dtd_name
);
584 ctf_list_delete (&fp
->ctf_dtdefs
, dtd
);
589 ctf_dtd_lookup (const ctf_file_t
*fp
, ctf_id_t type
)
591 return (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dthash
, (void *) type
);
595 ctf_dtd_lookup_type_by_name (ctf_file_t
*fp
, int kind
, const char *name
)
598 char *decorated
= ctf_prefixed_name (kind
, name
);
600 dtd
= (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dtbyname
, decorated
);
604 return dtd
->dtd_type
;
610 ctf_dynamic_type (const ctf_file_t
*fp
, ctf_id_t id
)
614 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, id
))
617 idx
= LCTF_TYPE_TO_INDEX(fp
, id
);
619 if (((unsigned long) idx
> fp
->ctf_typemax
) &&
620 ((unsigned long) idx
< fp
->ctf_dtnextid
))
621 return ctf_dtd_lookup (fp
, id
);
626 ctf_dvd_insert (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
628 ctf_dynhash_insert (fp
->ctf_dvhash
, dvd
->dvd_name
, dvd
);
629 ctf_list_append (&fp
->ctf_dvdefs
, dvd
);
633 ctf_dvd_delete (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
635 ctf_dynhash_remove (fp
->ctf_dvhash
, dvd
->dvd_name
);
637 fp
->ctf_dtvstrlen
-= strlen (dvd
->dvd_name
) + 1;
638 ctf_free (dvd
->dvd_name
);
640 ctf_list_delete (&fp
->ctf_dvdefs
, dvd
);
645 ctf_dvd_lookup (const ctf_file_t
*fp
, const char *name
)
647 return (ctf_dvdef_t
*) ctf_dynhash_lookup (fp
->ctf_dvhash
, name
);
650 /* Discard all of the dynamic type definitions and variable definitions that
651 have been added to the container since the last call to ctf_update(). We
652 locate such types by scanning the dtd list and deleting elements that have
653 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
654 by scanning the variable list and deleting elements that have update IDs
655 equal to the current value of the last-update snapshot count (indicating that
656 they were added after the most recent call to ctf_update()). */
658 ctf_discard (ctf_file_t
*fp
)
660 ctf_snapshot_id_t last_update
=
662 fp
->ctf_snapshot_lu
+ 1 };
664 /* Update required? */
665 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
668 return (ctf_rollback (fp
, last_update
));
672 ctf_snapshot (ctf_file_t
*fp
)
674 ctf_snapshot_id_t snapid
;
675 snapid
.dtd_id
= fp
->ctf_dtnextid
- 1;
676 snapid
.snapshot_id
= fp
->ctf_snapshots
++;
680 /* Like ctf_discard(), only discards everything after a particular ID. */
682 ctf_rollback (ctf_file_t
*fp
, ctf_snapshot_id_t id
)
684 ctf_dtdef_t
*dtd
, *ntd
;
685 ctf_dvdef_t
*dvd
, *nvd
;
687 if (!(fp
->ctf_flags
& LCTF_RDWR
))
688 return (ctf_set_errno (fp
, ECTF_RDONLY
));
690 if (fp
->ctf_dtoldid
> id
.dtd_id
)
691 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
693 if (fp
->ctf_snapshot_lu
>= id
.snapshot_id
)
694 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
696 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
); dtd
!= NULL
; dtd
= ntd
)
698 ntd
= ctf_list_next (dtd
);
700 if (LCTF_TYPE_TO_INDEX (fp
, dtd
->dtd_type
) <= id
.dtd_id
)
703 ctf_dtd_delete (fp
, dtd
);
706 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
708 nvd
= ctf_list_next (dvd
);
710 if (dvd
->dvd_snapshots
<= id
.snapshot_id
)
713 ctf_dvd_delete (fp
, dvd
);
716 fp
->ctf_dtnextid
= id
.dtd_id
+ 1;
717 fp
->ctf_snapshots
= id
.snapshot_id
;
719 if (fp
->ctf_snapshots
== fp
->ctf_snapshot_lu
)
720 fp
->ctf_flags
&= ~LCTF_DIRTY
;
726 ctf_add_generic (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
733 if (flag
!= CTF_ADD_NONROOT
&& flag
!= CTF_ADD_ROOT
)
734 return (ctf_set_errno (fp
, EINVAL
));
736 if (!(fp
->ctf_flags
& LCTF_RDWR
))
737 return (ctf_set_errno (fp
, ECTF_RDONLY
));
739 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) > CTF_MAX_TYPE
)
740 return (ctf_set_errno (fp
, ECTF_FULL
));
742 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) == CTF_MAX_PTYPE
)
743 return (ctf_set_errno (fp
, ECTF_FULL
));
745 if ((dtd
= ctf_alloc (sizeof (ctf_dtdef_t
))) == NULL
)
746 return (ctf_set_errno (fp
, EAGAIN
));
748 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
751 return (ctf_set_errno (fp
, EAGAIN
));
754 type
= fp
->ctf_dtnextid
++;
755 type
= LCTF_INDEX_TO_TYPE (fp
, type
, (fp
->ctf_flags
& LCTF_CHILD
));
757 memset (dtd
, 0, sizeof (ctf_dtdef_t
));
759 dtd
->dtd_type
= type
;
762 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
764 ctf_dtd_insert (fp
, dtd
);
765 fp
->ctf_flags
|= LCTF_DIRTY
;
771 /* When encoding integer sizes, we want to convert a byte count in the range
772 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
773 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
789 ctf_add_encoded (ctf_file_t
*fp
, uint32_t flag
,
790 const char *name
, const ctf_encoding_t
*ep
, uint32_t kind
)
796 return (ctf_set_errno (fp
, EINVAL
));
798 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
799 return CTF_ERR
; /* errno is set for us. */
801 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
802 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, NBBY
) / NBBY
);
803 dtd
->dtd_u
.dtu_enc
= *ep
;
809 ctf_add_reftype (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
, uint32_t kind
)
813 ctf_file_t
*tmp
= fp
;
815 if (ref
== CTF_ERR
|| ref
< 0 || ref
> CTF_MAX_TYPE
)
816 return (ctf_set_errno (fp
, EINVAL
));
818 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
819 return CTF_ERR
; /* errno is set for us. */
821 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
822 return CTF_ERR
; /* errno is set for us. */
824 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
825 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
831 ctf_add_slice (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
,
832 const ctf_encoding_t
*ep
)
837 const ctf_type_t
*tp
;
838 ctf_file_t
*tmp
= fp
;
841 return (ctf_set_errno (fp
, EINVAL
));
843 if ((ep
->cte_bits
> 255) || (ep
->cte_offset
> 255))
844 return (ctf_set_errno (fp
, ECTF_SLICEOVERFLOW
));
846 if (ref
== CTF_ERR
|| ref
< 0 || ref
> CTF_MAX_TYPE
)
847 return (ctf_set_errno (fp
, EINVAL
));
849 if ((tp
= ctf_lookup_by_id (&tmp
, ref
)) == NULL
)
850 return CTF_ERR
; /* errno is set for us. */
852 kind
= ctf_type_kind_unsliced (tmp
, ref
);
853 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) &&
854 (kind
!= CTF_K_ENUM
))
855 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
857 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
858 return CTF_ERR
; /* errno is set for us. */
860 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_SLICE
, flag
, 0);
861 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, NBBY
) / NBBY
);
862 dtd
->dtd_u
.dtu_slice
.cts_type
= ref
;
863 dtd
->dtd_u
.dtu_slice
.cts_bits
= ep
->cte_bits
;
864 dtd
->dtd_u
.dtu_slice
.cts_offset
= ep
->cte_offset
;
870 ctf_add_integer (ctf_file_t
*fp
, uint32_t flag
,
871 const char *name
, const ctf_encoding_t
*ep
)
873 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_INTEGER
));
877 ctf_add_float (ctf_file_t
*fp
, uint32_t flag
,
878 const char *name
, const ctf_encoding_t
*ep
)
880 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_FLOAT
));
884 ctf_add_pointer (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
886 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_POINTER
));
890 ctf_add_array (ctf_file_t
*fp
, uint32_t flag
, const ctf_arinfo_t
*arp
)
894 ctf_file_t
*tmp
= fp
;
897 return (ctf_set_errno (fp
, EINVAL
));
899 if (ctf_lookup_by_id (&tmp
, arp
->ctr_contents
) == NULL
)
900 return CTF_ERR
; /* errno is set for us. */
903 if (ctf_lookup_by_id (&tmp
, arp
->ctr_index
) == NULL
)
904 return CTF_ERR
; /* errno is set for us. */
906 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
907 return CTF_ERR
; /* errno is set for us. */
909 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ARRAY
, flag
, 0);
910 dtd
->dtd_data
.ctt_size
= 0;
911 dtd
->dtd_u
.dtu_arr
= *arp
;
917 ctf_set_array (ctf_file_t
*fp
, ctf_id_t type
, const ctf_arinfo_t
*arp
)
919 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
921 if (!(fp
->ctf_flags
& LCTF_RDWR
))
922 return (ctf_set_errno (fp
, ECTF_RDONLY
));
925 || LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
) != CTF_K_ARRAY
)
926 return (ctf_set_errno (fp
, ECTF_BADID
));
928 fp
->ctf_flags
|= LCTF_DIRTY
;
929 dtd
->dtd_u
.dtu_arr
= *arp
;
935 ctf_add_function (ctf_file_t
*fp
, uint32_t flag
,
936 const ctf_funcinfo_t
*ctc
, const ctf_id_t
*argv
)
941 ctf_id_t
*vdat
= NULL
;
942 ctf_file_t
*tmp
= fp
;
945 if (ctc
== NULL
|| (ctc
->ctc_flags
& ~CTF_FUNC_VARARG
) != 0
946 || (ctc
->ctc_argc
!= 0 && argv
== NULL
))
947 return (ctf_set_errno (fp
, EINVAL
));
949 vlen
= ctc
->ctc_argc
;
950 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
951 vlen
++; /* Add trailing zero to indicate varargs (see below). */
953 if (ctf_lookup_by_id (&tmp
, ctc
->ctc_return
) == NULL
)
954 return CTF_ERR
; /* errno is set for us. */
956 for (i
= 0; i
< ctc
->ctc_argc
; i
++)
959 if (ctf_lookup_by_id (&tmp
, argv
[i
]) == NULL
)
960 return CTF_ERR
; /* errno is set for us. */
963 if (vlen
> CTF_MAX_VLEN
)
964 return (ctf_set_errno (fp
, EOVERFLOW
));
966 if (vlen
!= 0 && (vdat
= ctf_alloc (sizeof (ctf_id_t
) * vlen
)) == NULL
)
967 return (ctf_set_errno (fp
, EAGAIN
));
969 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
972 return CTF_ERR
; /* errno is set for us. */
975 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FUNCTION
, flag
, vlen
);
976 dtd
->dtd_data
.ctt_type
= (uint32_t) ctc
->ctc_return
;
978 memcpy (vdat
, argv
, sizeof (ctf_id_t
) * ctc
->ctc_argc
);
979 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
980 vdat
[vlen
- 1] = 0; /* Add trailing zero to indicate varargs. */
981 dtd
->dtd_u
.dtu_argv
= vdat
;
987 ctf_add_struct_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
990 ctf_hash_t
*hp
= fp
->ctf_structs
;
994 /* Promote forwards to structs. */
998 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1000 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_STRUCT
, name
);
1003 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1004 dtd
= ctf_dtd_lookup (fp
, type
);
1005 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1006 return CTF_ERR
; /* errno is set for us. */
1008 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_STRUCT
, flag
, 0);
1010 if (size
> CTF_MAX_SIZE
)
1012 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1013 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1014 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1017 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1023 ctf_add_struct (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1025 return (ctf_add_struct_sized (fp
, flag
, name
, 0));
1029 ctf_add_union_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1032 ctf_hash_t
*hp
= fp
->ctf_unions
;
1036 /* Promote forwards to unions. */
1039 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1041 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_UNION
, name
);
1044 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1045 dtd
= ctf_dtd_lookup (fp
, type
);
1046 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1047 return CTF_ERR
; /* errno is set for us */
1049 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_UNION
, flag
, 0);
1051 if (size
> CTF_MAX_SIZE
)
1053 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1054 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1055 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1058 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1064 ctf_add_union (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1066 return (ctf_add_union_sized (fp
, flag
, name
, 0));
1070 ctf_add_enum (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1072 ctf_hash_t
*hp
= fp
->ctf_enums
;
1076 /* Promote forwards to enums. */
1079 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1081 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1084 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1085 dtd
= ctf_dtd_lookup (fp
, type
);
1086 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1087 return CTF_ERR
; /* errno is set for us. */
1089 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ENUM
, flag
, 0);
1090 dtd
->dtd_data
.ctt_size
= fp
->ctf_dmodel
->ctd_int
;
1096 ctf_add_enum_encoded (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1097 const ctf_encoding_t
*ep
)
1099 ctf_hash_t
*hp
= fp
->ctf_enums
;
1102 /* First, create the enum if need be, using most of the same machinery as
1103 ctf_add_enum(), to ensure that we do not allow things past that are not
1104 enums or forwards to them. (This includes other slices: you cannot slice a
1105 slice, which would be a useless thing to do anyway.) */
1109 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1111 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1116 if ((ctf_type_kind (fp
, type
) != CTF_K_FORWARD
) &&
1117 (ctf_type_kind_unsliced (fp
, type
) != CTF_K_ENUM
))
1118 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1120 else if ((type
= ctf_add_enum (fp
, flag
, name
)) == CTF_ERR
)
1121 return CTF_ERR
; /* errno is set for us. */
1123 /* Now attach a suitable slice to it. */
1125 return ctf_add_slice (fp
, flag
, type
, ep
);
1129 ctf_add_forward (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1139 hp
= fp
->ctf_structs
;
1142 hp
= fp
->ctf_unions
;
1148 return (ctf_set_errno (fp
, ECTF_NOTSUE
));
1151 /* If the type is already defined or exists as a forward tag, just
1152 return the ctf_id_t of the existing definition. */
1156 if (((type
= ctf_hash_lookup_type (hp
, fp
, name
)) != 0)
1157 || (type
= ctf_dtd_lookup_type_by_name (fp
, kind
, name
)) != 0)
1161 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1162 return CTF_ERR
; /* errno is set for us. */
1164 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FORWARD
, flag
, 0);
1165 dtd
->dtd_data
.ctt_type
= kind
;
1171 ctf_add_typedef (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1176 ctf_file_t
*tmp
= fp
;
1178 if (ref
== CTF_ERR
|| ref
< 0 || ref
> CTF_MAX_TYPE
)
1179 return (ctf_set_errno (fp
, EINVAL
));
1181 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1182 return CTF_ERR
; /* errno is set for us. */
1184 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1185 return CTF_ERR
; /* errno is set for us. */
1187 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_TYPEDEF
, flag
, 0);
1188 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
1194 ctf_add_volatile (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1196 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_VOLATILE
));
1200 ctf_add_const (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1202 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_CONST
));
1206 ctf_add_restrict (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1208 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_RESTRICT
));
1212 ctf_add_enumerator (ctf_file_t
*fp
, ctf_id_t enid
, const char *name
,
1215 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, enid
);
1218 uint32_t kind
, vlen
, root
;
1222 return (ctf_set_errno (fp
, EINVAL
));
1224 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1225 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1228 return (ctf_set_errno (fp
, ECTF_BADID
));
1230 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1231 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1232 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1234 if (kind
!= CTF_K_ENUM
)
1235 return (ctf_set_errno (fp
, ECTF_NOTENUM
));
1237 if (vlen
== CTF_MAX_VLEN
)
1238 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1240 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1241 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1243 if (strcmp (dmd
->dmd_name
, name
) == 0)
1244 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1247 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1248 return (ctf_set_errno (fp
, EAGAIN
));
1250 if ((s
= ctf_strdup (name
)) == NULL
)
1253 return (ctf_set_errno (fp
, EAGAIN
));
1257 dmd
->dmd_type
= CTF_ERR
;
1258 dmd
->dmd_offset
= 0;
1259 dmd
->dmd_value
= value
;
1261 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1262 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1264 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
1265 fp
->ctf_flags
|= LCTF_DIRTY
;
1271 ctf_add_member_offset (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1272 ctf_id_t type
, unsigned long bit_offset
)
1274 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, souid
);
1277 ssize_t msize
, malign
, ssize
;
1278 uint32_t kind
, vlen
, root
;
1281 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1282 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1285 return (ctf_set_errno (fp
, ECTF_BADID
));
1287 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1288 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1289 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1291 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1292 return (ctf_set_errno (fp
, ECTF_NOTSOU
));
1294 if (vlen
== CTF_MAX_VLEN
)
1295 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1299 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1300 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1302 if (dmd
->dmd_name
!= NULL
&& strcmp (dmd
->dmd_name
, name
) == 0)
1303 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1307 if ((msize
= ctf_type_size (fp
, type
)) == CTF_ERR
||
1308 (malign
= ctf_type_align (fp
, type
)) == CTF_ERR
)
1309 return CTF_ERR
; /* errno is set for us. */
1311 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1312 return (ctf_set_errno (fp
, EAGAIN
));
1314 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1317 return (ctf_set_errno (fp
, EAGAIN
));
1321 dmd
->dmd_type
= type
;
1322 dmd
->dmd_value
= -1;
1324 if (kind
== CTF_K_STRUCT
&& vlen
!= 0)
1326 if (bit_offset
== (unsigned long) - 1)
1328 /* Natural alignment. */
1330 ctf_dmdef_t
*lmd
= ctf_list_prev (&dtd
->dtd_u
.dtu_members
);
1331 ctf_id_t ltype
= ctf_type_resolve (fp
, lmd
->dmd_type
);
1332 size_t off
= lmd
->dmd_offset
;
1334 ctf_encoding_t linfo
;
1337 if (ctf_type_encoding (fp
, ltype
, &linfo
) != CTF_ERR
)
1338 off
+= linfo
.cte_bits
;
1339 else if ((lsize
= ctf_type_size (fp
, ltype
)) != CTF_ERR
)
1340 off
+= lsize
* NBBY
;
1342 /* Round up the offset of the end of the last member to
1343 the next byte boundary, convert 'off' to bytes, and
1344 then round it up again to the next multiple of the
1345 alignment required by the new member. Finally,
1346 convert back to bits and store the result in
1347 dmd_offset. Technically we could do more efficient
1348 packing if the new member is a bit-field, but we're
1349 the "compiler" and ANSI says we can do as we choose. */
1351 off
= roundup (off
, NBBY
) / NBBY
;
1352 off
= roundup (off
, MAX (malign
, 1));
1353 dmd
->dmd_offset
= off
* NBBY
;
1354 ssize
= off
+ msize
;
1358 /* Specified offset in bits. */
1360 dmd
->dmd_offset
= bit_offset
;
1361 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1362 ssize
= MAX (ssize
, (bit_offset
/ NBBY
) + msize
);
1367 dmd
->dmd_offset
= 0;
1368 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1369 ssize
= MAX (ssize
, msize
);
1372 if (ssize
> CTF_MAX_SIZE
)
1374 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1375 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (ssize
);
1376 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (ssize
);
1379 dtd
->dtd_data
.ctt_size
= (uint32_t) ssize
;
1381 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1382 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1385 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
1387 fp
->ctf_flags
|= LCTF_DIRTY
;
1392 ctf_add_member_encoded (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1393 ctf_id_t type
, unsigned long bit_offset
,
1394 const ctf_encoding_t encoding
)
1396 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
1397 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1400 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) && (kind
!= CTF_K_ENUM
))
1401 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1403 if ((type
= ctf_add_slice (fp
, CTF_ADD_NONROOT
, otype
, &encoding
)) == CTF_ERR
)
1404 return CTF_ERR
; /* errno is set for us. */
1406 return ctf_add_member_offset (fp
, souid
, name
, type
, bit_offset
);
1410 ctf_add_member (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1413 return ctf_add_member_offset (fp
, souid
, name
, type
, (unsigned long) - 1);
1417 ctf_add_variable (ctf_file_t
*fp
, const char *name
, ctf_id_t ref
)
1420 ctf_file_t
*tmp
= fp
;
1422 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1423 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1425 if (ctf_dvd_lookup (fp
, name
) != NULL
)
1426 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1428 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1429 return CTF_ERR
; /* errno is set for us. */
1431 if ((dvd
= ctf_alloc (sizeof (ctf_dvdef_t
))) == NULL
)
1432 return (ctf_set_errno (fp
, EAGAIN
));
1434 if (name
!= NULL
&& (dvd
->dvd_name
= ctf_strdup (name
)) == NULL
)
1437 return (ctf_set_errno (fp
, EAGAIN
));
1439 dvd
->dvd_type
= ref
;
1440 dvd
->dvd_snapshots
= fp
->ctf_snapshots
;
1442 ctf_dvd_insert (fp
, dvd
);
1444 fp
->ctf_dtvstrlen
+= strlen (name
) + 1;
1445 fp
->ctf_flags
|= LCTF_DIRTY
;
1449 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1450 This is useful for saving the results of dynamic CTF containers. */
1452 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1454 const unsigned char *buf
= fp
->ctf_base
;
1455 ssize_t resid
= fp
->ctf_size
;
1460 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1461 return (ctf_set_errno (fp
, errno
));
1469 /* Compress the specified CTF data stream and write it to the specified file
1472 ctf_compress_write (ctf_file_t
*fp
, int fd
)
1477 ctf_header_t
*hp
= &h
;
1478 ssize_t header_len
= sizeof (ctf_header_t
);
1479 ssize_t compress_len
;
1480 size_t max_compress_len
= compressBound (fp
->ctf_size
- header_len
);
1485 memcpy (hp
, fp
->ctf_base
, header_len
);
1486 hp
->cth_flags
|= CTF_F_COMPRESS
;
1488 if ((buf
= ctf_data_alloc (max_compress_len
)) == NULL
)
1489 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
1491 compress_len
= max_compress_len
;
1492 if ((rc
= compress (buf
, (uLongf
*) & compress_len
,
1493 fp
->ctf_base
+ header_len
,
1494 fp
->ctf_size
- header_len
)) != Z_OK
)
1496 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
1497 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
1501 while (header_len
> 0)
1503 if ((len
= write (fd
, hp
, header_len
)) < 0)
1505 err
= ctf_set_errno (fp
, errno
);
1513 while (compress_len
> 0)
1515 if ((len
= write (fd
, bp
, compress_len
)) < 0)
1517 err
= ctf_set_errno (fp
, errno
);
1520 compress_len
-= len
;
1525 ctf_data_free (buf
, max_compress_len
);
1529 /* Write the uncompressed CTF data stream to the specified file descriptor.
1530 This is useful for saving the results of dynamic CTF containers. */
1532 ctf_write (ctf_file_t
*fp
, int fd
)
1534 const unsigned char *buf
= fp
->ctf_base
;
1535 ssize_t resid
= fp
->ctf_size
;
1540 if ((len
= write (fd
, buf
, resid
)) < 0)
1541 return (ctf_set_errno (fp
, errno
));