xref: /netbsd-src/external/gpl3/gdb/dist/libctf/ctf-serialize.c (revision 4439cfd0acf9c7dc90625e5cd83b2317a9ab8967)
1 /* CTF dict creation.
2    Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 
4    This file is part of libctf.
5 
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.
10 
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.
15 
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/>.  */
19 
20 #include <ctf-impl.h>
21 #include <assert.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <zlib.h>
25 
26 #include <elf.h>
27 #include "elf-bfd.h"
28 
29 /* Symtypetab sections.  */
30 
31 /* Symtypetab emission flags.  */
32 
33 #define CTF_SYMTYPETAB_EMIT_FUNCTION 0x1
34 #define CTF_SYMTYPETAB_EMIT_PAD 0x2
35 #define CTF_SYMTYPETAB_FORCE_INDEXED 0x4
36 
37 /* Properties of symtypetab emission, shared by symtypetab section
38    sizing and symtypetab emission itself.  */
39 
40 typedef struct emit_symtypetab_state
41 {
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;
46 
47   /* True if symbols are being sorted.  */
48   int sort_syms;
49 
50   /* Flags for symtypetab emission.  */
51   int symflags;
52 
53   /* The dict to which the linker has reported symbols.  */
54   ctf_dict_t *symfp;
55 
56   /* The maximum number of objects seen.  */
57   size_t maxobjt;
58 
59   /* The maximum number of func info entris seen.  */
60   size_t maxfunc;
61 } emit_symtypetab_state_t;
62 
63 /* Determine if a symbol is "skippable" and should never appear in the
64    symtypetab sections.  */
65 
66 int
67 ctf_symtab_skippable (ctf_link_sym_t *sym)
68 {
69   /* Never skip symbols whose name is not yet known.  */
70   if (sym->st_nameidx_set)
71     return 0;
72 
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));
79 }
80 
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.
87 
88    Also figure out if any symbols need to be moved to the variable section, and
89    add them (if not already present).  */
90 
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)
96 {
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;
103 
104   *count = 0;
105   *max = 0;
106   *unpadsize = 0;
107   *idxsize = 0;
108   *padsize = 0;
109 
110   if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
111     {
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).
118 
119 	 If there are none, this symtypetab will be empty: just report that.  */
120 
121       if (!symfp->ctf_dynsyms)
122 	return 0;
123 
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));
127 
128       while ((err = ctf_dynhash_cnext (symfp->ctf_dynsyms, &i,
129 				       &name, &ctf_sym)) == 0)
130 	{
131 	  ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;
132 
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;
138 
139 	  if (ctf_symtab_skippable (sym))
140 	    continue;
141 
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.  */
146 
147 	  if (ctf_dynhash_cinsert (linker_known, name, ctf_sym) < 0)
148 	    {
149 	      ctf_dynhash_destroy (linker_known);
150 	      return (ctf_set_errno (fp, ENOMEM));
151 	    }
152 	}
153       if (err != ECTF_NEXT_END)
154 	{
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));
159 	}
160     }
161 
162   while ((err = ctf_dynhash_cnext (symhash, &i, &name, NULL)) == 0)
163     {
164       ctf_link_sym_t *sym;
165 
166       if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
167 	{
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)
171 	    {
172 	      ctf_dynhash_remove (symhash, name);
173 	      continue;
174 	    }
175 
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;
180 
181 	  if ((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
182 	      && sym->st_type != STT_FUNC)
183 	    {
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;
191 	    }
192 	  else if (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
193 		   && sym->st_type != STT_OBJECT)
194 	    {
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;
202 	    }
203 
204 	  ctf_dynhash_remove (linker_known, name);
205 
206 	  if (*max < sym->st_symidx)
207 	    *max = sym->st_symidx;
208 	}
209       else
210 	(*max)++;
211 
212       *unpadsize += sizeof (uint32_t);
213       (*count)++;
214     }
215   if (err != ECTF_NEXT_END)
216     {
217       ctf_err_warn (fp, 0, err, _("iterating over CTF symtypetab during "
218 				  "serialization"));
219       ctf_dynhash_destroy (linker_known);
220       return (ctf_set_errno (fp, err));
221     }
222 
223   if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
224     {
225       while ((err = ctf_dynhash_cnext (linker_known, &i, NULL, &ctf_sym)) == 0)
226 	{
227 	  ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;
228 
229 	  if (sym->st_symidx > *max)
230 	    beyond_max++;
231 	}
232       if (err != ECTF_NEXT_END)
233 	{
234 	  ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols "
235 				      "during CTF serialization"));
236 	  ctf_dynhash_destroy (linker_known);
237 	  return (ctf_set_errno (fp, err));
238 	}
239     }
240 
241   *idxsize = *count * sizeof (uint32_t);
242   if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
243     *padsize = (ctf_dynhash_elements (linker_known) - beyond_max) * sizeof (uint32_t);
244 
245   ctf_dynhash_destroy (linker_known);
246   return 0;
247 }
248 
249 /* Emit an objt or func symtypetab into DP in a particular order defined by an
250    array of ctf_link_sym_t or symbol names passed in.  The index has NIDX
251    elements in it: unindexed output would terminate at symbol OUTMAX and is in
252    any case no larger than SIZE bytes.  Some index elements are expected to be
253    skipped: see symtypetab_density.  The linker-reported set of symbols (if any)
254    is found in SYMFP. */
255 static int
256 emit_symtypetab (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
257 		 ctf_link_sym_t **idx, const char **nameidx, uint32_t nidx,
258 		 uint32_t outmax, int size, int flags)
259 {
260   uint32_t i;
261   uint32_t *dpp = dp;
262   ctf_dynhash_t *symhash;
263 
264   ctf_dprintf ("Emitting table of size %i, outmax %u, %u symtypetab entries, "
265 	       "flags %i\n", size, outmax, nidx, flags);
266 
267   /* Empty table? Nothing to do.  */
268   if (size == 0)
269     return 0;
270 
271   if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
272     symhash = fp->ctf_funchash;
273   else
274     symhash = fp->ctf_objthash;
275 
276   for (i = 0; i < nidx; i++)
277     {
278       const char *sym_name;
279       void *type;
280 
281       /* If we have a linker-reported set of symbols, we may be given that set
282 	 to work from, or a set of symbol names.  In both cases we want to look
283 	 at the corresponding linker-reported symbol (if any).  */
284       if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
285 	{
286 	  ctf_link_sym_t *this_link_sym;
287 
288 	  if (idx)
289 	    this_link_sym = idx[i];
290 	  else
291 	    this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, nameidx[i]);
292 
293 	  /* Unreported symbol number.  No pad, no nothing.  */
294 	  if (!this_link_sym)
295 	    continue;
296 
297 	  /* Symbol of the wrong type, or skippable?  This symbol is not in this
298 	     table.  */
299 	  if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
300 	       && this_link_sym->st_type != STT_FUNC)
301 	      || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
302 		  && this_link_sym->st_type != STT_OBJECT))
303 	    continue;
304 
305 	  if (ctf_symtab_skippable (this_link_sym))
306 	    continue;
307 
308 	  sym_name = this_link_sym->st_name;
309 
310 	  /* Linker reports symbol of a different type to the symbol we actually
311 	     added?  Skip the symbol.  No pad, since the symbol doesn't actually
312 	     belong in this table at all.  (Warned about in
313 	     symtypetab_density.)  */
314 	  if ((this_link_sym->st_type == STT_FUNC)
315 	      && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
316 	    continue;
317 
318 	  if ((this_link_sym->st_type == STT_OBJECT)
319 	      && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
320 	    continue;
321 	}
322       else
323 	sym_name = nameidx[i];
324 
325       /* Symbol in index but no type set? Silently skip and (optionally)
326 	 pad.  (In force-indexed mode, this is also where we track symbols of
327 	 the wrong type for this round of insertion.)  */
328       if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
329 	{
330 	  if (flags & CTF_SYMTYPETAB_EMIT_PAD)
331 	    *dpp++ = 0;
332 	  continue;
333 	}
334 
335       if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) < size))
336 	return -1;				/* errno is set for us.  */
337 
338       *dpp++ = (ctf_id_t) (uintptr_t) type;
339 
340       /* When emitting unindexed output, all later symbols are pads: stop
341 	 early.  */
342       if ((flags & CTF_SYMTYPETAB_EMIT_PAD) && idx[i]->st_symidx == outmax)
343 	break;
344     }
345 
346   return 0;
347 }
348 
349 /* Emit an objt or func symtypetab index into DP in a paticular order defined by
350    an array of symbol names passed in.  Stop at NIDX.  The linker-reported set
351    of symbols (if any) is found in SYMFP. */
352 static int
353 emit_symtypetab_index (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
354 		       const char **idx, uint32_t nidx, int size, int flags)
355 {
356   uint32_t i;
357   uint32_t *dpp = dp;
358   ctf_dynhash_t *symhash;
359 
360   ctf_dprintf ("Emitting index of size %i, %u entries reported by linker, "
361 	       "flags %i\n", size, nidx, flags);
362 
363   /* Empty table? Nothing to do.  */
364   if (size == 0)
365     return 0;
366 
367   if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
368     symhash = fp->ctf_funchash;
369   else
370     symhash = fp->ctf_objthash;
371 
372   /* Indexes should always be unpadded.  */
373   if (!ctf_assert (fp, !(flags & CTF_SYMTYPETAB_EMIT_PAD)))
374     return -1;					/* errno is set for us.  */
375 
376   for (i = 0; i < nidx; i++)
377     {
378       const char *sym_name;
379       void *type;
380 
381       if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
382 	{
383 	  ctf_link_sym_t *this_link_sym;
384 
385 	  this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, idx[i]);
386 
387 	  /* This is an index: unreported symbols should never appear in it.  */
388 	  if (!ctf_assert (fp, this_link_sym != NULL))
389 	    return -1;				/* errno is set for us.  */
390 
391 	  /* Symbol of the wrong type, or skippable?  This symbol is not in this
392 	     table.  */
393 	  if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
394 	       && this_link_sym->st_type != STT_FUNC)
395 	      || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
396 		  && this_link_sym->st_type != STT_OBJECT))
397 	    continue;
398 
399 	  if (ctf_symtab_skippable (this_link_sym))
400 	    continue;
401 
402 	  sym_name = this_link_sym->st_name;
403 
404 	  /* Linker reports symbol of a different type to the symbol we actually
405 	     added?  Skip the symbol.  */
406 	  if ((this_link_sym->st_type == STT_FUNC)
407 	      && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
408 	    continue;
409 
410 	  if ((this_link_sym->st_type == STT_OBJECT)
411 	      && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
412 	    continue;
413 	}
414       else
415 	sym_name = idx[i];
416 
417       /* Symbol in index and reported by linker, but no type set? Silently skip
418 	 and (optionally) pad.  (In force-indexed mode, this is also where we
419 	 track symbols of the wrong type for this round of insertion.)  */
420       if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
421 	continue;
422 
423       ctf_str_add_ref (fp, sym_name, dpp++);
424 
425       if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) <= size))
426 	return -1;				/* errno is set for us.  */
427     }
428 
429   return 0;
430 }
431 
432 /* Delete symbols that have been assigned names from the variable section.  Must
433    be called from within ctf_serialize, because that is the only place you can
434    safely delete variables without messing up ctf_rollback.  */
435 
436 static int
437 symtypetab_delete_nonstatics (ctf_dict_t *fp, ctf_dict_t *symfp)
438 {
439   ctf_dvdef_t *dvd, *nvd;
440   ctf_id_t type;
441 
442   for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
443     {
444       nvd = ctf_list_next (dvd);
445 
446       if ((((type = (ctf_id_t) (uintptr_t)
447 	     ctf_dynhash_lookup (fp->ctf_objthash, dvd->dvd_name)) > 0)
448 	   || (type = (ctf_id_t) (uintptr_t)
449 	       ctf_dynhash_lookup (fp->ctf_funchash, 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);
453     }
454 
455   return 0;
456 }
457 
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)
465 {
466   size_t nfuncs, nobjts;
467   size_t objt_unpadsize, func_unpadsize, objt_padsize, func_padsize;
468 
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 certainly 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 are in, since it only
476      iterates over symbols and does not use the ctf_lookup_by_symbol* API.)  */
477 
478   s->sort_syms = 1;
479   if (fp->ctf_flags & LCTF_LINKING)
480     {
481       s->filter_syms = !(fp->ctf_link_flags & CTF_LINK_NO_FILTER_REPORTED_SYMS);
482       if (!s->filter_syms)
483 	s->sort_syms = 0;
484     }
485 
486   /* Find the dict to which the linker has reported symbols, if any.  */
487 
488   if (s->filter_syms)
489     {
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;
494     }
495 
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;
502 
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;
507 
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.  */
511 
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.  */
516 
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);
521 
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.  */
526 
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);
531 
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.  */
542 
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))
547     {
548       *objt_size += objt_padsize;
549       *objtidx_size = 0;
550     }
551 
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))
556     {
557       *func_size += func_padsize;
558       *funcidx_size = 0;
559     }
560 
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
564      symbols.  There's no need to migrate new ones in: we do that (if necessary)
565      in ctf_link_deduplicating_variables.  */
566 
567   if (s->filter_syms && s->symfp->ctf_dynsyms &&
568       symtypetab_delete_nonstatics (fp, s->symfp) < 0)
569     return -1;
570 
571   return 0;
572 }
573 
574 static int
575 ctf_emit_symtypetab_sects (ctf_dict_t *fp, emit_symtypetab_state_t *s,
576 			   unsigned char **tptr, size_t objt_size,
577 			   size_t func_size, size_t objtidx_size,
578 			   size_t funcidx_size)
579 {
580   unsigned char *t = *tptr;
581   size_t nsymtypes = 0;
582   const char **sym_name_order = NULL;
583   int err;
584 
585   /* Sort the linker's symbols into name order if need be.  */
586 
587   if ((objtidx_size != 0) || (funcidx_size != 0))
588     {
589       ctf_next_t *i = NULL;
590       void *symname;
591       const char **walk;
592 
593       if (s->filter_syms)
594 	{
595 	  if (s->symfp->ctf_dynsyms)
596 	    nsymtypes = ctf_dynhash_elements (s->symfp->ctf_dynsyms);
597 	  else
598 	    nsymtypes = 0;
599 	}
600       else
601 	nsymtypes = ctf_dynhash_elements (fp->ctf_objthash)
602 	  + ctf_dynhash_elements (fp->ctf_funchash);
603 
604       if ((sym_name_order = calloc (nsymtypes, sizeof (const char *))) == NULL)
605 	goto oom;
606 
607       walk = sym_name_order;
608 
609       if (s->filter_syms)
610 	{
611 	  if (s->symfp->ctf_dynsyms)
612 	    {
613 	      while ((err = ctf_dynhash_next_sorted (s->symfp->ctf_dynsyms, &i,
614 						     &symname, NULL,
615 						     ctf_dynhash_sort_by_name,
616 						     NULL)) == 0)
617 		*walk++ = (const char *) symname;
618 	      if (err != ECTF_NEXT_END)
619 		goto symerr;
620 	    }
621 	}
622       else
623 	{
624 	  ctf_hash_sort_f sort_fun = NULL;
625 
626 	  /* Since we partition the set of symbols back into objt and func,
627 	     we can sort the two independently without harm.  */
628 	  if (s->sort_syms)
629 	    sort_fun = ctf_dynhash_sort_by_name;
630 
631 	  while ((err = ctf_dynhash_next_sorted (fp->ctf_objthash, &i, &symname,
632 						 NULL, sort_fun, NULL)) == 0)
633 	    *walk++ = (const char *) symname;
634 	  if (err != ECTF_NEXT_END)
635 	    goto symerr;
636 
637 	  while ((err = ctf_dynhash_next_sorted (fp->ctf_funchash, &i, &symname,
638 						 NULL, sort_fun, NULL)) == 0)
639 	    *walk++ = (const char *) symname;
640 	  if (err != ECTF_NEXT_END)
641 	    goto symerr;
642 	}
643     }
644 
645   /* Emit the object and function sections, and if necessary their indexes.
646      Emission is done in symtab order if there is no index, and in index
647      (name) order otherwise.  */
648 
649   if ((objtidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx)
650     {
651       ctf_dprintf ("Emitting unindexed objt symtypetab\n");
652       if (emit_symtypetab (fp, s->symfp, (uint32_t *) t,
653 			   s->symfp->ctf_dynsymidx, NULL,
654 			   s->symfp->ctf_dynsymmax + 1, s->maxobjt,
655 			   objt_size, s->symflags | CTF_SYMTYPETAB_EMIT_PAD) < 0)
656 	goto err;				/* errno is set for us.  */
657     }
658   else
659     {
660       ctf_dprintf ("Emitting indexed objt symtypetab\n");
661       if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL,
662 			   sym_name_order, nsymtypes, s->maxobjt,
663 			   objt_size, s->symflags) < 0)
664 	goto err;				/* errno is set for us.  */
665     }
666 
667   t += objt_size;
668 
669   if ((funcidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx)
670     {
671       ctf_dprintf ("Emitting unindexed func symtypetab\n");
672       if (emit_symtypetab (fp, s->symfp, (uint32_t *) t,
673 			   s->symfp->ctf_dynsymidx, NULL,
674 			   s->symfp->ctf_dynsymmax + 1, s->maxfunc,
675 			   func_size, s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION
676 			   | CTF_SYMTYPETAB_EMIT_PAD) < 0)
677 	goto err;				/* errno is set for us.  */
678     }
679   else
680     {
681       ctf_dprintf ("Emitting indexed func symtypetab\n");
682       if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL, sym_name_order,
683 			   nsymtypes, s->maxfunc, func_size,
684 			   s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
685 	goto err;				/* errno is set for us.  */
686     }
687 
688   t += func_size;
689 
690   if (objtidx_size > 0)
691     if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order,
692 			       nsymtypes, objtidx_size, s->symflags) < 0)
693       goto err;
694 
695   t += objtidx_size;
696 
697   if (funcidx_size > 0)
698     if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order,
699 			       nsymtypes, funcidx_size,
700 			       s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
701       goto err;
702 
703   t += funcidx_size;
704   free (sym_name_order);
705   *tptr = t;
706 
707   return 0;
708 
709  oom:
710   ctf_set_errno (fp, EAGAIN);
711   goto err;
712 symerr:
713   ctf_err_warn (fp, 0, err, _("error serializing symtypetabs"));
714  err:
715   free (sym_name_order);
716   return -1;
717 }
718 
719 /* Type section.  */
720 
721 /* Iterate through the static types and the dynamic type definition list and
722    compute the size of the CTF type section.  */
723 
724 static size_t
725 ctf_type_sect_size (ctf_dict_t *fp)
726 {
727   ctf_dtdef_t *dtd;
728   size_t type_size;
729 
730   for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
731        dtd != NULL; dtd = ctf_list_next (dtd))
732     {
733       uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
734       uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
735       size_t type_ctt_size = dtd->dtd_data.ctt_size;
736 
737       /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
738 	 if possible.  */
739 
740       if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
741 	{
742 	  size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);
743 
744 	  if (lsize <= CTF_MAX_SIZE)
745 	    type_ctt_size = lsize;
746 	}
747 
748       if (type_ctt_size != CTF_LSIZE_SENT)
749 	type_size += sizeof (ctf_stype_t);
750       else
751 	type_size += sizeof (ctf_type_t);
752 
753       switch (kind)
754 	{
755 	case CTF_K_INTEGER:
756 	case CTF_K_FLOAT:
757 	  type_size += sizeof (uint32_t);
758 	  break;
759 	case CTF_K_ARRAY:
760 	  type_size += sizeof (ctf_array_t);
761 	  break;
762 	case CTF_K_SLICE:
763 	  type_size += sizeof (ctf_slice_t);
764 	  break;
765 	case CTF_K_FUNCTION:
766 	  type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
767 	  break;
768 	case CTF_K_STRUCT:
769 	case CTF_K_UNION:
770 	  if (type_ctt_size < CTF_LSTRUCT_THRESH)
771 	    type_size += sizeof (ctf_member_t) * vlen;
772 	  else
773 	    type_size += sizeof (ctf_lmember_t) * vlen;
774 	  break;
775 	case CTF_K_ENUM:
776 	  type_size += sizeof (ctf_enum_t) * vlen;
777 	  break;
778 	}
779     }
780 
781   return type_size + fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff;
782 }
783 
784 /* Take a final lap through the dynamic type definition list and copy the
785    appropriate type records to the output buffer, noting down the strings as
786    we go.  */
787 
788 static void
789 ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr)
790 {
791   unsigned char *t = *tptr;
792   ctf_dtdef_t *dtd;
793 
794   for (dtd = ctf_list_next (&fp->ctf_dtdefs);
795        dtd != NULL; dtd = ctf_list_next (dtd))
796     {
797       uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
798       uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
799       size_t type_ctt_size = dtd->dtd_data.ctt_size;
800       size_t len;
801       ctf_stype_t *copied;
802       const char *name;
803       size_t i;
804 
805       /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
806 	 if possible.  */
807 
808       if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
809 	{
810 	  size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);
811 
812 	  if (lsize <= CTF_MAX_SIZE)
813 	    type_ctt_size = lsize;
814 	}
815 
816       if (type_ctt_size != CTF_LSIZE_SENT)
817 	len = sizeof (ctf_stype_t);
818       else
819 	len = sizeof (ctf_type_t);
820 
821       memcpy (t, &dtd->dtd_data, len);
822       copied = (ctf_stype_t *) t;  /* name is at the start: constant offset.  */
823       if (copied->ctt_name
824 	  && (name = ctf_strraw (fp, copied->ctt_name)) != NULL)
825         ctf_str_add_ref (fp, name, &copied->ctt_name);
826       copied->ctt_size = type_ctt_size;
827       t += len;
828 
829       switch (kind)
830 	{
831 	case CTF_K_INTEGER:
832 	case CTF_K_FLOAT:
833 	  memcpy (t, dtd->dtd_vlen, sizeof (uint32_t));
834 	  t += sizeof (uint32_t);
835 	  break;
836 
837 	case CTF_K_SLICE:
838 	  memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_slice));
839 	  t += sizeof (struct ctf_slice);
840 	  break;
841 
842 	case CTF_K_ARRAY:
843 	  memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_array));
844 	  t += sizeof (struct ctf_array);
845 	  break;
846 
847 	case CTF_K_FUNCTION:
848 	  /* Functions with no args also have no vlen.  */
849 	  if (dtd->dtd_vlen)
850 	    memcpy (t, dtd->dtd_vlen, sizeof (uint32_t) * (vlen + (vlen & 1)));
851 	  t += sizeof (uint32_t) * (vlen + (vlen & 1));
852 	  break;
853 
854 	  /* These need to be copied across element by element, depending on
855 	     their ctt_size.  */
856 	case CTF_K_STRUCT:
857 	case CTF_K_UNION:
858 	  {
859 	    ctf_lmember_t *dtd_vlen = (ctf_lmember_t *) dtd->dtd_vlen;
860 	    ctf_lmember_t *t_lvlen = (ctf_lmember_t *) t;
861 	    ctf_member_t *t_vlen = (ctf_member_t *) t;
862 
863 	    for (i = 0; i < vlen; i++)
864 	      {
865 		const char *name = ctf_strraw (fp, dtd_vlen[i].ctlm_name);
866 
867 		ctf_str_add_ref (fp, name, &dtd_vlen[i].ctlm_name);
868 
869 		if (type_ctt_size < CTF_LSTRUCT_THRESH)
870 		  {
871 		    t_vlen[i].ctm_name = dtd_vlen[i].ctlm_name;
872 		    t_vlen[i].ctm_type = dtd_vlen[i].ctlm_type;
873 		    t_vlen[i].ctm_offset = CTF_LMEM_OFFSET (&dtd_vlen[i]);
874 		    ctf_str_add_ref (fp, name, &t_vlen[i].ctm_name);
875 		  }
876 		else
877 		  {
878 		    t_lvlen[i] = dtd_vlen[i];
879 		    ctf_str_add_ref (fp, name, &t_lvlen[i].ctlm_name);
880 		  }
881 	      }
882 	  }
883 
884 	  if (type_ctt_size < CTF_LSTRUCT_THRESH)
885 	    t += sizeof (ctf_member_t) * vlen;
886 	  else
887 	    t += sizeof (ctf_lmember_t) * vlen;
888 	  break;
889 
890 	case CTF_K_ENUM:
891 	  {
892 	    ctf_enum_t *dtd_vlen = (struct ctf_enum *) dtd->dtd_vlen;
893 	    ctf_enum_t *t_vlen = (struct ctf_enum *) t;
894 
895 	    memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_enum) * vlen);
896 	    for (i = 0; i < vlen; i++)
897 	      {
898 		const char *name = ctf_strraw (fp, dtd_vlen[i].cte_name);
899 
900 		ctf_str_add_ref (fp, name, &t_vlen[i].cte_name);
901 		ctf_str_add_ref (fp, name, &dtd_vlen[i].cte_name);
902 	      }
903 	    t += sizeof (struct ctf_enum) * vlen;
904 
905 	    break;
906 	  }
907 	}
908     }
909 
910   *tptr = t;
911 }
912 
913 /* Variable section.  */
914 
915 /* Sort a newly-constructed static variable array.  */
916 
917 typedef struct ctf_sort_var_arg_cb
918 {
919   ctf_dict_t *fp;
920   ctf_strs_t *strtab;
921 } ctf_sort_var_arg_cb_t;
922 
923 static int
924 ctf_sort_var (const void *one_, const void *two_, void *arg_)
925 {
926   const ctf_varent_t *one = one_;
927   const ctf_varent_t *two = two_;
928   ctf_sort_var_arg_cb_t *arg = arg_;
929 
930   return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
931 		  ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
932 }
933 
934 /* Overall serialization.  */
935 
936 /* Emit a new CTF dict which is a serialized copy of this one: also reify
937    the string table and update all offsets in the current dict suitably.
938    (This simplifies ctf-string.c a little, at the cost of storing a second
939    copy of the strtab if this dict was originally read in via ctf_open.)
940 
941    Other aspects of the existing dict are unchanged, although some
942    static entries may be duplicated in the dynamic state (which should
943    have no effect on visible operation).  */
944 
945 static unsigned char *
946 ctf_serialize (ctf_dict_t *fp, size_t *bufsiz)
947 {
948   ctf_header_t hdr, *hdrp;
949   ctf_dvdef_t *dvd;
950   ctf_varent_t *dvarents;
951   const ctf_strs_writable_t *strtab;
952   int sym_functions = 0;
953 
954   unsigned char *t;
955   unsigned long i;
956   size_t buf_size, type_size, objt_size, func_size;
957   size_t funcidx_size, objtidx_size;
958   size_t nvars;
959   unsigned char *buf = NULL, *newbuf;
960 
961   emit_symtypetab_state_t symstate;
962   memset (&symstate, 0, sizeof (emit_symtypetab_state_t));
963 
964   /* Fill in an initial CTF header.  We will leave the label, object,
965      and function sections empty and only output a header, type section,
966      and string table.  The type section begins at a 4-byte aligned
967      boundary past the CTF header itself (at relative offset zero).  The flag
968      indicating a new-style function info section (an array of CTF_K_FUNCTION
969      type IDs in the types section) is flipped on.  */
970 
971   memset (&hdr, 0, sizeof (hdr));
972   hdr.cth_magic = CTF_MAGIC;
973   hdr.cth_version = CTF_VERSION;
974 
975   /* This is a new-format func info section, and the symtab and strtab come out
976      of the dynsym and dynstr these days.  */
977   hdr.cth_flags = (CTF_F_NEWFUNCINFO | CTF_F_DYNSTR);
978 
979   /* Propagate all symbols in the symtypetabs into the dynamic state, so that
980      we can put them back in the right order.  Symbols already in the dynamic
981      state, likely due to repeated serialization, are left unchanged.  */
982   do
983     {
984       ctf_next_t *it = NULL;
985       const char *sym_name;
986       ctf_id_t sym;
987 
988       while ((sym = ctf_symbol_next_static (fp, &it, &sym_name,
989 					    sym_functions)) != CTF_ERR)
990 	if ((ctf_add_funcobjt_sym_forced (fp, sym_functions, sym_name, sym)) < 0)
991 	  if (ctf_errno (fp) != ECTF_DUPLICATE)
992 	    return NULL;			/* errno is set for us.  */
993 
994       if (ctf_errno (fp) != ECTF_NEXT_END)
995 	return NULL;				/* errno is set for us.  */
996     } while (sym_functions++ < 1);
997 
998   /* Figure out how big the symtypetabs are now.  */
999 
1000   if (ctf_symtypetab_sect_sizes (fp, &symstate, &hdr, &objt_size, &func_size,
1001 				 &objtidx_size, &funcidx_size) < 0)
1002     return NULL;				/* errno is set for us.  */
1003 
1004   /* Propagate all vars into the dynamic state, so we can put them back later.
1005      Variables already in the dynamic state, likely due to repeated
1006      serialization, are left unchanged.  */
1007 
1008   for (i = 0; i < fp->ctf_nvars; i++)
1009     {
1010       const char *name = ctf_strptr (fp, fp->ctf_vars[i].ctv_name);
1011 
1012       if (name != NULL && !ctf_dvd_lookup (fp, name))
1013 	if (ctf_add_variable_forced (fp, name, fp->ctf_vars[i].ctv_type) < 0)
1014 	  return NULL;				/* errno is set for us.  */
1015     }
1016 
1017   for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
1018        dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
1019 
1020   type_size = ctf_type_sect_size (fp);
1021 
1022   /* Compute the size of the CTF buffer we need, sans only the string table,
1023      then allocate a new buffer and memcpy the finished header to the start of
1024      the buffer.  (We will adjust this later with strtab length info.)  */
1025 
1026   hdr.cth_lbloff = hdr.cth_objtoff = 0;
1027   hdr.cth_funcoff = hdr.cth_objtoff + objt_size;
1028   hdr.cth_objtidxoff = hdr.cth_funcoff + func_size;
1029   hdr.cth_funcidxoff = hdr.cth_objtidxoff + objtidx_size;
1030   hdr.cth_varoff = hdr.cth_funcidxoff + funcidx_size;
1031   hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
1032   hdr.cth_stroff = hdr.cth_typeoff + type_size;
1033   hdr.cth_strlen = 0;
1034 
1035   buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
1036 
1037   if ((buf = malloc (buf_size)) == NULL)
1038     {
1039       ctf_set_errno (fp, EAGAIN);
1040       return NULL;
1041     }
1042 
1043   memcpy (buf, &hdr, sizeof (ctf_header_t));
1044   t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_objtoff;
1045 
1046   hdrp = (ctf_header_t *) buf;
1047   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
1048     ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
1049   if (fp->ctf_cuname != NULL)
1050     ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);
1051 
1052   if (ctf_emit_symtypetab_sects (fp, &symstate, &t, objt_size, func_size,
1053 				 objtidx_size, funcidx_size) < 0)
1054     goto err;
1055 
1056   assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff);
1057 
1058   /* Work over the variable list, translating everything into ctf_varent_t's and
1059      prepping the string table.  */
1060 
1061   dvarents = (ctf_varent_t *) t;
1062   for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
1063        dvd = ctf_list_next (dvd), i++)
1064     {
1065       ctf_varent_t *var = &dvarents[i];
1066 
1067       ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
1068       var->ctv_type = (uint32_t) dvd->dvd_type;
1069     }
1070   assert (i == nvars);
1071 
1072   t += sizeof (ctf_varent_t) * nvars;
1073 
1074   assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
1075 
1076   /* Copy in existing static types, then emit new dynamic types.  */
1077 
1078   memcpy (t, fp->ctf_buf + fp->ctf_header->cth_typeoff,
1079 	  fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff);
1080   t += fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff;
1081   ctf_emit_type_sect (fp, &t);
1082 
1083   assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
1084 
1085   /* Construct the final string table and fill out all the string refs with the
1086      final offsets.  */
1087 
1088   strtab = ctf_str_write_strtab (fp);
1089 
1090   if (strtab == NULL)
1091     goto oom;
1092 
1093   /* Now the string table is constructed, we can sort the buffer of
1094      ctf_varent_t's.  */
1095   ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) strtab };
1096   ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
1097 	       &sort_var_arg);
1098 
1099   if ((newbuf = realloc (buf, buf_size + strtab->cts_len)) == NULL)
1100     goto oom;
1101 
1102   buf = newbuf;
1103   memcpy (buf + buf_size, strtab->cts_strs, strtab->cts_len);
1104   hdrp = (ctf_header_t *) buf;
1105   hdrp->cth_strlen = strtab->cts_len;
1106   buf_size += hdrp->cth_strlen;
1107   *bufsiz = buf_size;
1108 
1109   return buf;
1110 
1111 oom:
1112   ctf_set_errno (fp, EAGAIN);
1113 err:
1114   free (buf);
1115   return NULL;					/* errno is set for us.  */
1116 }
1117 
1118 /* File writing.  */
1119 
1120 /* Write the compressed CTF data stream to the specified gzFile descriptor.  The
1121    whole stream is compressed, and cannot be read by CTF opening functions in
1122    this library until it is decompressed.  (The functions below this one leave
1123    the header uncompressed, and the CTF opening functions work on them without
1124    manual decompression.)
1125 
1126    No support for (testing-only) endian-flipping.  */
1127 int
1128 ctf_gzwrite (ctf_dict_t *fp, gzFile fd)
1129 {
1130   unsigned char *buf;
1131   unsigned char *p;
1132   size_t bufsiz;
1133   size_t len, written = 0;
1134 
1135   if ((buf = ctf_serialize (fp, &bufsiz)) == NULL)
1136     return -1;					/* errno is set for us.  */
1137 
1138   p = buf;
1139   while (written < bufsiz)
1140     {
1141       if ((len = gzwrite (fd, p, bufsiz - written)) <= 0)
1142 	{
1143 	  free (buf);
1144 	  return (ctf_set_errno (fp, errno));
1145 	}
1146       written += len;
1147       p += len;
1148     }
1149 
1150   free (buf);
1151   return 0;
1152 }
1153 
1154 /* Optionally compress the specified CTF data stream and return it as a new
1155    dynamically-allocated string.  Possibly write it with reversed
1156    endianness.  */
1157 unsigned char *
1158 ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold)
1159 {
1160   unsigned char *rawbuf;
1161   unsigned char *buf = NULL;
1162   unsigned char *bp;
1163   ctf_header_t *rawhp, *hp;
1164   unsigned char *src;
1165   size_t rawbufsiz;
1166   size_t alloc_len = 0;
1167   int uncompressed = 0;
1168   int flip_endian;
1169   int rc;
1170 
1171   flip_endian = getenv ("LIBCTF_WRITE_FOREIGN_ENDIAN") != NULL;
1172 
1173   if ((rawbuf = ctf_serialize (fp, &rawbufsiz)) == NULL)
1174     return NULL;				/* errno is set for us.  */
1175 
1176   if (!ctf_assert (fp, rawbufsiz >= sizeof (ctf_header_t)))
1177     goto err;
1178 
1179   if (rawbufsiz >= threshold)
1180     alloc_len = compressBound (rawbufsiz - sizeof (ctf_header_t))
1181       + sizeof (ctf_header_t);
1182 
1183   /* Trivial operation if the buffer is incompressible or too small to bother
1184      compressing, and we're not doing a forced write-time flip.  */
1185 
1186   if (rawbufsiz < threshold || rawbufsiz < alloc_len)
1187     {
1188       alloc_len = rawbufsiz;
1189       uncompressed = 1;
1190     }
1191 
1192   if (!flip_endian && uncompressed)
1193     {
1194       *size = rawbufsiz;
1195       return rawbuf;
1196     }
1197 
1198   if ((buf = malloc (alloc_len)) == NULL)
1199     {
1200       ctf_set_errno (fp, ENOMEM);
1201       ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
1202 		    (unsigned long) (alloc_len));
1203       goto err;
1204     }
1205 
1206   rawhp = (ctf_header_t *) rawbuf;
1207   hp = (ctf_header_t *) buf;
1208   memcpy (hp, rawbuf, sizeof (ctf_header_t));
1209   bp = buf + sizeof (ctf_header_t);
1210   *size = sizeof (ctf_header_t);
1211 
1212   if (!uncompressed)
1213     hp->cth_flags |= CTF_F_COMPRESS;
1214 
1215   src = rawbuf + sizeof (ctf_header_t);
1216 
1217   if (flip_endian)
1218     {
1219       ctf_flip_header (hp);
1220       if (ctf_flip (fp, rawhp, src, 1) < 0)
1221 	goto err;				/* errno is set for us.  */
1222     }
1223 
1224   if (!uncompressed)
1225     {
1226       size_t compress_len = alloc_len - sizeof (ctf_header_t);
1227 
1228       if ((rc = compress (bp, (uLongf *) &compress_len,
1229 			  src, rawbufsiz - sizeof (ctf_header_t))) != Z_OK)
1230 	{
1231 	  ctf_set_errno (fp, ECTF_COMPRESS);
1232 	  ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
1233 	  goto err;
1234 	}
1235       *size += compress_len;
1236     }
1237   else
1238     {
1239       memcpy (bp, src, rawbufsiz - sizeof (ctf_header_t));
1240       *size += rawbufsiz - sizeof (ctf_header_t);
1241     }
1242 
1243   free (rawbuf);
1244   return buf;
1245 err:
1246   free (buf);
1247   free (rawbuf);
1248   return NULL;
1249 }
1250 
1251 /* Compress the specified CTF data stream and write it to the specified file
1252    descriptor.  */
1253 int
1254 ctf_compress_write (ctf_dict_t *fp, int fd)
1255 {
1256   unsigned char *buf;
1257   unsigned char *bp;
1258   size_t tmp;
1259   ssize_t buf_len;
1260   ssize_t len;
1261   int err = 0;
1262 
1263   if ((buf = ctf_write_mem (fp, &tmp, 0)) == NULL)
1264     return -1;					/* errno is set for us.  */
1265 
1266   buf_len = tmp;
1267   bp = buf;
1268 
1269   while (buf_len > 0)
1270     {
1271       if ((len = write (fd, bp, buf_len)) < 0)
1272 	{
1273 	  err = ctf_set_errno (fp, errno);
1274 	  ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
1275 	  goto ret;
1276 	}
1277       buf_len -= len;
1278       bp += len;
1279     }
1280 
1281 ret:
1282   free (buf);
1283   return err;
1284 }
1285 
1286 /* Write the uncompressed CTF data stream to the specified file descriptor.  */
1287 int
1288 ctf_write (ctf_dict_t *fp, int fd)
1289 {
1290   unsigned char *buf;
1291   unsigned char *bp;
1292   size_t tmp;
1293   ssize_t buf_len;
1294   ssize_t len;
1295   int err = 0;
1296 
1297   if ((buf = ctf_write_mem (fp, &tmp, (size_t) -1)) == NULL)
1298     return -1;					/* errno is set for us.  */
1299 
1300   buf_len = tmp;
1301   bp = buf;
1302 
1303   while (buf_len > 0)
1304     {
1305       if ((len = write (fd, bp, buf_len)) < 0)
1306 	{
1307 	  err = ctf_set_errno (fp, errno);
1308 	  ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
1309 	  goto ret;
1310 	}
1311       buf_len -= len;
1312       bp += len;
1313     }
1314 
1315 ret:
1316   free (buf);
1317   return err;
1318 }
1319