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 set dtvstrlen to 1 to reserve the
33 first byte of the string table for a \0 byte, and we start assigning type
34 IDs at 1 because type ID 0 is used as a sentinel and a not-found
38 ctf_create (int *errp
)
40 static const ctf_header_t hdr
= { .cth_preamble
= { CTF_MAGIC
, CTF_VERSION
, 0 } };
42 ctf_dynhash_t
*dthash
;
43 ctf_dynhash_t
*dvhash
;
44 ctf_dynhash_t
*dtbyname
;
49 dthash
= ctf_dynhash_create (ctf_hash_integer
, ctf_hash_eq_integer
,
53 ctf_set_open_errno (errp
, EAGAIN
);
57 dvhash
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
61 ctf_set_open_errno (errp
, EAGAIN
);
65 dtbyname
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
69 ctf_set_open_errno (errp
, EAGAIN
);
73 cts
.cts_name
= _CTF_SECTION
;
75 cts
.cts_size
= sizeof (hdr
);
78 if ((fp
= ctf_bufopen (&cts
, NULL
, NULL
, errp
)) == NULL
)
81 fp
->ctf_flags
|= LCTF_RDWR
;
82 fp
->ctf_dtbyname
= dtbyname
;
83 fp
->ctf_dthash
= dthash
;
84 fp
->ctf_dvhash
= dvhash
;
85 fp
->ctf_dtvstrlen
= 1;
88 fp
->ctf_snapshots
= 0;
89 fp
->ctf_snapshot_lu
= 0;
94 ctf_dynhash_destroy (dtbyname
);
96 ctf_dynhash_destroy (dvhash
);
98 ctf_dynhash_destroy (dthash
);
103 static unsigned char *
104 ctf_copy_smembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
106 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
109 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
114 soff
+= strlen (dmd
->dmd_name
) + 1;
119 ctm
.ctm_type
= (uint32_t) dmd
->dmd_type
;
120 ctm
.ctm_offset
= (uint32_t) dmd
->dmd_offset
;
122 memcpy (t
, &ctm
, sizeof (ctm
));
129 static unsigned char *
130 ctf_copy_lmembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
132 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
135 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
139 ctlm
.ctlm_name
= soff
;
140 soff
+= strlen (dmd
->dmd_name
) + 1;
145 ctlm
.ctlm_type
= (uint32_t) dmd
->dmd_type
;
146 ctlm
.ctlm_offsethi
= CTF_OFFSET_TO_LMEMHI (dmd
->dmd_offset
);
147 ctlm
.ctlm_offsetlo
= CTF_OFFSET_TO_LMEMLO (dmd
->dmd_offset
);
149 memcpy (t
, &ctlm
, sizeof (ctlm
));
156 static unsigned char *
157 ctf_copy_emembers (ctf_dtdef_t
*dtd
, uint32_t soff
, unsigned char *t
)
159 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
162 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
165 cte
.cte_value
= dmd
->dmd_value
;
166 soff
+= strlen (dmd
->dmd_name
) + 1;
167 memcpy (t
, &cte
, sizeof (cte
));
174 static unsigned char *
175 ctf_copy_membnames (ctf_dtdef_t
*dtd
, unsigned char *s
)
177 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
180 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
182 if (dmd
->dmd_name
== NULL
)
183 continue; /* Skip anonymous members. */
184 len
= strlen (dmd
->dmd_name
) + 1;
185 memcpy (s
, dmd
->dmd_name
, len
);
192 /* Sort a newly-constructed static variable array. */
195 ctf_sort_var (const void *one_
, const void *two_
, void *strtab_
)
197 const ctf_varent_t
*one
= one_
;
198 const ctf_varent_t
*two
= two_
;
199 const char *strtab
= strtab_
;
200 const char *n1
= strtab
+ CTF_NAME_OFFSET (one
->ctv_name
);
201 const char *n2
= strtab
+ CTF_NAME_OFFSET (two
->ctv_name
);
203 return (strcmp (n1
, n2
));
206 /* If the specified CTF container is writable and has been modified, reload this
207 container with the updated type definitions. In order to make this code and
208 the rest of libctf as simple as possible, we perform updates by taking the
209 dynamic type definitions and creating an in-memory CTF file containing the
210 definitions, and then call ctf_simple_open() on it. This not only leverages
211 ctf_simple_open(), but also avoids having to bifurcate the rest of the library
212 code with different lookup paths for static and dynamic type definitions. We
213 are therefore optimizing greatly for lookup over update, which we assume will
214 be an uncommon operation. We perform one extra trick here for the benefit of
215 callers and to keep our code simple: ctf_simple_open() will return a new
216 ctf_file_t, but we want to keep the fp constant for the caller, so after
217 ctf_simple_open() returns, we use memcpy to swap the interior of the old and
218 new ctf_file_t's, and then free the old. */
220 ctf_update (ctf_file_t
*fp
)
222 ctf_file_t ofp
, *nfp
;
226 ctf_varent_t
*dvarents
;
228 unsigned char *s
, *s0
, *t
;
230 size_t buf_size
, type_size
, nvars
;
234 if (!(fp
->ctf_flags
& LCTF_RDWR
))
235 return (ctf_set_errno (fp
, ECTF_RDONLY
));
237 /* Update required? */
238 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
241 /* Fill in an initial CTF header. We will leave the label, object,
242 and function sections empty and only output a header, type section,
243 and string table. The type section begins at a 4-byte aligned
244 boundary past the CTF header itself (at relative offset zero). */
246 memset (&hdr
, 0, sizeof (hdr
));
247 hdr
.cth_magic
= CTF_MAGIC
;
248 hdr
.cth_version
= CTF_VERSION
;
250 if (fp
->ctf_flags
& LCTF_CHILD
)
251 hdr
.cth_parname
= 1; /* parname added just below. */
253 /* Iterate through the dynamic type definition list and compute the
254 size of the CTF type section we will need to generate. */
256 for (type_size
= 0, dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
257 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
259 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
260 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
262 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
263 type_size
+= sizeof (ctf_stype_t
);
265 type_size
+= sizeof (ctf_type_t
);
271 type_size
+= sizeof (uint32_t);
274 type_size
+= sizeof (ctf_array_t
);
277 type_size
+= sizeof (ctf_slice_t
);
280 type_size
+= sizeof (uint32_t) * (vlen
+ (vlen
& 1));
284 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
285 type_size
+= sizeof (ctf_member_t
) * vlen
;
287 type_size
+= sizeof (ctf_lmember_t
) * vlen
;
290 type_size
+= sizeof (ctf_enum_t
) * vlen
;
295 /* Computing the number of entries in the CTF variable section is much
298 for (nvars
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
299 dvd
!= NULL
; dvd
= ctf_list_next (dvd
), nvars
++);
301 /* Fill in the string table and type offset and size, compute the size
302 of the entire CTF buffer we need, and then allocate a new buffer and
303 memcpy the finished header to the start of the buffer. */
305 hdr
.cth_typeoff
= hdr
.cth_varoff
+ (nvars
* sizeof (ctf_varent_t
));
306 hdr
.cth_stroff
= hdr
.cth_typeoff
+ type_size
;
307 hdr
.cth_strlen
= fp
->ctf_dtvstrlen
;
308 if (fp
->ctf_parname
!= NULL
)
309 hdr
.cth_strlen
+= strlen (fp
->ctf_parname
) + 1;
311 buf_size
= sizeof (ctf_header_t
) + hdr
.cth_stroff
+ hdr
.cth_strlen
;
313 if ((buf
= malloc (buf_size
)) == NULL
)
314 return (ctf_set_errno (fp
, EAGAIN
));
316 memcpy (buf
, &hdr
, sizeof (ctf_header_t
));
317 t
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_varoff
;
318 s
= s0
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
;
323 if (fp
->ctf_parname
!= NULL
)
325 memcpy (s
, fp
->ctf_parname
, strlen (fp
->ctf_parname
) + 1);
326 s
+= strlen (fp
->ctf_parname
) + 1;
329 /* Work over the variable list, translating everything into
330 ctf_varent_t's and filling out the string table, then sort the buffer
331 of ctf_varent_t's. */
333 dvarents
= (ctf_varent_t
*) t
;
334 for (i
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
335 dvd
= ctf_list_next (dvd
), i
++)
337 ctf_varent_t
*var
= &dvarents
[i
];
338 size_t len
= strlen (dvd
->dvd_name
) + 1;
340 var
->ctv_name
= (uint32_t) (s
- s0
);
341 var
->ctv_type
= dvd
->dvd_type
;
342 memcpy (s
, dvd
->dvd_name
, len
);
347 ctf_qsort_r (dvarents
, nvars
, sizeof (ctf_varent_t
), ctf_sort_var
, s0
);
348 t
+= sizeof (ctf_varent_t
) * nvars
;
350 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_typeoff
);
352 /* We now take a final lap through the dynamic type definition list and
353 copy the appropriate type records and strings to the output buffer. */
355 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
356 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
359 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
360 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
366 if (dtd
->dtd_name
!= NULL
)
368 dtd
->dtd_data
.ctt_name
= (uint32_t) (s
- s0
);
369 len
= strlen (dtd
->dtd_name
) + 1;
370 memcpy (s
, dtd
->dtd_name
, len
);
374 dtd
->dtd_data
.ctt_name
= 0;
376 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
377 len
= sizeof (ctf_stype_t
);
379 len
= sizeof (ctf_type_t
);
381 memcpy (t
, &dtd
->dtd_data
, len
);
388 if (kind
== CTF_K_INTEGER
)
390 encoding
= CTF_INT_DATA (dtd
->dtd_u
.dtu_enc
.cte_format
,
391 dtd
->dtd_u
.dtu_enc
.cte_offset
,
392 dtd
->dtd_u
.dtu_enc
.cte_bits
);
396 encoding
= CTF_FP_DATA (dtd
->dtd_u
.dtu_enc
.cte_format
,
397 dtd
->dtd_u
.dtu_enc
.cte_offset
,
398 dtd
->dtd_u
.dtu_enc
.cte_bits
);
400 memcpy (t
, &encoding
, sizeof (encoding
));
401 t
+= sizeof (encoding
);
405 memcpy (t
, &dtd
->dtd_u
.dtu_slice
, sizeof (struct ctf_slice
));
406 t
+= sizeof (struct ctf_slice
);
410 cta
.cta_contents
= (uint32_t) dtd
->dtd_u
.dtu_arr
.ctr_contents
;
411 cta
.cta_index
= (uint32_t) dtd
->dtd_u
.dtu_arr
.ctr_index
;
412 cta
.cta_nelems
= dtd
->dtd_u
.dtu_arr
.ctr_nelems
;
413 memcpy (t
, &cta
, sizeof (cta
));
419 uint32_t *argv
= (uint32_t *) (uintptr_t) t
;
422 for (argc
= 0; argc
< vlen
; argc
++)
423 *argv
++ = (uint32_t) dtd
->dtd_u
.dtu_argv
[argc
];
426 *argv
++ = 0; /* Pad to 4-byte boundary. */
428 t
= (unsigned char *) argv
;
434 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
435 t
= ctf_copy_smembers (dtd
, (uint32_t) (s
- s0
), t
);
437 t
= ctf_copy_lmembers (dtd
, (uint32_t) (s
- s0
), t
);
438 s
= ctf_copy_membnames (dtd
, s
);
442 t
= ctf_copy_emembers (dtd
, (uint32_t) (s
- s0
), t
);
443 s
= ctf_copy_membnames (dtd
, s
);
447 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
);
449 /* Finally, we are ready to ctf_simple_open() the new container. If this
450 is successful, we then switch nfp and fp and free the old container. */
452 if ((nfp
= ctf_simple_open (buf
, buf_size
, NULL
, 0, 0, NULL
, 0, &err
)) == NULL
)
455 return (ctf_set_errno (fp
, err
));
458 (void) ctf_setmodel (nfp
, ctf_getmodel (fp
));
459 (void) ctf_import (nfp
, fp
->ctf_parent
);
461 nfp
->ctf_refcnt
= fp
->ctf_refcnt
;
462 nfp
->ctf_flags
|= fp
->ctf_flags
& ~LCTF_DIRTY
;
463 nfp
->ctf_data
.cts_data
= NULL
; /* Force ctf_free() 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_dtvstrlen
= fp
->ctf_dtvstrlen
;
470 nfp
->ctf_dtnextid
= fp
->ctf_dtnextid
;
471 nfp
->ctf_dtoldid
= fp
->ctf_dtnextid
- 1;
472 nfp
->ctf_snapshots
= fp
->ctf_snapshots
+ 1;
473 nfp
->ctf_specific
= fp
->ctf_specific
;
475 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
477 fp
->ctf_dtbyname
= NULL
;
478 fp
->ctf_dthash
= NULL
;
479 memset (&fp
->ctf_dtdefs
, 0, sizeof (ctf_list_t
));
481 fp
->ctf_dvhash
= NULL
;
482 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
484 memcpy (&ofp
, fp
, sizeof (ctf_file_t
));
485 memcpy (fp
, nfp
, sizeof (ctf_file_t
));
486 memcpy (nfp
, &ofp
, sizeof (ctf_file_t
));
488 /* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
489 array of type name prefixes and the corresponding ctf_dynhash to use.
490 NOTE: This code must be kept in sync with the code in ctf_bufopen(). */
492 fp
->ctf_lookups
[0].ctl_hash
= fp
->ctf_structs
;
493 fp
->ctf_lookups
[1].ctl_hash
= fp
->ctf_unions
;
494 fp
->ctf_lookups
[2].ctl_hash
= fp
->ctf_enums
;
495 fp
->ctf_lookups
[3].ctl_hash
= fp
->ctf_names
;
497 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
498 ctf_file_close (nfp
);
504 ctf_prefixed_name (int kind
, const char *name
)
511 prefixed
= ctf_strdup ("struct ");
514 prefixed
= ctf_strdup ("union ");
517 prefixed
= ctf_strdup ("enum ");
520 prefixed
= ctf_strdup ("");
523 prefixed
= ctf_str_append (prefixed
, name
);
528 ctf_dtd_insert (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
530 if (ctf_dynhash_insert (fp
->ctf_dthash
, (void *) dtd
->dtd_type
, dtd
) < 0)
535 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
536 if (ctf_dynhash_insert (fp
->ctf_dtbyname
,
537 ctf_prefixed_name (kind
, dtd
->dtd_name
),
541 ctf_list_append (&fp
->ctf_dtdefs
, dtd
);
546 ctf_dtd_delete (ctf_file_t
*fp
, ctf_dtdef_t
*dtd
)
548 ctf_dmdef_t
*dmd
, *nmd
;
549 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
551 ctf_dynhash_remove (fp
->ctf_dthash
, (void *) dtd
->dtd_type
);
558 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
559 dmd
!= NULL
; dmd
= nmd
)
561 if (dmd
->dmd_name
!= NULL
)
563 fp
->ctf_dtvstrlen
-= strlen (dmd
->dmd_name
) + 1;
564 ctf_free (dmd
->dmd_name
);
566 nmd
= ctf_list_next (dmd
);
571 ctf_free (dtd
->dtd_u
.dtu_argv
);
579 name
= ctf_prefixed_name (kind
, dtd
->dtd_name
);
580 ctf_dynhash_remove (fp
->ctf_dtbyname
, name
);
583 fp
->ctf_dtvstrlen
-= strlen (dtd
->dtd_name
) + 1;
584 ctf_free (dtd
->dtd_name
);
587 ctf_list_delete (&fp
->ctf_dtdefs
, dtd
);
592 ctf_dtd_lookup (const ctf_file_t
*fp
, ctf_id_t type
)
594 return (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dthash
, (void *) type
);
598 ctf_dtd_lookup_type_by_name (ctf_file_t
*fp
, int kind
, const char *name
)
601 char *decorated
= ctf_prefixed_name (kind
, name
);
603 dtd
= (ctf_dtdef_t
*) ctf_dynhash_lookup (fp
->ctf_dtbyname
, decorated
);
607 return dtd
->dtd_type
;
613 ctf_dynamic_type (const ctf_file_t
*fp
, ctf_id_t id
)
617 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, id
))
620 idx
= LCTF_TYPE_TO_INDEX(fp
, id
);
622 if (((unsigned long) idx
> fp
->ctf_typemax
) &&
623 ((unsigned long) idx
< fp
->ctf_dtnextid
))
624 return ctf_dtd_lookup (fp
, id
);
629 ctf_dvd_insert (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
631 if (ctf_dynhash_insert (fp
->ctf_dvhash
, dvd
->dvd_name
, dvd
) < 0)
633 ctf_list_append (&fp
->ctf_dvdefs
, dvd
);
638 ctf_dvd_delete (ctf_file_t
*fp
, ctf_dvdef_t
*dvd
)
640 ctf_dynhash_remove (fp
->ctf_dvhash
, dvd
->dvd_name
);
642 fp
->ctf_dtvstrlen
-= strlen (dvd
->dvd_name
) + 1;
643 ctf_free (dvd
->dvd_name
);
645 ctf_list_delete (&fp
->ctf_dvdefs
, dvd
);
650 ctf_dvd_lookup (const ctf_file_t
*fp
, const char *name
)
652 return (ctf_dvdef_t
*) ctf_dynhash_lookup (fp
->ctf_dvhash
, name
);
655 /* Discard all of the dynamic type definitions and variable definitions that
656 have been added to the container since the last call to ctf_update(). We
657 locate such types by scanning the dtd list and deleting elements that have
658 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
659 by scanning the variable list and deleting elements that have update IDs
660 equal to the current value of the last-update snapshot count (indicating that
661 they were added after the most recent call to ctf_update()). */
663 ctf_discard (ctf_file_t
*fp
)
665 ctf_snapshot_id_t last_update
=
667 fp
->ctf_snapshot_lu
+ 1 };
669 /* Update required? */
670 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
673 return (ctf_rollback (fp
, last_update
));
677 ctf_snapshot (ctf_file_t
*fp
)
679 ctf_snapshot_id_t snapid
;
680 snapid
.dtd_id
= fp
->ctf_dtnextid
- 1;
681 snapid
.snapshot_id
= fp
->ctf_snapshots
++;
685 /* Like ctf_discard(), only discards everything after a particular ID. */
687 ctf_rollback (ctf_file_t
*fp
, ctf_snapshot_id_t id
)
689 ctf_dtdef_t
*dtd
, *ntd
;
690 ctf_dvdef_t
*dvd
, *nvd
;
692 if (!(fp
->ctf_flags
& LCTF_RDWR
))
693 return (ctf_set_errno (fp
, ECTF_RDONLY
));
695 if (fp
->ctf_dtoldid
> id
.dtd_id
)
696 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
698 if (fp
->ctf_snapshot_lu
>= id
.snapshot_id
)
699 return (ctf_set_errno (fp
, ECTF_OVERROLLBACK
));
701 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
); dtd
!= NULL
; dtd
= ntd
)
703 ntd
= ctf_list_next (dtd
);
705 if (LCTF_TYPE_TO_INDEX (fp
, dtd
->dtd_type
) <= id
.dtd_id
)
708 ctf_dtd_delete (fp
, dtd
);
711 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
713 nvd
= ctf_list_next (dvd
);
715 if (dvd
->dvd_snapshots
<= id
.snapshot_id
)
718 ctf_dvd_delete (fp
, dvd
);
721 fp
->ctf_dtnextid
= id
.dtd_id
+ 1;
722 fp
->ctf_snapshots
= id
.snapshot_id
;
724 if (fp
->ctf_snapshots
== fp
->ctf_snapshot_lu
)
725 fp
->ctf_flags
&= ~LCTF_DIRTY
;
731 ctf_add_generic (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
738 if (flag
!= CTF_ADD_NONROOT
&& flag
!= CTF_ADD_ROOT
)
739 return (ctf_set_errno (fp
, EINVAL
));
741 if (!(fp
->ctf_flags
& LCTF_RDWR
))
742 return (ctf_set_errno (fp
, ECTF_RDONLY
));
744 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) > CTF_MAX_TYPE
)
745 return (ctf_set_errno (fp
, ECTF_FULL
));
747 if (LCTF_INDEX_TO_TYPE (fp
, fp
->ctf_dtnextid
, 1) == CTF_MAX_PTYPE
)
748 return (ctf_set_errno (fp
, ECTF_FULL
));
750 if ((dtd
= ctf_alloc (sizeof (ctf_dtdef_t
))) == NULL
)
751 return (ctf_set_errno (fp
, EAGAIN
));
753 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
756 return (ctf_set_errno (fp
, EAGAIN
));
759 type
= fp
->ctf_dtnextid
++;
760 type
= LCTF_INDEX_TO_TYPE (fp
, type
, (fp
->ctf_flags
& LCTF_CHILD
));
762 memset (dtd
, 0, sizeof (ctf_dtdef_t
));
764 dtd
->dtd_type
= type
;
767 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
769 if (ctf_dtd_insert (fp
, dtd
) < 0)
772 return CTF_ERR
; /* errno is set for us. */
774 fp
->ctf_flags
|= LCTF_DIRTY
;
780 /* When encoding integer sizes, we want to convert a byte count in the range
781 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
782 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
798 ctf_add_encoded (ctf_file_t
*fp
, uint32_t flag
,
799 const char *name
, const ctf_encoding_t
*ep
, uint32_t kind
)
805 return (ctf_set_errno (fp
, EINVAL
));
807 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
808 return CTF_ERR
; /* errno is set for us. */
810 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
811 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
813 dtd
->dtd_u
.dtu_enc
= *ep
;
819 ctf_add_reftype (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
, uint32_t kind
)
823 ctf_file_t
*tmp
= fp
;
825 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
826 return (ctf_set_errno (fp
, EINVAL
));
828 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
829 return CTF_ERR
; /* errno is set for us. */
831 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
832 return CTF_ERR
; /* errno is set for us. */
834 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, 0);
835 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
841 ctf_add_slice (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
,
842 const ctf_encoding_t
*ep
)
847 const ctf_type_t
*tp
;
848 ctf_file_t
*tmp
= fp
;
851 return (ctf_set_errno (fp
, EINVAL
));
853 if ((ep
->cte_bits
> 255) || (ep
->cte_offset
> 255))
854 return (ctf_set_errno (fp
, ECTF_SLICEOVERFLOW
));
856 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
857 return (ctf_set_errno (fp
, EINVAL
));
859 if ((tp
= ctf_lookup_by_id (&tmp
, ref
)) == NULL
)
860 return CTF_ERR
; /* errno is set for us. */
862 kind
= ctf_type_kind_unsliced (tmp
, ref
);
863 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) &&
864 (kind
!= CTF_K_ENUM
))
865 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
867 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
868 return CTF_ERR
; /* errno is set for us. */
870 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_SLICE
, flag
, 0);
871 dtd
->dtd_data
.ctt_size
= clp2 (P2ROUNDUP (ep
->cte_bits
, CHAR_BIT
)
873 dtd
->dtd_u
.dtu_slice
.cts_type
= ref
;
874 dtd
->dtd_u
.dtu_slice
.cts_bits
= ep
->cte_bits
;
875 dtd
->dtd_u
.dtu_slice
.cts_offset
= ep
->cte_offset
;
881 ctf_add_integer (ctf_file_t
*fp
, uint32_t flag
,
882 const char *name
, const ctf_encoding_t
*ep
)
884 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_INTEGER
));
888 ctf_add_float (ctf_file_t
*fp
, uint32_t flag
,
889 const char *name
, const ctf_encoding_t
*ep
)
891 return (ctf_add_encoded (fp
, flag
, name
, ep
, CTF_K_FLOAT
));
895 ctf_add_pointer (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
897 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_POINTER
));
901 ctf_add_array (ctf_file_t
*fp
, uint32_t flag
, const ctf_arinfo_t
*arp
)
905 ctf_file_t
*tmp
= fp
;
908 return (ctf_set_errno (fp
, EINVAL
));
910 if (ctf_lookup_by_id (&tmp
, arp
->ctr_contents
) == NULL
)
911 return CTF_ERR
; /* errno is set for us. */
914 if (ctf_lookup_by_id (&tmp
, arp
->ctr_index
) == NULL
)
915 return CTF_ERR
; /* errno is set for us. */
917 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
918 return CTF_ERR
; /* errno is set for us. */
920 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ARRAY
, flag
, 0);
921 dtd
->dtd_data
.ctt_size
= 0;
922 dtd
->dtd_u
.dtu_arr
= *arp
;
928 ctf_set_array (ctf_file_t
*fp
, ctf_id_t type
, const ctf_arinfo_t
*arp
)
930 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
932 if (!(fp
->ctf_flags
& LCTF_RDWR
))
933 return (ctf_set_errno (fp
, ECTF_RDONLY
));
936 || LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
) != CTF_K_ARRAY
)
937 return (ctf_set_errno (fp
, ECTF_BADID
));
939 fp
->ctf_flags
|= LCTF_DIRTY
;
940 dtd
->dtd_u
.dtu_arr
= *arp
;
946 ctf_add_function (ctf_file_t
*fp
, uint32_t flag
,
947 const ctf_funcinfo_t
*ctc
, const ctf_id_t
*argv
)
952 ctf_id_t
*vdat
= NULL
;
953 ctf_file_t
*tmp
= fp
;
956 if (ctc
== NULL
|| (ctc
->ctc_flags
& ~CTF_FUNC_VARARG
) != 0
957 || (ctc
->ctc_argc
!= 0 && argv
== NULL
))
958 return (ctf_set_errno (fp
, EINVAL
));
960 vlen
= ctc
->ctc_argc
;
961 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
962 vlen
++; /* Add trailing zero to indicate varargs (see below). */
964 if (ctf_lookup_by_id (&tmp
, ctc
->ctc_return
) == NULL
)
965 return CTF_ERR
; /* errno is set for us. */
967 for (i
= 0; i
< ctc
->ctc_argc
; i
++)
970 if (ctf_lookup_by_id (&tmp
, argv
[i
]) == NULL
)
971 return CTF_ERR
; /* errno is set for us. */
974 if (vlen
> CTF_MAX_VLEN
)
975 return (ctf_set_errno (fp
, EOVERFLOW
));
977 if (vlen
!= 0 && (vdat
= ctf_alloc (sizeof (ctf_id_t
) * vlen
)) == NULL
)
978 return (ctf_set_errno (fp
, EAGAIN
));
980 if ((type
= ctf_add_generic (fp
, flag
, NULL
, &dtd
)) == CTF_ERR
)
983 return CTF_ERR
; /* errno is set for us. */
986 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FUNCTION
, flag
, vlen
);
987 dtd
->dtd_data
.ctt_type
= (uint32_t) ctc
->ctc_return
;
989 memcpy (vdat
, argv
, sizeof (ctf_id_t
) * ctc
->ctc_argc
);
990 if (ctc
->ctc_flags
& CTF_FUNC_VARARG
)
991 vdat
[vlen
- 1] = 0; /* Add trailing zero to indicate varargs. */
992 dtd
->dtd_u
.dtu_argv
= vdat
;
998 ctf_add_struct_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1001 ctf_hash_t
*hp
= fp
->ctf_structs
;
1005 /* Promote forwards to structs. */
1009 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1011 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_STRUCT
, name
);
1014 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1015 dtd
= ctf_dtd_lookup (fp
, type
);
1016 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1017 return CTF_ERR
; /* errno is set for us. */
1019 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_STRUCT
, flag
, 0);
1021 if (size
> CTF_MAX_SIZE
)
1023 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1024 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1025 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1028 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1034 ctf_add_struct (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1036 return (ctf_add_struct_sized (fp
, flag
, name
, 0));
1040 ctf_add_union_sized (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1043 ctf_hash_t
*hp
= fp
->ctf_unions
;
1047 /* Promote forwards to unions. */
1050 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1052 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_UNION
, name
);
1055 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1056 dtd
= ctf_dtd_lookup (fp
, type
);
1057 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1058 return CTF_ERR
; /* errno is set for us */
1060 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_UNION
, flag
, 0);
1062 if (size
> CTF_MAX_SIZE
)
1064 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1065 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1066 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1069 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1075 ctf_add_union (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1077 return (ctf_add_union_sized (fp
, flag
, name
, 0));
1081 ctf_add_enum (ctf_file_t
*fp
, uint32_t flag
, const char *name
)
1083 ctf_hash_t
*hp
= fp
->ctf_enums
;
1087 /* Promote forwards to enums. */
1090 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1092 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1095 if (type
!= 0 && ctf_type_kind (fp
, type
) == CTF_K_FORWARD
)
1096 dtd
= ctf_dtd_lookup (fp
, type
);
1097 else if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1098 return CTF_ERR
; /* errno is set for us. */
1100 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_ENUM
, flag
, 0);
1101 dtd
->dtd_data
.ctt_size
= fp
->ctf_dmodel
->ctd_int
;
1107 ctf_add_enum_encoded (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1108 const ctf_encoding_t
*ep
)
1110 ctf_hash_t
*hp
= fp
->ctf_enums
;
1113 /* First, create the enum if need be, using most of the same machinery as
1114 ctf_add_enum(), to ensure that we do not allow things past that are not
1115 enums or forwards to them. (This includes other slices: you cannot slice a
1116 slice, which would be a useless thing to do anyway.) */
1120 type
= ctf_hash_lookup_type (hp
, fp
, name
);
1122 type
= ctf_dtd_lookup_type_by_name (fp
, CTF_K_ENUM
, name
);
1127 if ((ctf_type_kind (fp
, type
) != CTF_K_FORWARD
) &&
1128 (ctf_type_kind_unsliced (fp
, type
) != CTF_K_ENUM
))
1129 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1131 else if ((type
= ctf_add_enum (fp
, flag
, name
)) == CTF_ERR
)
1132 return CTF_ERR
; /* errno is set for us. */
1134 /* Now attach a suitable slice to it. */
1136 return ctf_add_slice (fp
, flag
, type
, ep
);
1140 ctf_add_forward (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1150 hp
= fp
->ctf_structs
;
1153 hp
= fp
->ctf_unions
;
1159 return (ctf_set_errno (fp
, ECTF_NOTSUE
));
1162 /* If the type is already defined or exists as a forward tag, just
1163 return the ctf_id_t of the existing definition. */
1167 if (((type
= ctf_hash_lookup_type (hp
, fp
, name
)) != 0)
1168 || (type
= ctf_dtd_lookup_type_by_name (fp
, kind
, name
)) != 0)
1172 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1173 return CTF_ERR
; /* errno is set for us. */
1175 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_FORWARD
, flag
, 0);
1176 dtd
->dtd_data
.ctt_type
= kind
;
1182 ctf_add_typedef (ctf_file_t
*fp
, uint32_t flag
, const char *name
,
1187 ctf_file_t
*tmp
= fp
;
1189 if (ref
== CTF_ERR
|| ref
> CTF_MAX_TYPE
)
1190 return (ctf_set_errno (fp
, EINVAL
));
1192 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1193 return CTF_ERR
; /* errno is set for us. */
1195 if ((type
= ctf_add_generic (fp
, flag
, name
, &dtd
)) == CTF_ERR
)
1196 return CTF_ERR
; /* errno is set for us. */
1198 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (CTF_K_TYPEDEF
, flag
, 0);
1199 dtd
->dtd_data
.ctt_type
= (uint32_t) ref
;
1205 ctf_add_volatile (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1207 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_VOLATILE
));
1211 ctf_add_const (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1213 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_CONST
));
1217 ctf_add_restrict (ctf_file_t
*fp
, uint32_t flag
, ctf_id_t ref
)
1219 return (ctf_add_reftype (fp
, flag
, ref
, CTF_K_RESTRICT
));
1223 ctf_add_enumerator (ctf_file_t
*fp
, ctf_id_t enid
, const char *name
,
1226 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, enid
);
1229 uint32_t kind
, vlen
, root
;
1233 return (ctf_set_errno (fp
, EINVAL
));
1235 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1236 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1239 return (ctf_set_errno (fp
, ECTF_BADID
));
1241 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1242 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1243 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1245 if (kind
!= CTF_K_ENUM
)
1246 return (ctf_set_errno (fp
, ECTF_NOTENUM
));
1248 if (vlen
== CTF_MAX_VLEN
)
1249 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1251 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1252 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1254 if (strcmp (dmd
->dmd_name
, name
) == 0)
1255 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1258 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1259 return (ctf_set_errno (fp
, EAGAIN
));
1261 if ((s
= ctf_strdup (name
)) == NULL
)
1264 return (ctf_set_errno (fp
, EAGAIN
));
1268 dmd
->dmd_type
= CTF_ERR
;
1269 dmd
->dmd_offset
= 0;
1270 dmd
->dmd_value
= value
;
1272 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1273 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1275 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
1276 fp
->ctf_flags
|= LCTF_DIRTY
;
1282 ctf_add_member_offset (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1283 ctf_id_t type
, unsigned long bit_offset
)
1285 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, souid
);
1288 ssize_t msize
, malign
, ssize
;
1289 uint32_t kind
, vlen
, root
;
1292 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1293 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1296 return (ctf_set_errno (fp
, ECTF_BADID
));
1298 kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1299 root
= LCTF_INFO_ISROOT (fp
, dtd
->dtd_data
.ctt_info
);
1300 vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
1302 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1303 return (ctf_set_errno (fp
, ECTF_NOTSOU
));
1305 if (vlen
== CTF_MAX_VLEN
)
1306 return (ctf_set_errno (fp
, ECTF_DTFULL
));
1310 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1311 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1313 if (dmd
->dmd_name
!= NULL
&& strcmp (dmd
->dmd_name
, name
) == 0)
1314 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1318 if ((msize
= ctf_type_size (fp
, type
)) < 0 ||
1319 (malign
= ctf_type_align (fp
, type
)) < 0)
1320 return -1; /* errno is set for us. */
1322 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1323 return (ctf_set_errno (fp
, EAGAIN
));
1325 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1328 return (ctf_set_errno (fp
, EAGAIN
));
1332 dmd
->dmd_type
= type
;
1333 dmd
->dmd_value
= -1;
1335 if (kind
== CTF_K_STRUCT
&& vlen
!= 0)
1337 if (bit_offset
== (unsigned long) - 1)
1339 /* Natural alignment. */
1341 ctf_dmdef_t
*lmd
= ctf_list_prev (&dtd
->dtd_u
.dtu_members
);
1342 ctf_id_t ltype
= ctf_type_resolve (fp
, lmd
->dmd_type
);
1343 size_t off
= lmd
->dmd_offset
;
1345 ctf_encoding_t linfo
;
1348 if (ctf_type_encoding (fp
, ltype
, &linfo
) == 0)
1349 off
+= linfo
.cte_bits
;
1350 else if ((lsize
= ctf_type_size (fp
, ltype
)) > 0)
1351 off
+= lsize
* CHAR_BIT
;
1353 /* Round up the offset of the end of the last member to
1354 the next byte boundary, convert 'off' to bytes, and
1355 then round it up again to the next multiple of the
1356 alignment required by the new member. Finally,
1357 convert back to bits and store the result in
1358 dmd_offset. Technically we could do more efficient
1359 packing if the new member is a bit-field, but we're
1360 the "compiler" and ANSI says we can do as we choose. */
1362 off
= roundup (off
, CHAR_BIT
) / CHAR_BIT
;
1363 off
= roundup (off
, MAX (malign
, 1));
1364 dmd
->dmd_offset
= off
* CHAR_BIT
;
1365 ssize
= off
+ msize
;
1369 /* Specified offset in bits. */
1371 dmd
->dmd_offset
= bit_offset
;
1372 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1373 ssize
= MAX (ssize
, ((signed) bit_offset
/ CHAR_BIT
) + msize
);
1378 dmd
->dmd_offset
= 0;
1379 ssize
= ctf_get_ctt_size (fp
, &dtd
->dtd_data
, NULL
, NULL
);
1380 ssize
= MAX (ssize
, msize
);
1383 if ((size_t) ssize
> CTF_MAX_SIZE
)
1385 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1386 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (ssize
);
1387 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (ssize
);
1390 dtd
->dtd_data
.ctt_size
= (uint32_t) ssize
;
1392 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, root
, vlen
+ 1);
1393 ctf_list_append (&dtd
->dtd_u
.dtu_members
, dmd
);
1396 fp
->ctf_dtvstrlen
+= strlen (s
) + 1;
1398 fp
->ctf_flags
|= LCTF_DIRTY
;
1403 ctf_add_member_encoded (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1404 ctf_id_t type
, unsigned long bit_offset
,
1405 const ctf_encoding_t encoding
)
1407 ctf_dtdef_t
*dtd
= ctf_dtd_lookup (fp
, type
);
1408 int kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
1411 if ((kind
!= CTF_K_INTEGER
) && (kind
!= CTF_K_FLOAT
) && (kind
!= CTF_K_ENUM
))
1412 return (ctf_set_errno (fp
, ECTF_NOTINTFP
));
1414 if ((type
= ctf_add_slice (fp
, CTF_ADD_NONROOT
, otype
, &encoding
)) == CTF_ERR
)
1415 return -1; /* errno is set for us. */
1417 return ctf_add_member_offset (fp
, souid
, name
, type
, bit_offset
);
1421 ctf_add_member (ctf_file_t
*fp
, ctf_id_t souid
, const char *name
,
1424 return ctf_add_member_offset (fp
, souid
, name
, type
, (unsigned long) - 1);
1428 ctf_add_variable (ctf_file_t
*fp
, const char *name
, ctf_id_t ref
)
1431 ctf_file_t
*tmp
= fp
;
1433 if (!(fp
->ctf_flags
& LCTF_RDWR
))
1434 return (ctf_set_errno (fp
, ECTF_RDONLY
));
1436 if (ctf_dvd_lookup (fp
, name
) != NULL
)
1437 return (ctf_set_errno (fp
, ECTF_DUPLICATE
));
1439 if (ctf_lookup_by_id (&tmp
, ref
) == NULL
)
1440 return -1; /* errno is set for us. */
1442 if ((dvd
= ctf_alloc (sizeof (ctf_dvdef_t
))) == NULL
)
1443 return (ctf_set_errno (fp
, EAGAIN
));
1445 if (name
!= NULL
&& (dvd
->dvd_name
= ctf_strdup (name
)) == NULL
)
1448 return (ctf_set_errno (fp
, EAGAIN
));
1450 dvd
->dvd_type
= ref
;
1451 dvd
->dvd_snapshots
= fp
->ctf_snapshots
;
1453 if (ctf_dvd_insert (fp
, dvd
) < 0)
1456 return -1; /* errno is set for us. */
1459 fp
->ctf_dtvstrlen
+= strlen (name
) + 1;
1460 fp
->ctf_flags
|= LCTF_DIRTY
;
1465 enumcmp (const char *name
, int value
, void *arg
)
1467 ctf_bundle_t
*ctb
= arg
;
1470 if (ctf_enum_value (ctb
->ctb_file
, ctb
->ctb_type
, name
, &bvalue
) < 0)
1472 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1475 if (value
!= bvalue
)
1477 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1485 enumadd (const char *name
, int value
, void *arg
)
1487 ctf_bundle_t
*ctb
= arg
;
1489 return (ctf_add_enumerator (ctb
->ctb_file
, ctb
->ctb_type
,
1494 membcmp (const char *name
, ctf_id_t type _libctf_unused_
, unsigned long offset
,
1497 ctf_bundle_t
*ctb
= arg
;
1500 if (ctf_member_info (ctb
->ctb_file
, ctb
->ctb_type
, name
, &ctm
) < 0)
1502 ctf_dprintf ("Conflict due to member %s iteration error.\n", name
);
1505 if (ctm
.ctm_offset
!= offset
)
1507 ctf_dprintf ("Conflict due to member %s offset change: "
1508 "%lx versus %lx\n", name
, ctm
.ctm_offset
, offset
);
1515 membadd (const char *name
, ctf_id_t type
, unsigned long offset
, void *arg
)
1517 ctf_bundle_t
*ctb
= arg
;
1521 if ((dmd
= ctf_alloc (sizeof (ctf_dmdef_t
))) == NULL
)
1522 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1524 if (name
!= NULL
&& (s
= ctf_strdup (name
)) == NULL
)
1527 return (ctf_set_errno (ctb
->ctb_file
, EAGAIN
));
1530 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1531 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1533 dmd
->dmd_type
= type
;
1534 dmd
->dmd_offset
= offset
;
1535 dmd
->dmd_value
= -1;
1537 ctf_list_append (&ctb
->ctb_dtd
->dtd_u
.dtu_members
, dmd
);
1540 ctb
->ctb_file
->ctf_dtvstrlen
+= strlen (s
) + 1;
1542 ctb
->ctb_file
->ctf_flags
|= LCTF_DIRTY
;
1546 /* The ctf_add_type routine is used to copy a type from a source CTF container
1547 to a dynamic destination container. This routine operates recursively by
1548 following the source type's links and embedded member types. If the
1549 destination container already contains a named type which has the same
1550 attributes, then we succeed and return this type but no changes occur. */
1552 ctf_add_type (ctf_file_t
*dst_fp
, ctf_file_t
*src_fp
, ctf_id_t src_type
)
1554 ctf_id_t dst_type
= CTF_ERR
;
1555 uint32_t dst_kind
= CTF_K_UNKNOWN
;
1559 uint32_t kind
, flag
, vlen
;
1561 const ctf_type_t
*src_tp
, *dst_tp
;
1562 ctf_bundle_t src
, dst
;
1563 ctf_encoding_t src_en
, dst_en
;
1564 ctf_arinfo_t src_ar
, dst_ar
;
1571 if (!(dst_fp
->ctf_flags
& LCTF_RDWR
))
1572 return (ctf_set_errno (dst_fp
, ECTF_RDONLY
));
1574 if ((src_tp
= ctf_lookup_by_id (&src_fp
, src_type
)) == NULL
)
1575 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1577 name
= ctf_strptr (src_fp
, src_tp
->ctt_name
);
1578 kind
= LCTF_INFO_KIND (src_fp
, src_tp
->ctt_info
);
1579 flag
= LCTF_INFO_ISROOT (src_fp
, src_tp
->ctt_info
);
1580 vlen
= LCTF_INFO_VLEN (src_fp
, src_tp
->ctt_info
);
1585 hp
= dst_fp
->ctf_structs
;
1588 hp
= dst_fp
->ctf_unions
;
1591 hp
= dst_fp
->ctf_enums
;
1594 hp
= dst_fp
->ctf_names
;
1598 /* If the source type has a name and is a root type (visible at the
1599 top-level scope), lookup the name in the destination container and
1600 verify that it is of the same kind before we do anything else. */
1602 if ((flag
& CTF_ADD_ROOT
) && name
[0] != '\0'
1603 && (tmp
= ctf_hash_lookup_type (hp
, dst_fp
, name
)) != 0)
1606 dst_kind
= ctf_type_kind_unsliced (dst_fp
, dst_type
);
1609 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1610 unless dst_type is a forward declaration and src_type is a struct,
1611 union, or enum (i.e. the definition of the previous forward decl). */
1613 if (dst_type
!= CTF_ERR
&& dst_kind
!= kind
1614 && (dst_kind
!= CTF_K_FORWARD
1615 || (kind
!= CTF_K_ENUM
&& kind
!= CTF_K_STRUCT
1616 && kind
!= CTF_K_UNION
)))
1618 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1619 "old (ID %lx): %i\n", name
, kind
, dst_type
, dst_kind
);
1620 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1623 /* We take special action for an integer, float, or slice since it is
1624 described not only by its name but also its encoding. For integers,
1625 bit-fields exploit this degeneracy. */
1627 if (kind
== CTF_K_INTEGER
|| kind
== CTF_K_FLOAT
|| kind
== CTF_K_SLICE
)
1629 if (ctf_type_encoding (src_fp
, src_type
, &src_en
) != 0)
1630 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1632 if (dst_type
!= CTF_ERR
)
1634 ctf_file_t
*fp
= dst_fp
;
1636 if ((dst_tp
= ctf_lookup_by_id (&fp
, dst_type
)) == NULL
)
1639 if (LCTF_INFO_ISROOT (fp
, dst_tp
->ctt_info
) & CTF_ADD_ROOT
)
1641 /* The type that we found in the hash is also root-visible. If
1642 the two types match then use the existing one; otherwise,
1643 declare a conflict. Note: slices are not certain to match
1644 even if there is no conflict: we must check the contained type
1647 if (ctf_type_encoding (dst_fp
, dst_type
, &dst_en
) != 0)
1648 return CTF_ERR
; /* errno set for us. */
1650 if (memcmp (&src_en
, &dst_en
, sizeof (ctf_encoding_t
)) == 0)
1652 if (kind
!= CTF_K_SLICE
)
1657 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1662 /* We found a non-root-visible type in the hash. We reset
1663 dst_type to ensure that we continue to look for a possible
1664 conflict in the pending list. */
1671 /* If the non-empty name was not found in the appropriate hash, search
1672 the list of pending dynamic definitions that are not yet committed.
1673 If a matching name and kind are found, assume this is the type that
1674 we are looking for. This is necessary to permit ctf_add_type() to
1675 operate recursively on entities such as a struct that contains a
1676 pointer member that refers to the same struct type. */
1678 if (dst_type
== CTF_ERR
&& name
[0] != '\0')
1680 for (dtd
= ctf_list_prev (&dst_fp
->ctf_dtdefs
); dtd
!= NULL
1681 && LCTF_TYPE_TO_INDEX (src_fp
, dtd
->dtd_type
) > dst_fp
->ctf_dtoldid
;
1682 dtd
= ctf_list_prev (dtd
))
1684 if (LCTF_INFO_KIND (src_fp
, dtd
->dtd_data
.ctt_info
) == kind
1685 && dtd
->dtd_name
!= NULL
&& strcmp (dtd
->dtd_name
, name
) == 0)
1687 int sroot
; /* Is the src root-visible? */
1688 int droot
; /* Is the dst root-visible? */
1689 int match
; /* Do the encodings match? */
1691 if (kind
!= CTF_K_INTEGER
&& kind
!= CTF_K_FLOAT
&& kind
!= CTF_K_SLICE
)
1692 return dtd
->dtd_type
;
1694 sroot
= (flag
& CTF_ADD_ROOT
);
1695 droot
= (LCTF_INFO_ISROOT (dst_fp
,
1697 ctt_info
) & CTF_ADD_ROOT
);
1699 match
= (memcmp (&src_en
, &dtd
->dtd_u
.dtu_enc
,
1700 sizeof (ctf_encoding_t
)) == 0);
1702 /* If the types share the same encoding then return the id of the
1703 first unless one type is root-visible and the other is not; in
1704 that case the new type must get a new id if a match is never
1705 found. Note: slices are not certain to match even if there is
1706 no conflict: we must check the contained type too. */
1708 if (match
&& sroot
== droot
)
1710 if (kind
!= CTF_K_SLICE
)
1711 return dtd
->dtd_type
;
1713 else if (!match
&& sroot
&& droot
)
1715 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1721 src
.ctb_file
= src_fp
;
1722 src
.ctb_type
= src_type
;
1725 dst
.ctb_file
= dst_fp
;
1726 dst
.ctb_type
= dst_type
;
1729 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1730 we add a new type with the same properties as src_type to dst_fp.
1731 If dst_type is not CTF_ERR, then we verify that dst_type has the
1732 same attributes as src_type. We recurse for embedded references. */
1736 /* If we found a match we will have either returned it or declared a
1738 dst_type
= ctf_add_integer (dst_fp
, flag
, name
, &src_en
);
1742 /* If we found a match we will have either returned it or declared a
1744 dst_type
= ctf_add_float (dst_fp
, flag
, name
, &src_en
);
1748 /* We have checked for conflicting encodings: now try to add the
1750 src_type
= ctf_type_reference (src_fp
, src_type
);
1751 dst_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1753 if (src_type
== CTF_ERR
)
1754 return CTF_ERR
; /* errno is set for us. */
1756 dst_type
= ctf_add_slice (dst_fp
, flag
, src_type
, &src_en
);
1760 case CTF_K_VOLATILE
:
1762 case CTF_K_RESTRICT
:
1763 src_type
= ctf_type_reference (src_fp
, src_type
);
1764 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1766 if (src_type
== CTF_ERR
)
1767 return CTF_ERR
; /* errno is set for us. */
1769 dst_type
= ctf_add_reftype (dst_fp
, flag
, src_type
, kind
);
1773 if (ctf_array_info (src_fp
, src_type
, &src_ar
) != 0)
1774 return (ctf_set_errno (dst_fp
, ctf_errno (src_fp
)));
1776 src_ar
.ctr_contents
=
1777 ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_contents
);
1778 src_ar
.ctr_index
= ctf_add_type (dst_fp
, src_fp
, src_ar
.ctr_index
);
1779 src_ar
.ctr_nelems
= src_ar
.ctr_nelems
;
1781 if (src_ar
.ctr_contents
== CTF_ERR
|| src_ar
.ctr_index
== CTF_ERR
)
1782 return CTF_ERR
; /* errno is set for us. */
1784 if (dst_type
!= CTF_ERR
)
1786 if (ctf_array_info (dst_fp
, dst_type
, &dst_ar
) != 0)
1787 return CTF_ERR
; /* errno is set for us. */
1789 if (memcmp (&src_ar
, &dst_ar
, sizeof (ctf_arinfo_t
)))
1791 ctf_dprintf ("Conflict for type %s against ID %lx: "
1792 "array info differs, old %lx/%lx/%x; "
1793 "new: %lx/%lx/%x\n", name
, dst_type
,
1794 src_ar
.ctr_contents
, src_ar
.ctr_index
,
1795 src_ar
.ctr_nelems
, dst_ar
.ctr_contents
,
1796 dst_ar
.ctr_index
, dst_ar
.ctr_nelems
);
1797 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1801 dst_type
= ctf_add_array (dst_fp
, flag
, &src_ar
);
1804 case CTF_K_FUNCTION
:
1805 ctc
.ctc_return
= ctf_add_type (dst_fp
, src_fp
, src_tp
->ctt_type
);
1809 if (ctc
.ctc_return
== CTF_ERR
)
1810 return CTF_ERR
; /* errno is set for us. */
1812 dst_type
= ctf_add_function (dst_fp
, flag
, &ctc
, NULL
);
1823 /* Technically to match a struct or union we need to check both
1824 ways (src members vs. dst, dst members vs. src) but we make
1825 this more optimal by only checking src vs. dst and comparing
1826 the total size of the structure (which we must do anyway)
1827 which covers the possibility of dst members not in src.
1828 This optimization can be defeated for unions, but is so
1829 pathological as to render it irrelevant for our purposes. */
1831 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1833 if (ctf_type_size (src_fp
, src_type
) !=
1834 ctf_type_size (dst_fp
, dst_type
))
1836 ctf_dprintf ("Conflict for type %s against ID %lx: "
1837 "union size differs, old %li, new %li\n",
1839 (long) ctf_type_size (src_fp
, src_type
),
1840 (long) ctf_type_size (dst_fp
, dst_type
));
1841 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1844 if (ctf_member_iter (src_fp
, src_type
, membcmp
, &dst
))
1846 ctf_dprintf ("Conflict for type %s against ID %lx: "
1847 "members differ, see above\n", name
, dst_type
);
1848 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1854 /* Unlike the other cases, copying structs and unions is done
1855 manually so as to avoid repeated lookups in ctf_add_member
1856 and to ensure the exact same member offsets as in src_type. */
1858 dst_type
= ctf_add_generic (dst_fp
, flag
, name
, &dtd
);
1859 if (dst_type
== CTF_ERR
)
1860 return CTF_ERR
; /* errno is set for us. */
1862 dst
.ctb_type
= dst_type
;
1865 if (ctf_member_iter (src_fp
, src_type
, membadd
, &dst
) != 0)
1866 errs
++; /* Increment errs and fail at bottom of case. */
1868 if ((ssize
= ctf_type_size (src_fp
, src_type
)) < 0)
1869 return CTF_ERR
; /* errno is set for us. */
1871 size
= (size_t) ssize
;
1872 if (size
> CTF_MAX_SIZE
)
1874 dtd
->dtd_data
.ctt_size
= CTF_LSIZE_SENT
;
1875 dtd
->dtd_data
.ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI (size
);
1876 dtd
->dtd_data
.ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO (size
);
1879 dtd
->dtd_data
.ctt_size
= (uint32_t) size
;
1881 dtd
->dtd_data
.ctt_info
= CTF_TYPE_INFO (kind
, flag
, vlen
);
1883 /* Make a final pass through the members changing each dmd_type (a
1884 src_fp type) to an equivalent type in dst_fp. We pass through all
1885 members, leaving any that fail set to CTF_ERR. */
1886 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1887 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1889 if ((dmd
->dmd_type
= ctf_add_type (dst_fp
, src_fp
,
1890 dmd
->dmd_type
)) == CTF_ERR
)
1895 return CTF_ERR
; /* errno is set for us. */
1900 if (dst_type
!= CTF_ERR
&& dst_kind
!= CTF_K_FORWARD
)
1902 if (ctf_enum_iter (src_fp
, src_type
, enumcmp
, &dst
)
1903 || ctf_enum_iter (dst_fp
, dst_type
, enumcmp
, &src
))
1905 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1906 "members differ, see above\n", name
, dst_type
);
1907 return (ctf_set_errno (dst_fp
, ECTF_CONFLICT
));
1912 dst_type
= ctf_add_enum (dst_fp
, flag
, name
);
1913 if ((dst
.ctb_type
= dst_type
) == CTF_ERR
1914 || ctf_enum_iter (src_fp
, src_type
, enumadd
, &dst
))
1915 return CTF_ERR
; /* errno is set for us */
1920 if (dst_type
== CTF_ERR
)
1922 dst_type
= ctf_add_forward (dst_fp
, flag
,
1923 name
, CTF_K_STRUCT
); /* Assume STRUCT. */
1928 src_type
= ctf_type_reference (src_fp
, src_type
);
1929 src_type
= ctf_add_type (dst_fp
, src_fp
, src_type
);
1931 if (src_type
== CTF_ERR
)
1932 return CTF_ERR
; /* errno is set for us. */
1934 /* If dst_type is not CTF_ERR at this point, we should check if
1935 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1936 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1937 that vary based on things like if 32-bit then pid_t is int otherwise
1938 long. We therefore omit this check and assume that if the identically
1939 named typedef already exists in dst_fp, it is correct or
1942 if (dst_type
== CTF_ERR
)
1944 dst_type
= ctf_add_typedef (dst_fp
, flag
, name
, src_type
);
1949 return (ctf_set_errno (dst_fp
, ECTF_CORRUPT
));
1955 /* Write the compressed CTF data stream to the specified gzFile descriptor.
1956 This is useful for saving the results of dynamic CTF containers. */
1958 ctf_gzwrite (ctf_file_t
*fp
, gzFile fd
)
1960 const unsigned char *buf
= fp
->ctf_base
;
1961 ssize_t resid
= fp
->ctf_size
;
1966 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1967 return (ctf_set_errno (fp
, errno
));
1975 /* Compress the specified CTF data stream and write it to the specified file
1978 ctf_compress_write (ctf_file_t
*fp
, int fd
)
1983 ctf_header_t
*hp
= &h
;
1984 ssize_t header_len
= sizeof (ctf_header_t
);
1985 ssize_t compress_len
;
1986 size_t max_compress_len
= compressBound (fp
->ctf_size
- header_len
);
1991 memcpy (hp
, fp
->ctf_base
, header_len
);
1992 hp
->cth_flags
|= CTF_F_COMPRESS
;
1994 if ((buf
= ctf_alloc (max_compress_len
)) == NULL
)
1995 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
1997 compress_len
= max_compress_len
;
1998 if ((rc
= compress (buf
, (uLongf
*) &compress_len
,
1999 fp
->ctf_base
+ header_len
,
2000 fp
->ctf_size
- header_len
)) != Z_OK
)
2002 ctf_dprintf ("zlib deflate err: %s\n", zError (rc
));
2003 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
2008 while (header_len
> 0)
2010 if ((len
= write (fd
, hp
, header_len
)) < 0)
2012 err
= ctf_set_errno (fp
, errno
);
2020 while (compress_len
> 0)
2022 if ((len
= write (fd
, bp
, compress_len
)) < 0)
2024 err
= ctf_set_errno (fp
, errno
);
2027 compress_len
-= len
;
2036 /* Write the uncompressed CTF data stream to the specified file descriptor.
2037 This is useful for saving the results of dynamic CTF containers. */
2039 ctf_write (ctf_file_t
*fp
, int fd
)
2041 const unsigned char *buf
= fp
->ctf_base
;
2042 ssize_t resid
= fp
->ctf_size
;
2047 if ((len
= write (fd
, buf
, resid
)) < 0)
2048 return (ctf_set_errno (fp
, errno
));