2 Copyright (C) 2019-2021 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/>. */
29 /* Symtypetab sections. */
31 /* Symtypetab emission flags. */
33 #define CTF_SYMTYPETAB_EMIT_FUNCTION 0x1
34 #define CTF_SYMTYPETAB_EMIT_PAD 0x2
35 #define CTF_SYMTYPETAB_FORCE_INDEXED 0x4
37 /* Properties of symtypetab emission, shared by symtypetab section
38 sizing and symtypetab emission itself. */
40 typedef struct emit_symtypetab_state
42 /* True if linker-reported symbols are being filtered out. symfp is set if
43 this is true: otherwise, indexing is forced and the symflags indicate as
47 /* True if symbols are being sorted. */
50 /* Flags for symtypetab emission. */
53 /* The dict to which the linker has reported symbols. */
56 /* The maximum number of objects seen. */
59 /* The maximum number of func info entris seen. */
61 } emit_symtypetab_state_t
;
63 /* Determine if a symbol is "skippable" and should never appear in the
64 symtypetab sections. */
67 ctf_symtab_skippable (ctf_link_sym_t
*sym
)
69 /* Never skip symbols whose name is not yet known. */
70 if (sym
->st_nameidx_set
)
73 return (sym
->st_name
== NULL
|| sym
->st_name
[0] == 0
74 || sym
->st_shndx
== SHN_UNDEF
75 || strcmp (sym
->st_name
, "_START_") == 0
76 || strcmp (sym
->st_name
, "_END_") == 0
77 || (sym
->st_type
== STT_OBJECT
&& sym
->st_shndx
== SHN_EXTABS
78 && sym
->st_value
== 0));
81 /* Get the number of symbols in a symbol hash, the count of symbols, the maximum
82 seen, the eventual size, without any padding elements, of the func/data and
83 (if generated) index sections, and the size of accumulated padding elements.
84 The linker-reported set of symbols is found in SYMFP: it may be NULL if
85 symbol filtering is not desired, in which case CTF_SYMTYPETAB_FORCE_INDEXED
86 will always be set in the flags.
88 Also figure out if any symbols need to be moved to the variable section, and
89 add them (if not already present). */
91 _libctf_nonnull_ ((1,3,4,5,6,7,8))
93 symtypetab_density (ctf_dict_t
*fp
, ctf_dict_t
*symfp
, ctf_dynhash_t
*symhash
,
94 size_t *count
, size_t *max
, size_t *unpadsize
,
95 size_t *padsize
, size_t *idxsize
, int flags
)
100 ctf_dynhash_t
*linker_known
= NULL
;
110 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
112 /* Make a dynhash citing only symbols reported by the linker of the
113 appropriate type, then traverse all potential-symbols we know the types
114 of, removing them from linker_known as we go. Once this is done, the
115 only symbols remaining in linker_known are symbols we don't know the
116 types of: we must emit pads for those symbols that are below the
117 maximum symbol we will emit (any beyond that are simply skipped).
119 If there are none, this symtypetab will be empty: just report that. */
121 if (!symfp
->ctf_dynsyms
)
124 if ((linker_known
= ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
125 NULL
, NULL
)) == NULL
)
126 return (ctf_set_errno (fp
, ENOMEM
));
128 while ((err
= ctf_dynhash_cnext (symfp
->ctf_dynsyms
, &i
,
129 &name
, &ctf_sym
)) == 0)
131 ctf_link_sym_t
*sym
= (ctf_link_sym_t
*) ctf_sym
;
133 if (((flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
134 && sym
->st_type
!= STT_FUNC
)
135 || (!(flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
136 && sym
->st_type
!= STT_OBJECT
))
139 if (ctf_symtab_skippable (sym
))
142 /* This should only be true briefly before all the names are
143 finalized, long before we get this far. */
144 if (!ctf_assert (fp
, !sym
->st_nameidx_set
))
145 return -1; /* errno is set for us. */
147 if (ctf_dynhash_cinsert (linker_known
, name
, ctf_sym
) < 0)
149 ctf_dynhash_destroy (linker_known
);
150 return (ctf_set_errno (fp
, ENOMEM
));
153 if (err
!= ECTF_NEXT_END
)
155 ctf_err_warn (fp
, 0, err
, _("iterating over linker-known symbols during "
157 ctf_dynhash_destroy (linker_known
);
158 return (ctf_set_errno (fp
, err
));
162 while ((err
= ctf_dynhash_cnext (symhash
, &i
, &name
, NULL
)) == 0)
166 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
168 /* Linker did not report symbol in symtab. Remove it from the
169 set of known data symbols and continue. */
170 if ((sym
= ctf_dynhash_lookup (symfp
->ctf_dynsyms
, name
)) == NULL
)
172 ctf_dynhash_remove (symhash
, name
);
176 /* We don't remove skippable symbols from the symhash because we don't
177 want them to be migrated into variables. */
178 if (ctf_symtab_skippable (sym
))
181 if ((flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
182 && sym
->st_type
!= STT_FUNC
)
184 ctf_err_warn (fp
, 1, 0, _("symbol %s (%x) added to CTF as a "
185 "function but is of type %x. "
186 "The symbol type lookup tables "
187 "are probably corrupted"),
188 sym
->st_name
, sym
->st_symidx
, sym
->st_type
);
189 ctf_dynhash_remove (symhash
, name
);
192 else if (!(flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
193 && sym
->st_type
!= STT_OBJECT
)
195 ctf_err_warn (fp
, 1, 0, _("symbol %s (%x) added to CTF as a "
196 "data object but is of type %x. "
197 "The symbol type lookup tables "
198 "are probably corrupted"),
199 sym
->st_name
, sym
->st_symidx
, sym
->st_type
);
200 ctf_dynhash_remove (symhash
, name
);
204 ctf_dynhash_remove (linker_known
, name
);
206 *unpadsize
+= sizeof (uint32_t);
209 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
211 if (*max
< sym
->st_symidx
)
212 *max
= sym
->st_symidx
;
217 if (err
!= ECTF_NEXT_END
)
219 ctf_err_warn (fp
, 0, err
, _("iterating over CTF symtypetab during "
221 ctf_dynhash_destroy (linker_known
);
222 return (ctf_set_errno (fp
, err
));
225 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
227 while ((err
= ctf_dynhash_cnext (linker_known
, &i
, NULL
, &ctf_sym
)) == 0)
229 ctf_link_sym_t
*sym
= (ctf_link_sym_t
*) ctf_sym
;
231 if (sym
->st_symidx
> *max
)
234 if (err
!= ECTF_NEXT_END
)
236 ctf_err_warn (fp
, 0, err
, _("iterating over linker-known symbols "
237 "during CTF serialization"));
238 ctf_dynhash_destroy (linker_known
);
239 return (ctf_set_errno (fp
, err
));
243 *idxsize
= *count
* sizeof (uint32_t);
244 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
245 *padsize
= (ctf_dynhash_elements (linker_known
) - beyond_max
) * sizeof (uint32_t);
247 ctf_dynhash_destroy (linker_known
);
251 /* Emit an objt or func symtypetab into DP in a particular order defined by an
252 array of ctf_link_sym_t or symbol names passed in. The index has NIDX
253 elements in it: unindexed output would terminate at symbol OUTMAX and is in
254 any case no larger than SIZE bytes. Some index elements are expected to be
255 skipped: see symtypetab_density. The linker-reported set of symbols (if any)
256 is found in SYMFP. */
258 emit_symtypetab (ctf_dict_t
*fp
, ctf_dict_t
*symfp
, uint32_t *dp
,
259 ctf_link_sym_t
**idx
, const char **nameidx
, uint32_t nidx
,
260 uint32_t outmax
, int size
, int flags
)
264 ctf_dynhash_t
*symhash
;
266 ctf_dprintf ("Emitting table of size %i, outmax %u, %u symtypetab entries, "
267 "flags %i\n", size
, outmax
, nidx
, flags
);
269 /* Empty table? Nothing to do. */
273 if (flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
274 symhash
= fp
->ctf_funchash
;
276 symhash
= fp
->ctf_objthash
;
278 for (i
= 0; i
< nidx
; i
++)
280 const char *sym_name
;
283 /* If we have a linker-reported set of symbols, we may be given that set
284 to work from, or a set of symbol names. In both cases we want to look
285 at the corresponding linker-reported symbol (if any). */
286 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
288 ctf_link_sym_t
*this_link_sym
;
291 this_link_sym
= idx
[i
];
293 this_link_sym
= ctf_dynhash_lookup (symfp
->ctf_dynsyms
, nameidx
[i
]);
295 /* Unreported symbol number. No pad, no nothing. */
299 /* Symbol of the wrong type, or skippable? This symbol is not in this
301 if (((flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
302 && this_link_sym
->st_type
!= STT_FUNC
)
303 || (!(flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
304 && this_link_sym
->st_type
!= STT_OBJECT
))
307 if (ctf_symtab_skippable (this_link_sym
))
310 sym_name
= this_link_sym
->st_name
;
312 /* Linker reports symbol of a different type to the symbol we actually
313 added? Skip the symbol. No pad, since the symbol doesn't actually
314 belong in this table at all. (Warned about in
315 symtypetab_density.) */
316 if ((this_link_sym
->st_type
== STT_FUNC
)
317 && (ctf_dynhash_lookup (fp
->ctf_objthash
, sym_name
)))
320 if ((this_link_sym
->st_type
== STT_OBJECT
)
321 && (ctf_dynhash_lookup (fp
->ctf_funchash
, sym_name
)))
325 sym_name
= nameidx
[i
];
327 /* Symbol in index but no type set? Silently skip and (optionally)
328 pad. (In force-indexed mode, this is also where we track symbols of
329 the wrong type for this round of insertion.) */
330 if ((type
= ctf_dynhash_lookup (symhash
, sym_name
)) == NULL
)
332 if (flags
& CTF_SYMTYPETAB_EMIT_PAD
)
337 if (!ctf_assert (fp
, (((char *) dpp
) - (char *) dp
) < size
))
338 return -1; /* errno is set for us. */
340 *dpp
++ = (ctf_id_t
) (uintptr_t) type
;
342 /* When emitting unindexed output, all later symbols are pads: stop
344 if ((flags
& CTF_SYMTYPETAB_EMIT_PAD
) && idx
[i
]->st_symidx
== outmax
)
351 /* Emit an objt or func symtypetab index into DP in a paticular order defined by
352 an array of symbol names passed in. Stop at NIDX. The linker-reported set
353 of symbols (if any) is found in SYMFP. */
355 emit_symtypetab_index (ctf_dict_t
*fp
, ctf_dict_t
*symfp
, uint32_t *dp
,
356 const char **idx
, uint32_t nidx
, int size
, int flags
)
360 ctf_dynhash_t
*symhash
;
362 ctf_dprintf ("Emitting index of size %i, %u entries reported by linker, "
363 "flags %i\n", size
, nidx
, flags
);
365 /* Empty table? Nothing to do. */
369 if (flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
370 symhash
= fp
->ctf_funchash
;
372 symhash
= fp
->ctf_objthash
;
374 /* Indexes should always be unpadded. */
375 if (!ctf_assert (fp
, !(flags
& CTF_SYMTYPETAB_EMIT_PAD
)))
376 return -1; /* errno is set for us. */
378 for (i
= 0; i
< nidx
; i
++)
380 const char *sym_name
;
383 if (!(flags
& CTF_SYMTYPETAB_FORCE_INDEXED
))
385 ctf_link_sym_t
*this_link_sym
;
387 this_link_sym
= ctf_dynhash_lookup (symfp
->ctf_dynsyms
, idx
[i
]);
389 /* This is an index: unreported symbols should never appear in it. */
390 if (!ctf_assert (fp
, this_link_sym
!= NULL
))
391 return -1; /* errno is set for us. */
393 /* Symbol of the wrong type, or skippable? This symbol is not in this
395 if (((flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
396 && this_link_sym
->st_type
!= STT_FUNC
)
397 || (!(flags
& CTF_SYMTYPETAB_EMIT_FUNCTION
)
398 && this_link_sym
->st_type
!= STT_OBJECT
))
401 if (ctf_symtab_skippable (this_link_sym
))
404 sym_name
= this_link_sym
->st_name
;
406 /* Linker reports symbol of a different type to the symbol we actually
407 added? Skip the symbol. */
408 if ((this_link_sym
->st_type
== STT_FUNC
)
409 && (ctf_dynhash_lookup (fp
->ctf_objthash
, sym_name
)))
412 if ((this_link_sym
->st_type
== STT_OBJECT
)
413 && (ctf_dynhash_lookup (fp
->ctf_funchash
, sym_name
)))
419 /* Symbol in index and reported by linker, but no type set? Silently skip
420 and (optionally) pad. (In force-indexed mode, this is also where we
421 track symbols of the wrong type for this round of insertion.) */
422 if ((type
= ctf_dynhash_lookup (symhash
, sym_name
)) == NULL
)
425 ctf_str_add_ref (fp
, sym_name
, dpp
++);
427 if (!ctf_assert (fp
, (((char *) dpp
) - (char *) dp
) <= size
))
428 return -1; /* errno is set for us. */
434 /* Delete data symbols that have been assigned names from the variable section.
435 Must be called from within ctf_serialize, because that is the only place
436 you can safely delete variables without messing up ctf_rollback. */
439 symtypetab_delete_nonstatic_vars (ctf_dict_t
*fp
, ctf_dict_t
*symfp
)
441 ctf_dvdef_t
*dvd
, *nvd
;
444 for (dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
; dvd
= nvd
)
446 nvd
= ctf_list_next (dvd
);
448 if (((type
= (ctf_id_t
) (uintptr_t)
449 ctf_dynhash_lookup (fp
->ctf_objthash
, dvd
->dvd_name
)) > 0)
450 && ctf_dynhash_lookup (symfp
->ctf_dynsyms
, dvd
->dvd_name
) != NULL
451 && type
== dvd
->dvd_type
)
452 ctf_dvd_delete (fp
, dvd
);
458 /* Figure out the sizes of the symtypetab sections, their indexed state,
461 ctf_symtypetab_sect_sizes (ctf_dict_t
*fp
, emit_symtypetab_state_t
*s
,
462 ctf_header_t
*hdr
, size_t *objt_size
,
463 size_t *func_size
, size_t *objtidx_size
,
464 size_t *funcidx_size
)
466 size_t nfuncs
, nobjts
;
467 size_t objt_unpadsize
, func_unpadsize
, objt_padsize
, func_padsize
;
469 /* If doing a writeout as part of linking, and the link flags request it,
470 filter out reported symbols from the variable section, and filter out all
471 other symbols from the symtypetab sections. (If we are not linking, the
472 symbols are sorted; if we are linking, don't bother sorting if we are not
473 filtering out reported symbols: this is almost certaily an ld -r and only
474 the linker is likely to consume these symtypetabs again. The linker
475 doesn't care what order the symtypetab entries is in, since it only
476 iterates over symbols and does not use the ctf_lookup_by_symbol* API.) */
479 if (fp
->ctf_flags
& LCTF_LINKING
)
481 s
->filter_syms
= !(fp
->ctf_link_flags
& CTF_LINK_NO_FILTER_REPORTED_SYMS
);
486 /* Find the dict to which the linker has reported symbols, if any. */
490 if (!fp
->ctf_dynsyms
&& fp
->ctf_parent
&& fp
->ctf_parent
->ctf_dynsyms
)
491 s
->symfp
= fp
->ctf_parent
;
496 /* If not filtering, keep all potential symbols in an unsorted, indexed
499 s
->symflags
= CTF_SYMTYPETAB_FORCE_INDEXED
;
501 hdr
->cth_flags
|= CTF_F_IDXSORTED
;
503 if (!ctf_assert (fp
, (s
->filter_syms
&& s
->symfp
)
504 || (!s
->filter_syms
&& !s
->symfp
505 && ((s
->symflags
& CTF_SYMTYPETAB_FORCE_INDEXED
) != 0))))
508 /* Work out the sizes of the object and function sections, and work out the
509 number of pad (unassigned) symbols in each, and the overall size of the
512 if (symtypetab_density (fp
, s
->symfp
, fp
->ctf_objthash
, &nobjts
, &s
->maxobjt
,
513 &objt_unpadsize
, &objt_padsize
, objtidx_size
,
515 return -1; /* errno is set for us. */
517 ctf_dprintf ("Object symtypetab: %i objects, max %i, unpadded size %i, "
518 "%i bytes of pads, index size %i\n", (int) nobjts
,
519 (int) s
->maxobjt
, (int) objt_unpadsize
, (int) objt_padsize
,
520 (int) *objtidx_size
);
522 if (symtypetab_density (fp
, s
->symfp
, fp
->ctf_funchash
, &nfuncs
, &s
->maxfunc
,
523 &func_unpadsize
, &func_padsize
, funcidx_size
,
524 s
->symflags
| CTF_SYMTYPETAB_EMIT_FUNCTION
) < 0)
525 return -1; /* errno is set for us. */
527 ctf_dprintf ("Function symtypetab: %i functions, max %i, unpadded size %i, "
528 "%i bytes of pads, index size %i\n", (int) nfuncs
,
529 (int) s
->maxfunc
, (int) func_unpadsize
, (int) func_padsize
,
530 (int) *funcidx_size
);
532 /* It is worth indexing each section if it would save space to do so, due to
533 reducing the number of pads sufficiently. A pad is the same size as a
534 single index entry: but index sections compress relatively poorly compared
535 to constant pads, so it takes a lot of contiguous padding to equal one
536 index section entry. It would be nice to be able to *verify* whether we
537 would save space after compression rather than guessing, but this seems
538 difficult, since it would require complete reserialization. Regardless, if
539 the linker has not reported any symbols (e.g. if this is not a final link
540 but just an ld -r), we must emit things in indexed fashion just as the
543 *objt_size
= objt_unpadsize
;
544 if (!(s
->symflags
& CTF_SYMTYPETAB_FORCE_INDEXED
)
545 && ((objt_padsize
+ objt_unpadsize
) * CTF_INDEX_PAD_THRESHOLD
548 *objt_size
+= objt_padsize
;
552 *func_size
= func_unpadsize
;
553 if (!(s
->symflags
& CTF_SYMTYPETAB_FORCE_INDEXED
)
554 && ((func_padsize
+ func_unpadsize
) * CTF_INDEX_PAD_THRESHOLD
557 *func_size
+= func_padsize
;
561 /* If we are filtering symbols out, those symbols that the linker has not
562 reported have now been removed from the ctf_objthash and ctf_funchash.
563 Delete entries from the variable section that duplicate newly-added data
564 symbols. There's no need to migrate new ones in, because the compiler
565 always emits both a variable and a data symbol simultaneously, and
566 filtering only happens at final link time. */
568 if (s
->filter_syms
&& s
->symfp
->ctf_dynsyms
&&
569 symtypetab_delete_nonstatic_vars (fp
, s
->symfp
) < 0)
576 ctf_emit_symtypetab_sects (ctf_dict_t
*fp
, emit_symtypetab_state_t
*s
,
577 unsigned char **tptr
, size_t objt_size
,
578 size_t func_size
, size_t objtidx_size
,
581 unsigned char *t
= *tptr
;
582 size_t nsymtypes
= 0;
583 const char **sym_name_order
= NULL
;
586 /* Sort the linker's symbols into name order if need be. */
588 if ((objtidx_size
!= 0) || (funcidx_size
!= 0))
590 ctf_next_t
*i
= NULL
;
596 if (s
->symfp
->ctf_dynsyms
)
597 nsymtypes
= ctf_dynhash_elements (s
->symfp
->ctf_dynsyms
);
602 nsymtypes
= ctf_dynhash_elements (fp
->ctf_objthash
)
603 + ctf_dynhash_elements (fp
->ctf_funchash
);
605 if ((sym_name_order
= calloc (nsymtypes
, sizeof (const char *))) == NULL
)
608 walk
= sym_name_order
;
612 if (s
->symfp
->ctf_dynsyms
)
614 while ((err
= ctf_dynhash_next_sorted (s
->symfp
->ctf_dynsyms
, &i
,
616 ctf_dynhash_sort_by_name
,
618 *walk
++ = (const char *) symname
;
619 if (err
!= ECTF_NEXT_END
)
625 ctf_hash_sort_f sort_fun
= NULL
;
627 /* Since we partition the set of symbols back into objt and func,
628 we can sort the two independently without harm. */
630 sort_fun
= ctf_dynhash_sort_by_name
;
632 while ((err
= ctf_dynhash_next_sorted (fp
->ctf_objthash
, &i
, &symname
,
633 NULL
, sort_fun
, NULL
)) == 0)
634 *walk
++ = (const char *) symname
;
635 if (err
!= ECTF_NEXT_END
)
638 while ((err
= ctf_dynhash_next_sorted (fp
->ctf_funchash
, &i
, &symname
,
639 NULL
, sort_fun
, NULL
)) == 0)
640 *walk
++ = (const char *) symname
;
641 if (err
!= ECTF_NEXT_END
)
646 /* Emit the object and function sections, and if necessary their indexes.
647 Emission is done in symtab order if there is no index, and in index
648 (name) order otherwise. */
650 if ((objtidx_size
== 0) && s
->symfp
&& s
->symfp
->ctf_dynsymidx
)
652 ctf_dprintf ("Emitting unindexed objt symtypetab\n");
653 if (emit_symtypetab (fp
, s
->symfp
, (uint32_t *) t
,
654 s
->symfp
->ctf_dynsymidx
, NULL
,
655 s
->symfp
->ctf_dynsymmax
+ 1, s
->maxobjt
,
656 objt_size
, s
->symflags
| CTF_SYMTYPETAB_EMIT_PAD
) < 0)
657 goto err
; /* errno is set for us. */
661 ctf_dprintf ("Emitting indexed objt symtypetab\n");
662 if (emit_symtypetab (fp
, s
->symfp
, (uint32_t *) t
, NULL
,
663 sym_name_order
, nsymtypes
, s
->maxobjt
,
664 objt_size
, s
->symflags
) < 0)
665 goto err
; /* errno is set for us. */
670 if ((funcidx_size
== 0) && s
->symfp
&& s
->symfp
->ctf_dynsymidx
)
672 ctf_dprintf ("Emitting unindexed func symtypetab\n");
673 if (emit_symtypetab (fp
, s
->symfp
, (uint32_t *) t
,
674 s
->symfp
->ctf_dynsymidx
, NULL
,
675 s
->symfp
->ctf_dynsymmax
+ 1, s
->maxfunc
,
676 func_size
, s
->symflags
| CTF_SYMTYPETAB_EMIT_FUNCTION
677 | CTF_SYMTYPETAB_EMIT_PAD
) < 0)
678 goto err
; /* errno is set for us. */
682 ctf_dprintf ("Emitting indexed func symtypetab\n");
683 if (emit_symtypetab (fp
, s
->symfp
, (uint32_t *) t
, NULL
, sym_name_order
,
684 nsymtypes
, s
->maxfunc
, func_size
,
685 s
->symflags
| CTF_SYMTYPETAB_EMIT_FUNCTION
) < 0)
686 goto err
; /* errno is set for us. */
691 if (objtidx_size
> 0)
692 if (emit_symtypetab_index (fp
, s
->symfp
, (uint32_t *) t
, sym_name_order
,
693 nsymtypes
, objtidx_size
, s
->symflags
) < 0)
698 if (funcidx_size
> 0)
699 if (emit_symtypetab_index (fp
, s
->symfp
, (uint32_t *) t
, sym_name_order
,
700 nsymtypes
, funcidx_size
,
701 s
->symflags
| CTF_SYMTYPETAB_EMIT_FUNCTION
) < 0)
705 free (sym_name_order
);
711 ctf_set_errno (fp
, EAGAIN
);
714 ctf_err_warn (fp
, 0, err
, _("error serializing symtypetabs"));
716 free (sym_name_order
);
722 static unsigned char *
723 ctf_copy_smembers (ctf_dict_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
725 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
728 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
730 ctf_member_t
*copied
;
733 ctm
.ctm_type
= (uint32_t) dmd
->dmd_type
;
734 ctm
.ctm_offset
= (uint32_t) dmd
->dmd_offset
;
736 memcpy (t
, &ctm
, sizeof (ctm
));
737 copied
= (ctf_member_t
*) t
;
739 ctf_str_add_ref (fp
, dmd
->dmd_name
, &copied
->ctm_name
);
747 static unsigned char *
748 ctf_copy_lmembers (ctf_dict_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
750 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
753 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
755 ctf_lmember_t
*copied
;
758 ctlm
.ctlm_type
= (uint32_t) dmd
->dmd_type
;
759 ctlm
.ctlm_offsethi
= CTF_OFFSET_TO_LMEMHI (dmd
->dmd_offset
);
760 ctlm
.ctlm_offsetlo
= CTF_OFFSET_TO_LMEMLO (dmd
->dmd_offset
);
762 memcpy (t
, &ctlm
, sizeof (ctlm
));
763 copied
= (ctf_lmember_t
*) t
;
765 ctf_str_add_ref (fp
, dmd
->dmd_name
, &copied
->ctlm_name
);
773 static unsigned char *
774 ctf_copy_emembers (ctf_dict_t
*fp
, ctf_dtdef_t
*dtd
, unsigned char *t
)
776 ctf_dmdef_t
*dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
779 for (; dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
783 cte
.cte_value
= dmd
->dmd_value
;
784 memcpy (t
, &cte
, sizeof (cte
));
785 copied
= (ctf_enum_t
*) t
;
786 ctf_str_add_ref (fp
, dmd
->dmd_name
, &copied
->cte_name
);
793 /* Iterate through the dynamic type definition list and compute the
794 size of the CTF type section. */
797 ctf_type_sect_size (ctf_dict_t
*fp
)
802 for (type_size
= 0, dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
803 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
805 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
806 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
808 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
809 type_size
+= sizeof (ctf_stype_t
);
811 type_size
+= sizeof (ctf_type_t
);
817 type_size
+= sizeof (uint32_t);
820 type_size
+= sizeof (ctf_array_t
);
823 type_size
+= sizeof (ctf_slice_t
);
826 type_size
+= sizeof (uint32_t) * (vlen
+ (vlen
& 1));
830 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
831 type_size
+= sizeof (ctf_member_t
) * vlen
;
833 type_size
+= sizeof (ctf_lmember_t
) * vlen
;
836 type_size
+= sizeof (ctf_enum_t
) * vlen
;
844 /* Take a final lap through the dynamic type definition list and copy the
845 appropriate type records to the output buffer, noting down the strings as
849 ctf_emit_type_sect (ctf_dict_t
*fp
, unsigned char **tptr
)
851 unsigned char *t
= *tptr
;
854 for (dtd
= ctf_list_next (&fp
->ctf_dtdefs
);
855 dtd
!= NULL
; dtd
= ctf_list_next (dtd
))
857 uint32_t kind
= LCTF_INFO_KIND (fp
, dtd
->dtd_data
.ctt_info
);
858 uint32_t vlen
= LCTF_INFO_VLEN (fp
, dtd
->dtd_data
.ctt_info
);
864 if (dtd
->dtd_data
.ctt_size
!= CTF_LSIZE_SENT
)
865 len
= sizeof (ctf_stype_t
);
867 len
= sizeof (ctf_type_t
);
869 memcpy (t
, &dtd
->dtd_data
, len
);
870 copied
= (ctf_stype_t
*) t
; /* name is at the start: constant offset. */
872 && (name
= ctf_strraw (fp
, copied
->ctt_name
)) != NULL
)
873 ctf_str_add_ref (fp
, name
, &copied
->ctt_name
);
880 memcpy (t
, dtd
->dtd_vlen
, sizeof (uint32_t));
881 t
+= sizeof (uint32_t);
885 memcpy (t
, dtd
->dtd_vlen
, sizeof (struct ctf_slice
));
886 t
+= sizeof (struct ctf_slice
);
890 memcpy (t
, dtd
->dtd_vlen
, sizeof (struct ctf_array
));
891 t
+= sizeof (struct ctf_array
);
895 memcpy (t
, dtd
->dtd_vlen
, sizeof (uint32_t) * (vlen
+ (vlen
& 1)));
896 t
+= sizeof (uint32_t) * (vlen
+ (vlen
& 1));
901 if (dtd
->dtd_data
.ctt_size
< CTF_LSTRUCT_THRESH
)
902 t
= ctf_copy_smembers (fp
, dtd
, t
);
904 t
= ctf_copy_lmembers (fp
, dtd
, t
);
908 t
= ctf_copy_emembers (fp
, dtd
, t
);
916 /* Variable section. */
918 /* Sort a newly-constructed static variable array. */
920 typedef struct ctf_sort_var_arg_cb
924 } ctf_sort_var_arg_cb_t
;
927 ctf_sort_var (const void *one_
, const void *two_
, void *arg_
)
929 const ctf_varent_t
*one
= one_
;
930 const ctf_varent_t
*two
= two_
;
931 ctf_sort_var_arg_cb_t
*arg
= arg_
;
933 return (strcmp (ctf_strraw_explicit (arg
->fp
, one
->ctv_name
, arg
->strtab
),
934 ctf_strraw_explicit (arg
->fp
, two
->ctv_name
, arg
->strtab
)));
937 /* Overall serialization. */
939 /* If the specified CTF dict is writable and has been modified, reload this dict
940 with the updated type definitions, ready for serialization. In order to make
941 this code and the rest of libctf as simple as possible, we perform updates by
942 taking the dynamic type definitions and creating an in-memory CTF dict
943 containing the definitions, and then call ctf_simple_open_internal() on it.
944 We perform one extra trick here for the benefit of callers and to keep our
945 code simple: ctf_simple_open_internal() will return a new ctf_dict_t, but we
946 want to keep the fp constant for the caller, so after
947 ctf_simple_open_internal() returns, we use memcpy to swap the interior of the
948 old and new ctf_dict_t's, and then free the old. */
950 ctf_serialize (ctf_dict_t
*fp
)
952 ctf_dict_t ofp
, *nfp
;
953 ctf_header_t hdr
, *hdrp
;
955 ctf_varent_t
*dvarents
;
956 ctf_strs_writable_t strtab
;
961 size_t buf_size
, type_size
, objt_size
, func_size
;
962 size_t funcidx_size
, objtidx_size
;
964 unsigned char *buf
= NULL
, *newbuf
;
966 emit_symtypetab_state_t symstate
;
967 memset (&symstate
, 0, sizeof (emit_symtypetab_state_t
));
969 if (!(fp
->ctf_flags
& LCTF_RDWR
))
970 return (ctf_set_errno (fp
, ECTF_RDONLY
));
972 /* Update required? */
973 if (!(fp
->ctf_flags
& LCTF_DIRTY
))
976 /* Fill in an initial CTF header. We will leave the label, object,
977 and function sections empty and only output a header, type section,
978 and string table. The type section begins at a 4-byte aligned
979 boundary past the CTF header itself (at relative offset zero). The flag
980 indicating a new-style function info section (an array of CTF_K_FUNCTION
981 type IDs in the types section) is flipped on. */
983 memset (&hdr
, 0, sizeof (hdr
));
984 hdr
.cth_magic
= CTF_MAGIC
;
985 hdr
.cth_version
= CTF_VERSION
;
987 /* This is a new-format func info section, and the symtab and strtab come out
988 of the dynsym and dynstr these days. */
989 hdr
.cth_flags
= (CTF_F_NEWFUNCINFO
| CTF_F_DYNSTR
);
991 if (ctf_symtypetab_sect_sizes (fp
, &symstate
, &hdr
, &objt_size
, &func_size
,
992 &objtidx_size
, &funcidx_size
) < 0)
993 return -1; /* errno is set for us. */
995 for (nvars
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
996 dvd
!= NULL
; dvd
= ctf_list_next (dvd
), nvars
++);
998 type_size
= ctf_type_sect_size (fp
);
1000 /* Compute the size of the CTF buffer we need, sans only the string table,
1001 then allocate a new buffer and memcpy the finished header to the start of
1002 the buffer. (We will adjust this later with strtab length info.) */
1004 hdr
.cth_lbloff
= hdr
.cth_objtoff
= 0;
1005 hdr
.cth_funcoff
= hdr
.cth_objtoff
+ objt_size
;
1006 hdr
.cth_objtidxoff
= hdr
.cth_funcoff
+ func_size
;
1007 hdr
.cth_funcidxoff
= hdr
.cth_objtidxoff
+ objtidx_size
;
1008 hdr
.cth_varoff
= hdr
.cth_funcidxoff
+ funcidx_size
;
1009 hdr
.cth_typeoff
= hdr
.cth_varoff
+ (nvars
* sizeof (ctf_varent_t
));
1010 hdr
.cth_stroff
= hdr
.cth_typeoff
+ type_size
;
1013 buf_size
= sizeof (ctf_header_t
) + hdr
.cth_stroff
+ hdr
.cth_strlen
;
1015 if ((buf
= malloc (buf_size
)) == NULL
)
1016 return (ctf_set_errno (fp
, EAGAIN
));
1018 memcpy (buf
, &hdr
, sizeof (ctf_header_t
));
1019 t
= (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_objtoff
;
1021 hdrp
= (ctf_header_t
*) buf
;
1022 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parname
!= NULL
))
1023 ctf_str_add_ref (fp
, fp
->ctf_parname
, &hdrp
->cth_parname
);
1024 if (fp
->ctf_cuname
!= NULL
)
1025 ctf_str_add_ref (fp
, fp
->ctf_cuname
, &hdrp
->cth_cuname
);
1027 if (ctf_emit_symtypetab_sects (fp
, &symstate
, &t
, objt_size
, func_size
,
1028 objtidx_size
, funcidx_size
) < 0)
1031 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_varoff
);
1033 /* Work over the variable list, translating everything into ctf_varent_t's and
1034 prepping the string table. */
1036 dvarents
= (ctf_varent_t
*) t
;
1037 for (i
= 0, dvd
= ctf_list_next (&fp
->ctf_dvdefs
); dvd
!= NULL
;
1038 dvd
= ctf_list_next (dvd
), i
++)
1040 ctf_varent_t
*var
= &dvarents
[i
];
1042 ctf_str_add_ref (fp
, dvd
->dvd_name
, &var
->ctv_name
);
1043 var
->ctv_type
= (uint32_t) dvd
->dvd_type
;
1045 assert (i
== nvars
);
1047 t
+= sizeof (ctf_varent_t
) * nvars
;
1049 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_typeoff
);
1051 ctf_emit_type_sect (fp
, &t
);
1053 assert (t
== (unsigned char *) buf
+ sizeof (ctf_header_t
) + hdr
.cth_stroff
);
1055 /* Construct the final string table and fill out all the string refs with the
1056 final offsets. Then purge the refs list, because we're about to move this
1057 strtab onto the end of the buf, invalidating all the offsets. */
1058 strtab
= ctf_str_write_strtab (fp
);
1059 ctf_str_purge_refs (fp
);
1061 if (strtab
.cts_strs
== NULL
)
1064 /* Now the string table is constructed, we can sort the buffer of
1066 ctf_sort_var_arg_cb_t sort_var_arg
= { fp
, (ctf_strs_t
*) &strtab
};
1067 ctf_qsort_r (dvarents
, nvars
, sizeof (ctf_varent_t
), ctf_sort_var
,
1070 if ((newbuf
= ctf_realloc (fp
, buf
, buf_size
+ strtab
.cts_len
)) == NULL
)
1072 free (strtab
.cts_strs
);
1076 memcpy (buf
+ buf_size
, strtab
.cts_strs
, strtab
.cts_len
);
1077 hdrp
= (ctf_header_t
*) buf
;
1078 hdrp
->cth_strlen
= strtab
.cts_len
;
1079 buf_size
+= hdrp
->cth_strlen
;
1080 free (strtab
.cts_strs
);
1082 /* Finally, we are ready to ctf_simple_open() the new dict. If this is
1083 successful, we then switch nfp and fp and free the old dict. */
1085 if ((nfp
= ctf_simple_open_internal ((char *) buf
, buf_size
, NULL
, 0,
1086 0, NULL
, 0, fp
->ctf_syn_ext_strtab
,
1090 return (ctf_set_errno (fp
, err
));
1093 (void) ctf_setmodel (nfp
, ctf_getmodel (fp
));
1095 nfp
->ctf_parent
= fp
->ctf_parent
;
1096 nfp
->ctf_parent_unreffed
= fp
->ctf_parent_unreffed
;
1097 nfp
->ctf_refcnt
= fp
->ctf_refcnt
;
1098 nfp
->ctf_flags
|= fp
->ctf_flags
& ~LCTF_DIRTY
;
1099 if (nfp
->ctf_dynbase
== NULL
)
1100 nfp
->ctf_dynbase
= buf
; /* Make sure buf is freed on close. */
1101 nfp
->ctf_dthash
= fp
->ctf_dthash
;
1102 nfp
->ctf_dtdefs
= fp
->ctf_dtdefs
;
1103 nfp
->ctf_dvhash
= fp
->ctf_dvhash
;
1104 nfp
->ctf_dvdefs
= fp
->ctf_dvdefs
;
1105 nfp
->ctf_dtoldid
= fp
->ctf_dtoldid
;
1106 nfp
->ctf_add_processing
= fp
->ctf_add_processing
;
1107 nfp
->ctf_snapshots
= fp
->ctf_snapshots
+ 1;
1108 nfp
->ctf_specific
= fp
->ctf_specific
;
1109 nfp
->ctf_nfuncidx
= fp
->ctf_nfuncidx
;
1110 nfp
->ctf_nobjtidx
= fp
->ctf_nobjtidx
;
1111 nfp
->ctf_objthash
= fp
->ctf_objthash
;
1112 nfp
->ctf_funchash
= fp
->ctf_funchash
;
1113 nfp
->ctf_dynsyms
= fp
->ctf_dynsyms
;
1114 nfp
->ctf_ptrtab
= fp
->ctf_ptrtab
;
1115 nfp
->ctf_pptrtab
= fp
->ctf_pptrtab
;
1116 nfp
->ctf_typemax
= fp
->ctf_typemax
;
1117 nfp
->ctf_dynsymidx
= fp
->ctf_dynsymidx
;
1118 nfp
->ctf_dynsymmax
= fp
->ctf_dynsymmax
;
1119 nfp
->ctf_ptrtab_len
= fp
->ctf_ptrtab_len
;
1120 nfp
->ctf_pptrtab_len
= fp
->ctf_pptrtab_len
;
1121 nfp
->ctf_link_inputs
= fp
->ctf_link_inputs
;
1122 nfp
->ctf_link_outputs
= fp
->ctf_link_outputs
;
1123 nfp
->ctf_errs_warnings
= fp
->ctf_errs_warnings
;
1124 nfp
->ctf_funcidx_names
= fp
->ctf_funcidx_names
;
1125 nfp
->ctf_objtidx_names
= fp
->ctf_objtidx_names
;
1126 nfp
->ctf_funcidx_sxlate
= fp
->ctf_funcidx_sxlate
;
1127 nfp
->ctf_objtidx_sxlate
= fp
->ctf_objtidx_sxlate
;
1128 nfp
->ctf_str_prov_offset
= fp
->ctf_str_prov_offset
;
1129 nfp
->ctf_syn_ext_strtab
= fp
->ctf_syn_ext_strtab
;
1130 nfp
->ctf_pptrtab_typemax
= fp
->ctf_pptrtab_typemax
;
1131 nfp
->ctf_in_flight_dynsyms
= fp
->ctf_in_flight_dynsyms
;
1132 nfp
->ctf_link_in_cu_mapping
= fp
->ctf_link_in_cu_mapping
;
1133 nfp
->ctf_link_out_cu_mapping
= fp
->ctf_link_out_cu_mapping
;
1134 nfp
->ctf_link_type_mapping
= fp
->ctf_link_type_mapping
;
1135 nfp
->ctf_link_memb_name_changer
= fp
->ctf_link_memb_name_changer
;
1136 nfp
->ctf_link_memb_name_changer_arg
= fp
->ctf_link_memb_name_changer_arg
;
1137 nfp
->ctf_link_variable_filter
= fp
->ctf_link_variable_filter
;
1138 nfp
->ctf_link_variable_filter_arg
= fp
->ctf_link_variable_filter_arg
;
1139 nfp
->ctf_symsect_little_endian
= fp
->ctf_symsect_little_endian
;
1140 nfp
->ctf_link_flags
= fp
->ctf_link_flags
;
1141 nfp
->ctf_dedup_atoms
= fp
->ctf_dedup_atoms
;
1142 nfp
->ctf_dedup_atoms_alloc
= fp
->ctf_dedup_atoms_alloc
;
1143 memcpy (&nfp
->ctf_dedup
, &fp
->ctf_dedup
, sizeof (fp
->ctf_dedup
));
1145 nfp
->ctf_snapshot_lu
= fp
->ctf_snapshots
;
1147 memcpy (&nfp
->ctf_lookups
, fp
->ctf_lookups
, sizeof (fp
->ctf_lookups
));
1148 nfp
->ctf_structs
= fp
->ctf_structs
;
1149 nfp
->ctf_unions
= fp
->ctf_unions
;
1150 nfp
->ctf_enums
= fp
->ctf_enums
;
1151 nfp
->ctf_names
= fp
->ctf_names
;
1153 fp
->ctf_dthash
= NULL
;
1154 ctf_str_free_atoms (nfp
);
1155 nfp
->ctf_str_atoms
= fp
->ctf_str_atoms
;
1156 nfp
->ctf_prov_strtab
= fp
->ctf_prov_strtab
;
1157 fp
->ctf_str_atoms
= NULL
;
1158 fp
->ctf_prov_strtab
= NULL
;
1159 memset (&fp
->ctf_dtdefs
, 0, sizeof (ctf_list_t
));
1160 memset (&fp
->ctf_errs_warnings
, 0, sizeof (ctf_list_t
));
1161 fp
->ctf_add_processing
= NULL
;
1162 fp
->ctf_ptrtab
= NULL
;
1163 fp
->ctf_pptrtab
= NULL
;
1164 fp
->ctf_funcidx_names
= NULL
;
1165 fp
->ctf_objtidx_names
= NULL
;
1166 fp
->ctf_funcidx_sxlate
= NULL
;
1167 fp
->ctf_objtidx_sxlate
= NULL
;
1168 fp
->ctf_objthash
= NULL
;
1169 fp
->ctf_funchash
= NULL
;
1170 fp
->ctf_dynsyms
= NULL
;
1171 fp
->ctf_dynsymidx
= NULL
;
1172 fp
->ctf_link_inputs
= NULL
;
1173 fp
->ctf_link_outputs
= NULL
;
1174 fp
->ctf_syn_ext_strtab
= NULL
;
1175 fp
->ctf_link_in_cu_mapping
= NULL
;
1176 fp
->ctf_link_out_cu_mapping
= NULL
;
1177 fp
->ctf_link_type_mapping
= NULL
;
1178 fp
->ctf_dedup_atoms
= NULL
;
1179 fp
->ctf_dedup_atoms_alloc
= NULL
;
1180 fp
->ctf_parent_unreffed
= 1;
1182 fp
->ctf_dvhash
= NULL
;
1183 memset (&fp
->ctf_dvdefs
, 0, sizeof (ctf_list_t
));
1184 memset (fp
->ctf_lookups
, 0, sizeof (fp
->ctf_lookups
));
1185 memset (&fp
->ctf_in_flight_dynsyms
, 0, sizeof (fp
->ctf_in_flight_dynsyms
));
1186 memset (&fp
->ctf_dedup
, 0, sizeof (fp
->ctf_dedup
));
1187 fp
->ctf_structs
.ctn_writable
= NULL
;
1188 fp
->ctf_unions
.ctn_writable
= NULL
;
1189 fp
->ctf_enums
.ctn_writable
= NULL
;
1190 fp
->ctf_names
.ctn_writable
= NULL
;
1192 memcpy (&ofp
, fp
, sizeof (ctf_dict_t
));
1193 memcpy (fp
, nfp
, sizeof (ctf_dict_t
));
1194 memcpy (nfp
, &ofp
, sizeof (ctf_dict_t
));
1196 nfp
->ctf_refcnt
= 1; /* Force nfp to be freed. */
1197 ctf_dict_close (nfp
);
1203 return (ctf_set_errno (fp
, EAGAIN
));
1206 return -1; /* errno is set for us. */
1211 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1213 ctf_gzwrite (ctf_dict_t
*fp
, gzFile fd
)
1215 const unsigned char *buf
;
1219 resid
= sizeof (ctf_header_t
);
1220 buf
= (unsigned char *) fp
->ctf_header
;
1223 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1224 return (ctf_set_errno (fp
, errno
));
1229 resid
= fp
->ctf_size
;
1233 if ((len
= gzwrite (fd
, buf
, resid
)) <= 0)
1234 return (ctf_set_errno (fp
, errno
));
1242 /* Compress the specified CTF data stream and write it to the specified file
1245 ctf_compress_write (ctf_dict_t
*fp
, int fd
)
1250 ctf_header_t
*hp
= &h
;
1251 ssize_t header_len
= sizeof (ctf_header_t
);
1252 ssize_t compress_len
;
1257 if (ctf_serialize (fp
) < 0)
1258 return -1; /* errno is set for us. */
1260 memcpy (hp
, fp
->ctf_header
, header_len
);
1261 hp
->cth_flags
|= CTF_F_COMPRESS
;
1262 compress_len
= compressBound (fp
->ctf_size
);
1264 if ((buf
= malloc (compress_len
)) == NULL
)
1266 ctf_err_warn (fp
, 0, 0, _("ctf_compress_write: cannot allocate %li bytes"),
1267 (unsigned long) compress_len
);
1268 return (ctf_set_errno (fp
, ECTF_ZALLOC
));
1271 if ((rc
= compress (buf
, (uLongf
*) &compress_len
,
1272 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
1274 err
= ctf_set_errno (fp
, ECTF_COMPRESS
);
1275 ctf_err_warn (fp
, 0, 0, _("zlib deflate err: %s"), zError (rc
));
1279 while (header_len
> 0)
1281 if ((len
= write (fd
, hp
, header_len
)) < 0)
1283 err
= ctf_set_errno (fp
, errno
);
1284 ctf_err_warn (fp
, 0, 0, _("ctf_compress_write: error writing header"));
1292 while (compress_len
> 0)
1294 if ((len
= write (fd
, bp
, compress_len
)) < 0)
1296 err
= ctf_set_errno (fp
, errno
);
1297 ctf_err_warn (fp
, 0, 0, _("ctf_compress_write: error writing"));
1300 compress_len
-= len
;
1309 /* Optionally compress the specified CTF data stream and return it as a new
1310 dynamically-allocated string. */
1312 ctf_write_mem (ctf_dict_t
*fp
, size_t *size
, size_t threshold
)
1317 ssize_t header_len
= sizeof (ctf_header_t
);
1318 ssize_t compress_len
;
1321 if (ctf_serialize (fp
) < 0)
1322 return NULL
; /* errno is set for us. */
1324 compress_len
= compressBound (fp
->ctf_size
);
1325 if (fp
->ctf_size
< threshold
)
1326 compress_len
= fp
->ctf_size
;
1327 if ((buf
= malloc (compress_len
1328 + sizeof (struct ctf_header
))) == NULL
)
1330 ctf_set_errno (fp
, ENOMEM
);
1331 ctf_err_warn (fp
, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
1332 (unsigned long) (compress_len
+ sizeof (struct ctf_header
)));
1336 hp
= (ctf_header_t
*) buf
;
1337 memcpy (hp
, fp
->ctf_header
, header_len
);
1338 bp
= buf
+ sizeof (struct ctf_header
);
1339 *size
= sizeof (struct ctf_header
);
1341 if (fp
->ctf_size
< threshold
)
1343 hp
->cth_flags
&= ~CTF_F_COMPRESS
;
1344 memcpy (bp
, fp
->ctf_buf
, fp
->ctf_size
);
1345 *size
+= fp
->ctf_size
;
1349 hp
->cth_flags
|= CTF_F_COMPRESS
;
1350 if ((rc
= compress (bp
, (uLongf
*) &compress_len
,
1351 fp
->ctf_buf
, fp
->ctf_size
)) != Z_OK
)
1353 ctf_set_errno (fp
, ECTF_COMPRESS
);
1354 ctf_err_warn (fp
, 0, 0, _("zlib deflate err: %s"), zError (rc
));
1358 *size
+= compress_len
;
1363 /* Write the uncompressed CTF data stream to the specified file descriptor. */
1365 ctf_write (ctf_dict_t
*fp
, int fd
)
1367 const unsigned char *buf
;
1371 if (ctf_serialize (fp
) < 0)
1372 return -1; /* errno is set for us. */
1374 resid
= sizeof (ctf_header_t
);
1375 buf
= (unsigned char *) fp
->ctf_header
;
1378 if ((len
= write (fd
, buf
, resid
)) <= 0)
1380 ctf_err_warn (fp
, 0, errno
, _("ctf_write: error writing header"));
1381 return (ctf_set_errno (fp
, errno
));
1387 resid
= fp
->ctf_size
;
1391 if ((len
= write (fd
, buf
, resid
)) <= 0)
1393 ctf_err_warn (fp
, 0, errno
, _("ctf_write: error writing"));
1394 return (ctf_set_errno (fp
, errno
));