Document the GDB 10.2 release in gdb/ChangeLog
[binutils-gdb.git] / libctf / ctf-serialize.c
blob9f50280176c5ab6d0594087d3f83efca32f9a4a6
1 /* CTF dict creation.
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
9 version.
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/>. */
20 #include <ctf-impl.h>
21 #include <assert.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <zlib.h>
26 #include <elf.h>
27 #include "elf-bfd.h"
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
44 much. */
45 int filter_syms;
47 /* True if symbols are being sorted. */
48 int sort_syms;
50 /* Flags for symtypetab emission. */
51 int symflags;
53 /* The dict to which the linker has reported symbols. */
54 ctf_dict_t *symfp;
56 /* The maximum number of objects seen. */
57 size_t maxobjt;
59 /* The maximum number of func info entris seen. */
60 size_t maxfunc;
61 } emit_symtypetab_state_t;
63 /* Determine if a symbol is "skippable" and should never appear in the
64 symtypetab sections. */
66 int
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)
71 return 0;
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))
92 static int
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)
97 ctf_next_t *i = NULL;
98 const void *name;
99 const void *ctf_sym;
100 ctf_dynhash_t *linker_known = NULL;
101 int err;
102 int beyond_max = 0;
104 *count = 0;
105 *max = 0;
106 *unpadsize = 0;
107 *idxsize = 0;
108 *padsize = 0;
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)
122 return 0;
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))
137 continue;
139 if (ctf_symtab_skippable (sym))
140 continue;
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 "
156 "serialization"));
157 ctf_dynhash_destroy (linker_known);
158 return (ctf_set_errno (fp, err));
162 while ((err = ctf_dynhash_cnext (symhash, &i, &name, NULL)) == 0)
164 ctf_link_sym_t *sym;
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);
173 continue;
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))
179 continue;
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);
190 continue;
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);
201 continue;
204 ctf_dynhash_remove (linker_known, name);
206 *unpadsize += sizeof (uint32_t);
207 (*count)++;
209 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
211 if (*max < sym->st_symidx)
212 *max = sym->st_symidx;
214 else
215 (*max)++;
217 if (err != ECTF_NEXT_END)
219 ctf_err_warn (fp, 0, err, _("iterating over CTF symtypetab during "
220 "serialization"));
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)
232 beyond_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);
248 return 0;
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. */
257 static int
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)
262 uint32_t i;
263 uint32_t *dpp = dp;
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. */
270 if (size == 0)
271 return 0;
273 if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
274 symhash = fp->ctf_funchash;
275 else
276 symhash = fp->ctf_objthash;
278 for (i = 0; i < nidx; i++)
280 const char *sym_name;
281 void *type;
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;
290 if (idx)
291 this_link_sym = idx[i];
292 else
293 this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, nameidx[i]);
295 /* Unreported symbol number. No pad, no nothing. */
296 if (!this_link_sym)
297 continue;
299 /* Symbol of the wrong type, or skippable? This symbol is not in this
300 table. */
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))
305 continue;
307 if (ctf_symtab_skippable (this_link_sym))
308 continue;
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)))
318 continue;
320 if ((this_link_sym->st_type == STT_OBJECT)
321 && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
322 continue;
324 else
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)
333 *dpp++ = 0;
334 continue;
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
343 early. */
344 if ((flags & CTF_SYMTYPETAB_EMIT_PAD) && idx[i]->st_symidx == outmax)
345 break;
348 return 0;
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. */
354 static int
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)
358 uint32_t i;
359 uint32_t *dpp = dp;
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. */
366 if (size == 0)
367 return 0;
369 if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
370 symhash = fp->ctf_funchash;
371 else
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;
381 void *type;
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
394 table. */
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))
399 continue;
401 if (ctf_symtab_skippable (this_link_sym))
402 continue;
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)))
410 continue;
412 if ((this_link_sym->st_type == STT_OBJECT)
413 && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
414 continue;
416 else
417 sym_name = idx[i];
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)
423 continue;
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. */
431 return 0;
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. */
438 static int
439 symtypetab_delete_nonstatic_vars (ctf_dict_t *fp, ctf_dict_t *symfp)
441 ctf_dvdef_t *dvd, *nvd;
442 ctf_id_t type;
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);
455 return 0;
458 /* Figure out the sizes of the symtypetab sections, their indexed state,
459 etc. */
460 static int
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.) */
478 s->sort_syms = 1;
479 if (fp->ctf_flags & LCTF_LINKING)
481 s->filter_syms = !(fp->ctf_link_flags & CTF_LINK_NO_FILTER_REPORTED_SYMS);
482 if (!s->filter_syms)
483 s->sort_syms = 0;
486 /* Find the dict to which the linker has reported symbols, if any. */
488 if (s->filter_syms)
490 if (!fp->ctf_dynsyms && fp->ctf_parent && fp->ctf_parent->ctf_dynsyms)
491 s->symfp = fp->ctf_parent;
492 else
493 s->symfp = fp;
496 /* If not filtering, keep all potential symbols in an unsorted, indexed
497 dict. */
498 if (!s->filter_syms)
499 s->symflags = CTF_SYMTYPETAB_FORCE_INDEXED;
500 else
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))))
506 return -1;
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
510 sections. */
512 if (symtypetab_density (fp, s->symfp, fp->ctf_objthash, &nobjts, &s->maxobjt,
513 &objt_unpadsize, &objt_padsize, objtidx_size,
514 s->symflags) < 0)
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
541 compiler does. */
543 *objt_size = objt_unpadsize;
544 if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
545 && ((objt_padsize + objt_unpadsize) * CTF_INDEX_PAD_THRESHOLD
546 > objt_padsize))
548 *objt_size += objt_padsize;
549 *objtidx_size = 0;
552 *func_size = func_unpadsize;
553 if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
554 && ((func_padsize + func_unpadsize) * CTF_INDEX_PAD_THRESHOLD
555 > func_padsize))
557 *func_size += func_padsize;
558 *funcidx_size = 0;
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)
570 return -1;
572 return 0;
575 static int
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,
579 size_t funcidx_size)
581 unsigned char *t = *tptr;
582 size_t nsymtypes = 0;
583 const char **sym_name_order = NULL;
584 int err;
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;
591 void *symname;
592 const char **walk;
594 if (s->filter_syms)
596 if (s->symfp->ctf_dynsyms)
597 nsymtypes = ctf_dynhash_elements (s->symfp->ctf_dynsyms);
598 else
599 nsymtypes = 0;
601 else
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)
606 goto oom;
608 walk = sym_name_order;
610 if (s->filter_syms)
612 if (s->symfp->ctf_dynsyms)
614 while ((err = ctf_dynhash_next_sorted (s->symfp->ctf_dynsyms, &i,
615 &symname, NULL,
616 ctf_dynhash_sort_by_name,
617 NULL)) == 0)
618 *walk++ = (const char *) symname;
619 if (err != ECTF_NEXT_END)
620 goto symerr;
623 else
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. */
629 if (s->sort_syms)
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)
636 goto symerr;
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)
642 goto symerr;
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. */
659 else
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. */
668 t += objt_size;
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. */
680 else
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. */
689 t += func_size;
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)
694 goto err;
696 t += objtidx_size;
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)
702 goto err;
704 t += funcidx_size;
705 free (sym_name_order);
706 *tptr = t;
708 return 0;
710 oom:
711 ctf_set_errno (fp, EAGAIN);
712 goto err;
713 symerr:
714 ctf_err_warn (fp, 0, err, _("error serializing symtypetabs"));
715 err:
716 free (sym_name_order);
717 return -1;
720 /* Type section. */
722 /* Iterate through the dynamic type definition list and compute the
723 size of the CTF type section. */
725 static size_t
726 ctf_type_sect_size (ctf_dict_t *fp)
728 ctf_dtdef_t *dtd;
729 size_t type_size;
731 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
732 dtd != NULL; dtd = ctf_list_next (dtd))
734 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
735 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
736 size_t type_ctt_size = dtd->dtd_data.ctt_size;
738 /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
739 if possible. */
741 if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
743 size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);
745 if (lsize <= CTF_MAX_SIZE)
746 type_ctt_size = lsize;
749 if (type_ctt_size != CTF_LSIZE_SENT)
750 type_size += sizeof (ctf_stype_t);
751 else
752 type_size += sizeof (ctf_type_t);
754 switch (kind)
756 case CTF_K_INTEGER:
757 case CTF_K_FLOAT:
758 type_size += sizeof (uint32_t);
759 break;
760 case CTF_K_ARRAY:
761 type_size += sizeof (ctf_array_t);
762 break;
763 case CTF_K_SLICE:
764 type_size += sizeof (ctf_slice_t);
765 break;
766 case CTF_K_FUNCTION:
767 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
768 break;
769 case CTF_K_STRUCT:
770 case CTF_K_UNION:
771 if (type_ctt_size < CTF_LSTRUCT_THRESH)
772 type_size += sizeof (ctf_member_t) * vlen;
773 else
774 type_size += sizeof (ctf_lmember_t) * vlen;
775 break;
776 case CTF_K_ENUM:
777 type_size += sizeof (ctf_enum_t) * vlen;
778 break;
782 return type_size;
785 /* Take a final lap through the dynamic type definition list and copy the
786 appropriate type records to the output buffer, noting down the strings as
787 we go. */
789 static void
790 ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr)
792 unsigned char *t = *tptr;
793 ctf_dtdef_t *dtd;
795 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
796 dtd != NULL; dtd = ctf_list_next (dtd))
798 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
799 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
800 size_t type_ctt_size = dtd->dtd_data.ctt_size;
801 size_t len;
802 ctf_stype_t *copied;
803 const char *name;
804 size_t i;
806 /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
807 if possible. */
809 if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
811 size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);
813 if (lsize <= CTF_MAX_SIZE)
814 type_ctt_size = lsize;
817 if (type_ctt_size != CTF_LSIZE_SENT)
818 len = sizeof (ctf_stype_t);
819 else
820 len = sizeof (ctf_type_t);
822 memcpy (t, &dtd->dtd_data, len);
823 copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */
824 if (copied->ctt_name
825 && (name = ctf_strraw (fp, copied->ctt_name)) != NULL)
827 ctf_str_add_ref (fp, name, &copied->ctt_name);
828 ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
830 copied->ctt_size = type_ctt_size;
831 t += len;
833 switch (kind)
835 case CTF_K_INTEGER:
836 case CTF_K_FLOAT:
837 memcpy (t, dtd->dtd_vlen, sizeof (uint32_t));
838 t += sizeof (uint32_t);
839 break;
841 case CTF_K_SLICE:
842 memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_slice));
843 t += sizeof (struct ctf_slice);
844 break;
846 case CTF_K_ARRAY:
847 memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_array));
848 t += sizeof (struct ctf_array);
849 break;
851 case CTF_K_FUNCTION:
852 /* Functions with no args also have no vlen. */
853 if (dtd->dtd_vlen)
854 memcpy (t, dtd->dtd_vlen, sizeof (uint32_t) * (vlen + (vlen & 1)));
855 t += sizeof (uint32_t) * (vlen + (vlen & 1));
856 break;
858 /* These need to be copied across element by element, depending on
859 their ctt_size. */
860 case CTF_K_STRUCT:
861 case CTF_K_UNION:
863 ctf_lmember_t *dtd_vlen = (ctf_lmember_t *) dtd->dtd_vlen;
864 ctf_lmember_t *t_lvlen = (ctf_lmember_t *) t;
865 ctf_member_t *t_vlen = (ctf_member_t *) t;
867 for (i = 0; i < vlen; i++)
869 const char *name = ctf_strraw (fp, dtd_vlen[i].ctlm_name);
871 ctf_str_add_ref (fp, name, &dtd_vlen[i].ctlm_name);
873 if (type_ctt_size < CTF_LSTRUCT_THRESH)
875 t_vlen[i].ctm_name = dtd_vlen[i].ctlm_name;
876 t_vlen[i].ctm_type = dtd_vlen[i].ctlm_type;
877 t_vlen[i].ctm_offset = CTF_LMEM_OFFSET (&dtd_vlen[i]);
878 ctf_str_add_ref (fp, name, &t_vlen[i].ctm_name);
880 else
882 t_lvlen[i] = dtd_vlen[i];
883 ctf_str_add_ref (fp, name, &t_lvlen[i].ctlm_name);
888 if (type_ctt_size < CTF_LSTRUCT_THRESH)
889 t += sizeof (ctf_member_t) * vlen;
890 else
891 t += sizeof (ctf_lmember_t) * vlen;
892 break;
894 case CTF_K_ENUM:
896 ctf_enum_t *dtd_vlen = (struct ctf_enum *) dtd->dtd_vlen;
897 ctf_enum_t *t_vlen = (struct ctf_enum *) t;
899 memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_enum) * vlen);
900 for (i = 0; i < vlen; i++)
902 const char *name = ctf_strraw (fp, dtd_vlen[i].cte_name);
904 ctf_str_add_ref (fp, name, &t_vlen[i].cte_name);
905 ctf_str_add_ref (fp, name, &dtd_vlen[i].cte_name);
907 t += sizeof (struct ctf_enum) * vlen;
909 break;
914 *tptr = t;
917 /* Variable section. */
919 /* Sort a newly-constructed static variable array. */
921 typedef struct ctf_sort_var_arg_cb
923 ctf_dict_t *fp;
924 ctf_strs_t *strtab;
925 } ctf_sort_var_arg_cb_t;
927 static int
928 ctf_sort_var (const void *one_, const void *two_, void *arg_)
930 const ctf_varent_t *one = one_;
931 const ctf_varent_t *two = two_;
932 ctf_sort_var_arg_cb_t *arg = arg_;
934 return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
935 ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
938 /* Overall serialization. */
940 /* If the specified CTF dict is writable and has been modified, reload this dict
941 with the updated type definitions, ready for serialization. In order to make
942 this code and the rest of libctf as simple as possible, we perform updates by
943 taking the dynamic type definitions and creating an in-memory CTF dict
944 containing the definitions, and then call ctf_simple_open_internal() on it.
945 We perform one extra trick here for the benefit of callers and to keep our
946 code simple: ctf_simple_open_internal() will return a new ctf_dict_t, but we
947 want to keep the fp constant for the caller, so after
948 ctf_simple_open_internal() returns, we use memcpy to swap the interior of the
949 old and new ctf_dict_t's, and then free the old. */
951 ctf_serialize (ctf_dict_t *fp)
953 ctf_dict_t ofp, *nfp;
954 ctf_header_t hdr, *hdrp;
955 ctf_dvdef_t *dvd;
956 ctf_varent_t *dvarents;
957 ctf_strs_writable_t strtab;
958 int err;
959 int num_missed_str_refs;
961 unsigned char *t;
962 unsigned long i;
963 size_t buf_size, type_size, objt_size, func_size;
964 size_t funcidx_size, objtidx_size;
965 size_t nvars;
966 unsigned char *buf = NULL, *newbuf;
968 emit_symtypetab_state_t symstate;
969 memset (&symstate, 0, sizeof (emit_symtypetab_state_t));
971 if (!(fp->ctf_flags & LCTF_RDWR))
972 return (ctf_set_errno (fp, ECTF_RDONLY));
974 /* Update required? */
975 if (!(fp->ctf_flags & LCTF_DIRTY))
976 return 0;
978 /* The strtab refs table must be empty at this stage. Any refs already added
979 will be corrupted by any modifications, including reserialization, after
980 strtab finalization is complete. Only this function, and functions it
981 calls, may add refs, and all memory locations (including in the dtds)
982 containing strtab offsets must be traversed as part of serialization, and
983 refs added. */
985 if (!ctf_assert (fp, fp->ctf_str_num_refs == 0))
986 return -1; /* errno is set for us. */
988 /* Fill in an initial CTF header. We will leave the label, object,
989 and function sections empty and only output a header, type section,
990 and string table. The type section begins at a 4-byte aligned
991 boundary past the CTF header itself (at relative offset zero). The flag
992 indicating a new-style function info section (an array of CTF_K_FUNCTION
993 type IDs in the types section) is flipped on. */
995 memset (&hdr, 0, sizeof (hdr));
996 hdr.cth_magic = CTF_MAGIC;
997 hdr.cth_version = CTF_VERSION;
999 /* This is a new-format func info section, and the symtab and strtab come out
1000 of the dynsym and dynstr these days. */
1001 hdr.cth_flags = (CTF_F_NEWFUNCINFO | CTF_F_DYNSTR);
1003 if (ctf_symtypetab_sect_sizes (fp, &symstate, &hdr, &objt_size, &func_size,
1004 &objtidx_size, &funcidx_size) < 0)
1005 return -1; /* errno is set for us. */
1007 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
1008 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
1010 type_size = ctf_type_sect_size (fp);
1012 /* Compute the size of the CTF buffer we need, sans only the string table,
1013 then allocate a new buffer and memcpy the finished header to the start of
1014 the buffer. (We will adjust this later with strtab length info.) */
1016 hdr.cth_lbloff = hdr.cth_objtoff = 0;
1017 hdr.cth_funcoff = hdr.cth_objtoff + objt_size;
1018 hdr.cth_objtidxoff = hdr.cth_funcoff + func_size;
1019 hdr.cth_funcidxoff = hdr.cth_objtidxoff + objtidx_size;
1020 hdr.cth_varoff = hdr.cth_funcidxoff + funcidx_size;
1021 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
1022 hdr.cth_stroff = hdr.cth_typeoff + type_size;
1023 hdr.cth_strlen = 0;
1025 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
1027 if ((buf = malloc (buf_size)) == NULL)
1028 return (ctf_set_errno (fp, EAGAIN));
1030 memcpy (buf, &hdr, sizeof (ctf_header_t));
1031 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_objtoff;
1033 hdrp = (ctf_header_t *) buf;
1034 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
1035 ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
1036 if (fp->ctf_cuname != NULL)
1037 ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);
1039 if (ctf_emit_symtypetab_sects (fp, &symstate, &t, objt_size, func_size,
1040 objtidx_size, funcidx_size) < 0)
1041 goto err;
1043 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff);
1045 /* Work over the variable list, translating everything into ctf_varent_t's and
1046 prepping the string table. */
1048 dvarents = (ctf_varent_t *) t;
1049 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
1050 dvd = ctf_list_next (dvd), i++)
1052 ctf_varent_t *var = &dvarents[i];
1054 ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
1055 var->ctv_type = (uint32_t) dvd->dvd_type;
1057 assert (i == nvars);
1059 t += sizeof (ctf_varent_t) * nvars;
1061 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
1063 ctf_emit_type_sect (fp, &t);
1065 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
1067 /* Every string added outside serialization by ctf_str_add_pending should
1068 now have been added by ctf_add_ref. */
1069 num_missed_str_refs = ctf_dynset_elements (fp->ctf_str_pending_ref);
1070 if (!ctf_assert (fp, num_missed_str_refs == 0))
1071 goto err; /* errno is set for us. */
1073 /* Construct the final string table and fill out all the string refs with the
1074 final offsets. Then purge the refs list, because we're about to move this
1075 strtab onto the end of the buf, invalidating all the offsets. */
1076 strtab = ctf_str_write_strtab (fp);
1077 ctf_str_purge_refs (fp);
1079 if (strtab.cts_strs == NULL)
1080 goto oom;
1082 /* Now the string table is constructed, we can sort the buffer of
1083 ctf_varent_t's. */
1084 ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) &strtab };
1085 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
1086 &sort_var_arg);
1088 if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
1090 free (strtab.cts_strs);
1091 goto oom;
1093 buf = newbuf;
1094 memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
1095 hdrp = (ctf_header_t *) buf;
1096 hdrp->cth_strlen = strtab.cts_len;
1097 buf_size += hdrp->cth_strlen;
1098 free (strtab.cts_strs);
1100 /* Finally, we are ready to ctf_simple_open() the new dict. If this is
1101 successful, we then switch nfp and fp and free the old dict. */
1103 if ((nfp = ctf_simple_open_internal ((char *) buf, buf_size, NULL, 0,
1104 0, NULL, 0, fp->ctf_syn_ext_strtab,
1105 1, &err)) == NULL)
1107 free (buf);
1108 return (ctf_set_errno (fp, err));
1111 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
1113 nfp->ctf_parent = fp->ctf_parent;
1114 nfp->ctf_parent_unreffed = fp->ctf_parent_unreffed;
1115 nfp->ctf_refcnt = fp->ctf_refcnt;
1116 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
1117 if (nfp->ctf_dynbase == NULL)
1118 nfp->ctf_dynbase = buf; /* Make sure buf is freed on close. */
1119 nfp->ctf_dthash = fp->ctf_dthash;
1120 nfp->ctf_dtdefs = fp->ctf_dtdefs;
1121 nfp->ctf_dvhash = fp->ctf_dvhash;
1122 nfp->ctf_dvdefs = fp->ctf_dvdefs;
1123 nfp->ctf_dtoldid = fp->ctf_dtoldid;
1124 nfp->ctf_add_processing = fp->ctf_add_processing;
1125 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
1126 nfp->ctf_specific = fp->ctf_specific;
1127 nfp->ctf_nfuncidx = fp->ctf_nfuncidx;
1128 nfp->ctf_nobjtidx = fp->ctf_nobjtidx;
1129 nfp->ctf_objthash = fp->ctf_objthash;
1130 nfp->ctf_funchash = fp->ctf_funchash;
1131 nfp->ctf_dynsyms = fp->ctf_dynsyms;
1132 nfp->ctf_ptrtab = fp->ctf_ptrtab;
1133 nfp->ctf_pptrtab = fp->ctf_pptrtab;
1134 nfp->ctf_typemax = fp->ctf_typemax;
1135 nfp->ctf_dynsymidx = fp->ctf_dynsymidx;
1136 nfp->ctf_dynsymmax = fp->ctf_dynsymmax;
1137 nfp->ctf_ptrtab_len = fp->ctf_ptrtab_len;
1138 nfp->ctf_pptrtab_len = fp->ctf_pptrtab_len;
1139 nfp->ctf_link_inputs = fp->ctf_link_inputs;
1140 nfp->ctf_link_outputs = fp->ctf_link_outputs;
1141 nfp->ctf_errs_warnings = fp->ctf_errs_warnings;
1142 nfp->ctf_funcidx_names = fp->ctf_funcidx_names;
1143 nfp->ctf_objtidx_names = fp->ctf_objtidx_names;
1144 nfp->ctf_funcidx_sxlate = fp->ctf_funcidx_sxlate;
1145 nfp->ctf_objtidx_sxlate = fp->ctf_objtidx_sxlate;
1146 nfp->ctf_str_prov_offset = fp->ctf_str_prov_offset;
1147 nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
1148 nfp->ctf_pptrtab_typemax = fp->ctf_pptrtab_typemax;
1149 nfp->ctf_in_flight_dynsyms = fp->ctf_in_flight_dynsyms;
1150 nfp->ctf_link_in_cu_mapping = fp->ctf_link_in_cu_mapping;
1151 nfp->ctf_link_out_cu_mapping = fp->ctf_link_out_cu_mapping;
1152 nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
1153 nfp->ctf_link_memb_name_changer = fp->ctf_link_memb_name_changer;
1154 nfp->ctf_link_memb_name_changer_arg = fp->ctf_link_memb_name_changer_arg;
1155 nfp->ctf_link_variable_filter = fp->ctf_link_variable_filter;
1156 nfp->ctf_link_variable_filter_arg = fp->ctf_link_variable_filter_arg;
1157 nfp->ctf_symsect_little_endian = fp->ctf_symsect_little_endian;
1158 nfp->ctf_link_flags = fp->ctf_link_flags;
1159 nfp->ctf_dedup_atoms = fp->ctf_dedup_atoms;
1160 nfp->ctf_dedup_atoms_alloc = fp->ctf_dedup_atoms_alloc;
1161 memcpy (&nfp->ctf_dedup, &fp->ctf_dedup, sizeof (fp->ctf_dedup));
1163 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
1165 memcpy (&nfp->ctf_lookups, fp->ctf_lookups, sizeof (fp->ctf_lookups));
1166 nfp->ctf_structs = fp->ctf_structs;
1167 nfp->ctf_unions = fp->ctf_unions;
1168 nfp->ctf_enums = fp->ctf_enums;
1169 nfp->ctf_names = fp->ctf_names;
1171 fp->ctf_dthash = NULL;
1172 ctf_str_free_atoms (nfp);
1173 nfp->ctf_str_atoms = fp->ctf_str_atoms;
1174 nfp->ctf_prov_strtab = fp->ctf_prov_strtab;
1175 nfp->ctf_str_pending_ref = fp->ctf_str_pending_ref;
1176 fp->ctf_str_atoms = NULL;
1177 fp->ctf_prov_strtab = NULL;
1178 fp->ctf_str_pending_ref = NULL;
1179 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
1180 memset (&fp->ctf_errs_warnings, 0, sizeof (ctf_list_t));
1181 fp->ctf_add_processing = NULL;
1182 fp->ctf_ptrtab = NULL;
1183 fp->ctf_pptrtab = NULL;
1184 fp->ctf_funcidx_names = NULL;
1185 fp->ctf_objtidx_names = NULL;
1186 fp->ctf_funcidx_sxlate = NULL;
1187 fp->ctf_objtidx_sxlate = NULL;
1188 fp->ctf_objthash = NULL;
1189 fp->ctf_funchash = NULL;
1190 fp->ctf_dynsyms = NULL;
1191 fp->ctf_dynsymidx = NULL;
1192 fp->ctf_link_inputs = NULL;
1193 fp->ctf_link_outputs = NULL;
1194 fp->ctf_syn_ext_strtab = NULL;
1195 fp->ctf_link_in_cu_mapping = NULL;
1196 fp->ctf_link_out_cu_mapping = NULL;
1197 fp->ctf_link_type_mapping = NULL;
1198 fp->ctf_dedup_atoms = NULL;
1199 fp->ctf_dedup_atoms_alloc = NULL;
1200 fp->ctf_parent_unreffed = 1;
1202 fp->ctf_dvhash = NULL;
1203 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
1204 memset (fp->ctf_lookups, 0, sizeof (fp->ctf_lookups));
1205 memset (&fp->ctf_in_flight_dynsyms, 0, sizeof (fp->ctf_in_flight_dynsyms));
1206 memset (&fp->ctf_dedup, 0, sizeof (fp->ctf_dedup));
1207 fp->ctf_structs.ctn_writable = NULL;
1208 fp->ctf_unions.ctn_writable = NULL;
1209 fp->ctf_enums.ctn_writable = NULL;
1210 fp->ctf_names.ctn_writable = NULL;
1212 memcpy (&ofp, fp, sizeof (ctf_dict_t));
1213 memcpy (fp, nfp, sizeof (ctf_dict_t));
1214 memcpy (nfp, &ofp, sizeof (ctf_dict_t));
1216 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
1217 ctf_dict_close (nfp);
1219 return 0;
1221 oom:
1222 free (buf);
1223 return (ctf_set_errno (fp, EAGAIN));
1224 err:
1225 free (buf);
1226 return -1; /* errno is set for us. */
1229 /* File writing. */
1231 /* Write the compressed CTF data stream to the specified gzFile descriptor. */
1233 ctf_gzwrite (ctf_dict_t *fp, gzFile fd)
1235 const unsigned char *buf;
1236 ssize_t resid;
1237 ssize_t len;
1239 resid = sizeof (ctf_header_t);
1240 buf = (unsigned char *) fp->ctf_header;
1241 while (resid != 0)
1243 if ((len = gzwrite (fd, buf, resid)) <= 0)
1244 return (ctf_set_errno (fp, errno));
1245 resid -= len;
1246 buf += len;
1249 resid = fp->ctf_size;
1250 buf = fp->ctf_buf;
1251 while (resid != 0)
1253 if ((len = gzwrite (fd, buf, resid)) <= 0)
1254 return (ctf_set_errno (fp, errno));
1255 resid -= len;
1256 buf += len;
1259 return 0;
1262 /* Compress the specified CTF data stream and write it to the specified file
1263 descriptor. */
1265 ctf_compress_write (ctf_dict_t *fp, int fd)
1267 unsigned char *buf;
1268 unsigned char *bp;
1269 ctf_header_t h;
1270 ctf_header_t *hp = &h;
1271 ssize_t header_len = sizeof (ctf_header_t);
1272 ssize_t compress_len;
1273 ssize_t len;
1274 int rc;
1275 int err = 0;
1277 if (ctf_serialize (fp) < 0)
1278 return -1; /* errno is set for us. */
1280 memcpy (hp, fp->ctf_header, header_len);
1281 hp->cth_flags |= CTF_F_COMPRESS;
1282 compress_len = compressBound (fp->ctf_size);
1284 if ((buf = malloc (compress_len)) == NULL)
1286 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: cannot allocate %li bytes"),
1287 (unsigned long) compress_len);
1288 return (ctf_set_errno (fp, ECTF_ZALLOC));
1291 if ((rc = compress (buf, (uLongf *) &compress_len,
1292 fp->ctf_buf, fp->ctf_size)) != Z_OK)
1294 err = ctf_set_errno (fp, ECTF_COMPRESS);
1295 ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
1296 goto ret;
1299 while (header_len > 0)
1301 if ((len = write (fd, hp, header_len)) < 0)
1303 err = ctf_set_errno (fp, errno);
1304 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing header"));
1305 goto ret;
1307 header_len -= len;
1308 hp += len;
1311 bp = buf;
1312 while (compress_len > 0)
1314 if ((len = write (fd, bp, compress_len)) < 0)
1316 err = ctf_set_errno (fp, errno);
1317 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
1318 goto ret;
1320 compress_len -= len;
1321 bp += len;
1324 ret:
1325 free (buf);
1326 return err;
1329 /* Optionally compress the specified CTF data stream and return it as a new
1330 dynamically-allocated string. */
1331 unsigned char *
1332 ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold)
1334 unsigned char *buf;
1335 unsigned char *bp;
1336 ctf_header_t *hp;
1337 ssize_t header_len = sizeof (ctf_header_t);
1338 ssize_t compress_len;
1339 int rc;
1341 if (ctf_serialize (fp) < 0)
1342 return NULL; /* errno is set for us. */
1344 compress_len = compressBound (fp->ctf_size);
1345 if (fp->ctf_size < threshold)
1346 compress_len = fp->ctf_size;
1347 if ((buf = malloc (compress_len
1348 + sizeof (struct ctf_header))) == NULL)
1350 ctf_set_errno (fp, ENOMEM);
1351 ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
1352 (unsigned long) (compress_len + sizeof (struct ctf_header)));
1353 return NULL;
1356 hp = (ctf_header_t *) buf;
1357 memcpy (hp, fp->ctf_header, header_len);
1358 bp = buf + sizeof (struct ctf_header);
1359 *size = sizeof (struct ctf_header);
1361 if (fp->ctf_size < threshold)
1363 hp->cth_flags &= ~CTF_F_COMPRESS;
1364 memcpy (bp, fp->ctf_buf, fp->ctf_size);
1365 *size += fp->ctf_size;
1367 else
1369 hp->cth_flags |= CTF_F_COMPRESS;
1370 if ((rc = compress (bp, (uLongf *) &compress_len,
1371 fp->ctf_buf, fp->ctf_size)) != Z_OK)
1373 ctf_set_errno (fp, ECTF_COMPRESS);
1374 ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
1375 free (buf);
1376 return NULL;
1378 *size += compress_len;
1380 return buf;
1383 /* Write the uncompressed CTF data stream to the specified file descriptor. */
1385 ctf_write (ctf_dict_t *fp, int fd)
1387 const unsigned char *buf;
1388 ssize_t resid;
1389 ssize_t len;
1391 if (ctf_serialize (fp) < 0)
1392 return -1; /* errno is set for us. */
1394 resid = sizeof (ctf_header_t);
1395 buf = (unsigned char *) fp->ctf_header;
1396 while (resid != 0)
1398 if ((len = write (fd, buf, resid)) <= 0)
1400 ctf_err_warn (fp, 0, errno, _("ctf_write: error writing header"));
1401 return (ctf_set_errno (fp, errno));
1403 resid -= len;
1404 buf += len;
1407 resid = fp->ctf_size;
1408 buf = fp->ctf_buf;
1409 while (resid != 0)
1411 if ((len = write (fd, buf, resid)) <= 0)
1413 ctf_err_warn (fp, 0, errno, _("ctf_write: error writing"));
1414 return (ctf_set_errno (fp, errno));
1416 resid -= len;
1417 buf += len;
1420 return 0;