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
;
1450 enumcmp (const char *name
, int value
, void *arg
)
1452 ctf_bundle_t
*ctb
= arg
;
1455 if (ctf_enum_value (ctb
->ctb_file
, ctb
->ctb_type
, name
, &bvalue
) == CTF_ERR
)
1457 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1460 if (value
!= bvalue
)
1462 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1470 enumadd (const char *name
, int value
, void *arg
)
1472 ctf_bundle_t
*ctb
= arg
;
1474 return (ctf_add_enumerator (ctb
->ctb_file
, ctb
->ctb_type
,
1475 name
, value
) == CTF_ERR
);
1479 membcmp (const char *name
, ctf_id_t type _libctf_unused_
, unsigned long offset
,
1482 ctf_bundle_t
*ctb
= arg
;
1485 if (ctf_member_info (ctb
->ctb_file
, ctb
->ctb_type
, name
, &ctm
) == CTF_ERR
)
1487 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1490 if (ctm
.ctm_offset
!= offset
)
1492 ctf_dprintf ("Conflict due to member %s offset change: "
1493 "%lx versus %lx\n", name
, ctm
.ctm_offset
, offset
);
1500 membadd (const char *name
, ctf_id_t type
, unsigned long offset
, void *arg
)
1502 ctf_bundle_t
*ctb
= arg
;
1506 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1507 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1509 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1512 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1515 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1516 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1518 dmd
->dmd_type
= type
;
1519 dmd
->dmd_offset
= offset
;
1520 dmd
->dmd_value
= -1;
1522 ctf_list_append (&ctb
->ctb_dtd
->dtd_u
.dtu_members
, dmd
);
1525 ctb
->ctb_file
->ctf_dtvstrlen
+= strlen (s
) + 1;
1527 ctb
->ctb_file
->ctf_flags
|= LCTF_DIRTY
;
1531 /* The ctf_add_type routine is used to copy a type from a source CTF container
1532 to a dynamic destination container. This routine operates recursively by
1533 following the source type's links and embedded member types. If the
1534 destination container already contains a named type which has the same
1535 attributes, then we succeed and return this type but no changes occur. */
1537 ctf_add_type (ctf_file_t
*dst_fp
, ctf_file_t
*src_fp
, ctf_id_t src_type
)
1539 ctf_id_t dst_type
= CTF_ERR
;
1540 uint32_t dst_kind
= CTF_K_UNKNOWN
;
1544 uint32_t kind
, flag
, vlen
;
1546 const ctf_type_t
*src_tp
, *dst_tp
;
1547 ctf_bundle_t src
, dst
;
1548 ctf_encoding_t src_en
, dst_en
;
1549 ctf_arinfo_t src_ar
, dst_ar
;
1557 if (!(dst_fp
->ctf_flags
& LCTF_RDWR
))
1558 return (ctf_set_errno (dst_fp
, ECTF_RDONLY
));
1560 if ((src_tp
= ctf_lookup_by_id (&src_fp
, src_type
)) == NULL
)
1561 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1563 name
= ctf_strptr (src_fp
, src_tp
->ctt_name
);
1564 kind
= LCTF_INFO_KIND (src_fp
, src_tp
->ctt_info
);
1565 flag
= LCTF_INFO_ISROOT (src_fp
, src_tp
->ctt_info
);
1566 vlen
= LCTF_INFO_VLEN (src_fp
, src_tp
->ctt_info
);
1571 hp
= dst_fp
->ctf_structs
;
1574 hp
= dst_fp
->ctf_unions
;
1577 hp
= dst_fp
->ctf_enums
;
1580 hp
= dst_fp
->ctf_names
;
1584 /* If the source type has a name and is a root type (visible at the
1585 top-level scope), lookup the name in the destination container and
1586 verify that it is of the same kind before we do anything else. */
1588 if ((flag
& CTF_ADD_ROOT
) && name
[0] != '\0'
1589 && (tmp
= ctf_hash_lookup_type (hp
, dst_fp
, name
)) != 0)
1592 dst_kind
= ctf_type_kind_unsliced (dst_fp
, dst_type
);
1595 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1596 unless dst_type is a forward declaration and src_type is a struct,
1597 union, or enum (i.e. the definition of the previous forward decl). */
1599 if (dst_type
!= CTF_ERR
&& dst_kind
!= kind
1600 && (dst_kind
!= CTF_K_FORWARD
1601 || (kind
!= CTF_K_ENUM
&& kind
!= CTF_K_STRUCT
1602 && kind
!= CTF_K_UNION
)))
1604 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1605 "old (ID %lx): %i\n", name
, kind
, dst_type
, dst_kind
);
1606 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1609 /* We take special action for an integer, float, or slice since it is
1610 described not only by its name but also its encoding. For integers,
1611 bit-fields exploit this degeneracy. */
1613 if (kind
== CTF_K_INTEGER
|| kind
== CTF_K_FLOAT
|| kind
== CTF_K_SLICE
)
1615 if (ctf_type_encoding (src_fp
, src_type
, &src_en
) != 0)
1616 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1618 if (dst_type
!= CTF_ERR
)
1620 ctf_file_t
*fp
= dst_fp
;
1622 if ((dst_tp
= ctf_lookup_by_id (&fp
, dst_type
)) == NULL
)
1625 if (LCTF_INFO_ISROOT (fp
, dst_tp
->ctt_info
) & CTF_ADD_ROOT
)
1627 /* The type that we found in the hash is also root-visible. If
1628 the two types match then use the existing one; otherwise,
1629 declare a conflict. Note: slices are not certain to match
1630 even if there is no conflict: we must check the contained type
1633 if (ctf_type_encoding (dst_fp
, dst_type
, &dst_en
) != 0)
1634 return CTF_ERR
; /* errno set for us. */
1636 if (memcmp (&src_en
, &dst_en
, sizeof (ctf_encoding_t
)) == 0)
1638 if (kind
!= CTF_K_SLICE
)
1643 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1648 /* We found a non-root-visible type in the hash. We reset
1649 dst_type to ensure that we continue to look for a possible
1650 conflict in the pending list. */
1657 /* If the non-empty name was not found in the appropriate hash, search
1658 the list of pending dynamic definitions that are not yet committed.
1659 If a matching name and kind are found, assume this is the type that
1660 we are looking for. This is necessary to permit ctf_add_type() to
1661 operate recursively on entities such as a struct that contains a
1662 pointer member that refers to the same struct type. */
1664 if (dst_type
== CTF_ERR
&& name
[0] != '\0')
1666 for (dtd
= ctf_list_prev (&dst_fp
->ctf_dtdefs
); dtd
!= NULL
1667 && LCTF_TYPE_TO_INDEX (src_fp
, dtd
->dtd_type
) > dst_fp
->ctf_dtoldid
;
1668 dtd
= ctf_list_prev (dtd
))
1670 if (LCTF_INFO_KIND (src_fp
, dtd
->dtd_data
.ctt_info
) == kind
1671 && dtd
->dtd_name
!= NULL
&& strcmp (dtd
->dtd_name
, name
) == 0)
1673 int sroot
; /* Is the src root-visible? */
1674 int droot
; /* Is the dst root-visible? */
1675 int match
; /* Do the encodings match? */
1677 if (kind
!= CTF_K_INTEGER
&& kind
!= CTF_K_FLOAT
&& kind
!= CTF_K_SLICE
)
1678 return dtd
->dtd_type
;
1680 sroot
= (flag
& CTF_ADD_ROOT
);
1681 droot
= (LCTF_INFO_ISROOT (dst_fp
,
1683 ctt_info
) & CTF_ADD_ROOT
);
1685 match
= (memcmp (&src_en
, &dtd
->dtd_u
.dtu_enc
,
1686 sizeof (ctf_encoding_t
)) == 0);
1688 /* If the types share the same encoding then return the id of the
1689 first unless one type is root-visible and the other is not; in
1690 that case the new type must get a new id if a match is never
1691 found. Note: slices are not certain to match even if there is
1692 no conflict: we must check the contained type too. */
1694 if (match
&& sroot
== droot
)
1696 if (kind
!= CTF_K_SLICE
)
1697 return dtd
->dtd_type
;
1699 else if (!match
&& sroot
&& droot
)
1701 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1707 src
.ctb_file
= src_fp
;
1708 src
.ctb_type
= src_type
;
1711 dst
.ctb_file
= dst_fp
;
1712 dst
.ctb_type
= dst_type
;
1715 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1716 we add a new type with the same properties as src_type to dst_fp.
1717 If dst_type is not CTF_ERR, then we verify that dst_type has the
1718 same attributes as src_type. We recurse for embedded references. */
1722 /* If we found a match we will have either returned it or declared a
1724 dst_type
= ctf_add_integer (dst_fp
, flag
, name
, &src_en
);
1728 /* If we found a match we will have either returned it or declared a
1730 dst_type
= ctf_add_float (dst_fp
, flag
, name
, &src_en
);
1734 /* We have checked for conflicting encodings: now try to add the
1736 src_type
= ctf_type_reference (src_fp
, src_type
);
1737 dst_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1739 if (src_type
== CTF_ERR
)
1740 return CTF_ERR
; /* errno is set for us. */
1742 dst_type
= ctf_add_slice (dst_fp
, flag
, src_type
, &src_en
);
1746 case CTF_K_VOLATILE
:
1748 case CTF_K_RESTRICT
:
1749 src_type
= ctf_type_reference (src_fp
, src_type
);
1750 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1752 if (src_type
== CTF_ERR
)
1753 return CTF_ERR
; /* errno is set for us. */
1755 dst_type
= ctf_add_reftype (dst_fp
, flag
, src_type
, kind
);
1759 if (ctf_array_info (src_fp
, src_type
, &src_ar
) == CTF_ERR
)
1760 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1762 src_ar
.ctr_contents
=
1763 ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_contents
);
1764 src_ar
.ctr_index
= ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_index
);
1765 src_ar
.ctr_nelems
= src_ar
.ctr_nelems
;
1767 if (src_ar
.ctr_contents
== CTF_ERR
|| src_ar
.ctr_index
== CTF_ERR
)
1768 return CTF_ERR
; /* errno is set for us. */
1770 if (dst_type
!= CTF_ERR
)
1772 if (ctf_array_info (dst_fp
, dst_type
, &dst_ar
) != 0)
1773 return CTF_ERR
; /* errno is set for us. */
1775 if (memcmp (&src_ar
, &dst_ar
, sizeof (ctf_arinfo_t
)))
1777 ctf_dprintf ("Conflict for type %s against ID %lx: "
1778 "array info differs, old %lx/%lx/%x; "
1779 "new: %lx/%lx/%x\n", name
, dst_type
,
1780 src_ar
.ctr_contents
, src_ar
.ctr_index
,
1781 src_ar
.ctr_nelems
, dst_ar
.ctr_contents
,
1782 dst_ar
.ctr_index
, dst_ar
.ctr_nelems
);
1783 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1787 dst_type
= ctf_add_array (dst_fp
, flag
, &src_ar
);
1790 case CTF_K_FUNCTION
:
1791 ctc
.ctc_return
= ctf_add_type (dst_fp
, src_fp
, src_tp
->ctt_type
);
1795 if (ctc
.ctc_return
== CTF_ERR
)
1796 return CTF_ERR
; /* errno is set for us. */
1798 dst_type
= ctf_add_function (dst_fp
, flag
, &ctc
, NULL
);
1807 /* Technically to match a struct or union we need to check both
1808 ways (src members vs. dst, dst members vs. src) but we make
1809 this more optimal by only checking src vs. dst and comparing
1810 the total size of the structure (which we must do anyway)
1811 which covers the possibility of dst members not in src.
1812 This optimization can be defeated for unions, but is so
1813 pathological as to render it irrelevant for our purposes. */
1815 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1817 if (ctf_type_size (src_fp
, src_type
) !=
1818 ctf_type_size (dst_fp
, dst_type
))
1820 ctf_dprintf ("Conflict for type %s against ID %lx: "
1821 "union size differs, old %li, new %li\n",
1822 name
, dst_type
, ctf_type_size (src_fp
, src_type
),
1823 ctf_type_size (dst_fp
, dst_type
));
1824 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1827 if (ctf_member_iter (src_fp
, src_type
, membcmp
, &dst
))
1829 ctf_dprintf ("Conflict for type %s against ID %lx: "
1830 "members differ, see above\n", name
, dst_type
);
1831 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1837 /* Unlike the other cases, copying structs and unions is done
1838 manually so as to avoid repeated lookups in ctf_add_member
1839 and to ensure the exact same member offsets as in src_type. */
1841 dst_type
= ctf_add_generic (dst_fp
, flag
, name
, &dtd
);
1842 if (dst_type
== CTF_ERR
)
1843 return CTF_ERR
; /* errno is set for us. */
1845 dst
.ctb_type
= dst_type
;
1848 if (ctf_member_iter (src_fp
, src_type
, membadd
, &dst
) != 0)
1849 errs
++; /* Increment errs and fail at bottom of case. */
1851 if ((size
= ctf_type_size (src_fp
, src_type
)) > CTF_MAX_SIZE
)
1853 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1854 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1855 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1858 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1860 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, vlen
);
1862 /* Make a final pass through the members changing each dmd_type (a
1863 src_fp type) to an equivalent type in dst_fp. We pass through all
1864 members, leaving any that fail set to CTF_ERR. */
1865 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1866 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1868 if ((dmd
->dmd_type
= ctf_add_type (dst_fp
, src_fp
,
1869 dmd
->dmd_type
)) == CTF_ERR
)
1874 return CTF_ERR
; /* errno is set for us. */
1879 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1881 if (ctf_enum_iter (src_fp
, src_type
, enumcmp
, &dst
)
1882 || ctf_enum_iter (dst_fp
, dst_type
, enumcmp
, &src
))
1884 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1885 "members differ, see above\n", name
, dst_type
);
1886 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1891 dst_type
= ctf_add_enum (dst_fp
, flag
, name
);
1892 if ((dst
.ctb_type
= dst_type
) == CTF_ERR
1893 || ctf_enum_iter (src_fp
, src_type
, enumadd
, &dst
))
1894 return CTF_ERR
; /* errno is set for us */
1899 if (dst_type
== CTF_ERR
)
1901 dst_type
= ctf_add_forward (dst_fp
, flag
,
1902 name
, CTF_K_STRUCT
); /* Assume STRUCT. */
1907 src_type
= ctf_type_reference (src_fp
, src_type
);
1908 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1910 if (src_type
== CTF_ERR
)
1911 return CTF_ERR
; /* errno is set for us. */
1913 /* If dst_type is not CTF_ERR at this point, we should check if
1914 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1915 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1916 that vary based on things like if 32-bit then pid_t is int otherwise
1917 long. We therefore omit this check and assume that if the identically
1918 named typedef already exists in dst_fp, it is correct or
1921 if (dst_type
== CTF_ERR
)
1923 dst_type
= ctf_add_typedef (dst_fp
, flag
, name
, src_type
);
1928 return (ctf_set_errno (dst_fp
, ECTF_CORRUPT
));
1934 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1935 This is useful for saving the results of dynamic CTF containers. */
1937 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1939 const unsigned char *buf
= fp
->ctf_base
;
1940 ssize_t resid
= fp
->ctf_size
;
1945 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1946 return (ctf_set_errno (fp
, errno
));
1954 /* Compress the specified CTF data stream and write it to the specified file
1957 ctf_compress_write (ctf_file_t
*fp
, int fd
)
1962 ctf_header_t
*hp
= &h
;
1963 ssize_t header_len
= sizeof (ctf_header_t
);
1964 ssize_t compress_len
;
1965 size_t max_compress_len
= compressBound (fp
->ctf_size
- header_len
);
1970 memcpy (hp
, fp
->ctf_base
, header_len
);
1971 hp
->cth_flags
|= CTF_F_COMPRESS
;
1973 if ((buf
= ctf_data_alloc (max_compress_len
)) == NULL
)
1974 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
1976 compress_len
= max_compress_len
;
1977 if ((rc
= compress (buf
, (uLongf
*) & compress_len
,
1978 fp
->ctf_base
+ header_len
,
1979 fp
->ctf_size
- header_len
)) != Z_OK
)
1981 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
1982 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
1986 while (header_len
> 0)
1988 if ((len
= write (fd
, hp
, header_len
)) < 0)
1990 err
= ctf_set_errno (fp
, errno
);
1998 while (compress_len
> 0)
2000 if ((len
= write (fd
, bp
, compress_len
)) < 0)
2002 err
= ctf_set_errno (fp
, errno
);
2005 compress_len
-= len
;
2010 ctf_data_free (buf
, max_compress_len
);
2014 /* Write the uncompressed CTF data stream to the specified file descriptor.
2015 This is useful for saving the results of dynamic CTF containers. */
2017 ctf_write (ctf_file_t
*fp
, int fd
)
2019 const unsigned char *buf
= fp
->ctf_base
;
2020 ssize_t resid
= fp
->ctf_size
;
2025 if ((len
= write (fd
, buf
, resid
)) < 0)
2026 return (ctf_set_errno (fp
, errno
));