/* CTF dict creation.
   Copyright (C) 2019-2024 Free Software Foundation, Inc.

   This file is part of libctf.

   libctf is free software; you can redistribute it and/or modify it under
   the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3, or (at your option) any later
   version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not see
   <http://www.gnu.org/licenses/>.  */

#include <ctf-impl.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>

#include <elf.h>
#include "elf-bfd.h"

/* Symtypetab sections.  */

/* Symtypetab emission flags.  */

#define CTF_SYMTYPETAB_EMIT_FUNCTION 0x1
#define CTF_SYMTYPETAB_EMIT_PAD 0x2
#define CTF_SYMTYPETAB_FORCE_INDEXED 0x4

/* Properties of symtypetab emission, shared by symtypetab section
   sizing and symtypetab emission itself.  */

typedef struct emit_symtypetab_state
{
  /* True if linker-reported symbols are being filtered out.  symfp is set if
     this is true: otherwise, indexing is forced and the symflags indicate as
     much. */
  int filter_syms;

  /* True if symbols are being sorted.  */
  int sort_syms;

  /* Flags for symtypetab emission.  */
  int symflags;

  /* The dict to which the linker has reported symbols.  */
  ctf_dict_t *symfp;

  /* The maximum number of objects seen.  */
  size_t maxobjt;

  /* The maximum number of func info entris seen.  */
  size_t maxfunc;
} emit_symtypetab_state_t;

/* Determine if a symbol is "skippable" and should never appear in the
   symtypetab sections.  */

int
ctf_symtab_skippable (ctf_link_sym_t *sym)
{
  /* Never skip symbols whose name is not yet known.  */
  if (sym->st_nameidx_set)
    return 0;

  return (sym->st_name == NULL || sym->st_name[0] == 0
	  || sym->st_shndx == SHN_UNDEF
	  || strcmp (sym->st_name, "_START_") == 0
	  || strcmp (sym->st_name, "_END_") == 0
	  || (sym->st_type == STT_OBJECT && sym->st_shndx == SHN_EXTABS
	      && sym->st_value == 0));
}

/* Get the number of symbols in a symbol hash, the count of symbols, the maximum
   seen, the eventual size, without any padding elements, of the func/data and
   (if generated) index sections, and the size of accumulated padding elements.
   The linker-reported set of symbols is found in SYMFP: it may be NULL if
   symbol filtering is not desired, in which case CTF_SYMTYPETAB_FORCE_INDEXED
   will always be set in the flags.

   Also figure out if any symbols need to be moved to the variable section, and
   add them (if not already present).  */

_libctf_nonnull_ ((1,3,4,5,6,7,8))
static int
symtypetab_density (ctf_dict_t *fp, ctf_dict_t *symfp, ctf_dynhash_t *symhash,
		    size_t *count, size_t *max, size_t *unpadsize,
		    size_t *padsize, size_t *idxsize, int flags)
{
  ctf_next_t *i = NULL;
  const void *name;
  const void *ctf_sym;
  ctf_dynhash_t *linker_known = NULL;
  int err;
  int beyond_max = 0;

  *count = 0;
  *max = 0;
  *unpadsize = 0;
  *idxsize = 0;
  *padsize = 0;

  if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
    {
      /* Make a dynhash citing only symbols reported by the linker of the
	 appropriate type, then traverse all potential-symbols we know the types
	 of, removing them from linker_known as we go.  Once this is done, the
	 only symbols remaining in linker_known are symbols we don't know the
	 types of: we must emit pads for those symbols that are below the
	 maximum symbol we will emit (any beyond that are simply skipped).

	 If there are none, this symtypetab will be empty: just report that.  */

      if (!symfp->ctf_dynsyms)
	return 0;

      if ((linker_known = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
					      NULL, NULL)) == NULL)
	return (ctf_set_errno (fp, ENOMEM));

      while ((err = ctf_dynhash_cnext (symfp->ctf_dynsyms, &i,
				       &name, &ctf_sym)) == 0)
	{
	  ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;

	  if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
	       && sym->st_type != STT_FUNC)
	      || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
		  && sym->st_type != STT_OBJECT))
	    continue;

	  if (ctf_symtab_skippable (sym))
	    continue;

	  /* This should only be true briefly before all the names are
	     finalized, long before we get this far.  */
	  if (!ctf_assert (fp, !sym->st_nameidx_set))
	    return -1;				/* errno is set for us.  */

	  if (ctf_dynhash_cinsert (linker_known, name, ctf_sym) < 0)
	    {
	      ctf_dynhash_destroy (linker_known);
	      return (ctf_set_errno (fp, ENOMEM));
	    }
	}
      if (err != ECTF_NEXT_END)
	{
	  ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols during "
				  "serialization"));
	  ctf_dynhash_destroy (linker_known);
	  return (ctf_set_errno (fp, err));
	}
    }

  while ((err = ctf_dynhash_cnext (symhash, &i, &name, NULL)) == 0)
    {
      ctf_link_sym_t *sym;

      if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
	{
	  /* Linker did not report symbol in symtab.  Remove it from the
	     set of known data symbols and continue.  */
	  if ((sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, name)) == NULL)
	    {
	      ctf_dynhash_remove (symhash, name);
	      continue;
	    }

	  /* We don't remove skippable symbols from the symhash because we don't
	     want them to be migrated into variables.  */
	  if (ctf_symtab_skippable (sym))
	    continue;

	  if ((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
	      && sym->st_type != STT_FUNC)
	    {
	      ctf_err_warn (fp, 1, 0, _("symbol %s (%x) added to CTF as a "
					"function but is of type %x.  "
					"The symbol type lookup tables "
					"are probably corrupted"),
			    sym->st_name, sym->st_symidx, sym->st_type);
	      ctf_dynhash_remove (symhash, name);
	      continue;
	    }
	  else if (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
		   && sym->st_type != STT_OBJECT)
	    {
	      ctf_err_warn (fp, 1, 0, _("symbol %s (%x) added to CTF as a "
					"data object but is of type %x.  "
					"The symbol type lookup tables "
					"are probably corrupted"),
			    sym->st_name, sym->st_symidx, sym->st_type);
	      ctf_dynhash_remove (symhash, name);
	      continue;
	    }

	  ctf_dynhash_remove (linker_known, name);

	  if (*max < sym->st_symidx)
	    *max = sym->st_symidx;
	}
      else
	(*max)++;

      *unpadsize += sizeof (uint32_t);
      (*count)++;
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (fp, 0, err, _("iterating over CTF symtypetab during "
				  "serialization"));
      ctf_dynhash_destroy (linker_known);
      return (ctf_set_errno (fp, err));
    }

  if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
    {
      while ((err = ctf_dynhash_cnext (linker_known, &i, NULL, &ctf_sym)) == 0)
	{
	  ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;

	  if (sym->st_symidx > *max)
	    beyond_max++;
	}
      if (err != ECTF_NEXT_END)
	{
	  ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols "
				      "during CTF serialization"));
	  ctf_dynhash_destroy (linker_known);
	  return (ctf_set_errno (fp, err));
	}
    }

  *idxsize = *count * sizeof (uint32_t);
  if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
    *padsize = (ctf_dynhash_elements (linker_known) - beyond_max) * sizeof (uint32_t);

  ctf_dynhash_destroy (linker_known);
  return 0;
}

/* Emit an objt or func symtypetab into DP in a particular order defined by an
   array of ctf_link_sym_t or symbol names passed in.  The index has NIDX
   elements in it: unindexed output would terminate at symbol OUTMAX and is in
   any case no larger than SIZE bytes.  Some index elements are expected to be
   skipped: see symtypetab_density.  The linker-reported set of symbols (if any)
   is found in SYMFP. */
static int
emit_symtypetab (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
		 ctf_link_sym_t **idx, const char **nameidx, uint32_t nidx,
		 uint32_t outmax, int size, int flags)
{
  uint32_t i;
  uint32_t *dpp = dp;
  ctf_dynhash_t *symhash;

  ctf_dprintf ("Emitting table of size %i, outmax %u, %u symtypetab entries, "
	       "flags %i\n", size, outmax, nidx, flags);

  /* Empty table? Nothing to do.  */
  if (size == 0)
    return 0;

  if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
    symhash = fp->ctf_funchash;
  else
    symhash = fp->ctf_objthash;

  for (i = 0; i < nidx; i++)
    {
      const char *sym_name;
      void *type;

      /* If we have a linker-reported set of symbols, we may be given that set
	 to work from, or a set of symbol names.  In both cases we want to look
	 at the corresponding linker-reported symbol (if any).  */
      if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
	{
	  ctf_link_sym_t *this_link_sym;

	  if (idx)
	    this_link_sym = idx[i];
	  else
	    this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, nameidx[i]);

	  /* Unreported symbol number.  No pad, no nothing.  */
	  if (!this_link_sym)
	    continue;

	  /* Symbol of the wrong type, or skippable?  This symbol is not in this
	     table.  */
	  if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
	       && this_link_sym->st_type != STT_FUNC)
	      || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
		  && this_link_sym->st_type != STT_OBJECT))
	    continue;

	  if (ctf_symtab_skippable (this_link_sym))
	    continue;

	  sym_name = this_link_sym->st_name;

	  /* Linker reports symbol of a different type to the symbol we actually
	     added?  Skip the symbol.  No pad, since the symbol doesn't actually
	     belong in this table at all.  (Warned about in
	     symtypetab_density.)  */
	  if ((this_link_sym->st_type == STT_FUNC)
	      && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
	    continue;

	  if ((this_link_sym->st_type == STT_OBJECT)
	      && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
	    continue;
	}
      else
	sym_name = nameidx[i];

      /* Symbol in index but no type set? Silently skip and (optionally)
	 pad.  (In force-indexed mode, this is also where we track symbols of
	 the wrong type for this round of insertion.)  */
      if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
	{
	  if (flags & CTF_SYMTYPETAB_EMIT_PAD)
	    *dpp++ = 0;
	  continue;
	}

      if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) < size))
	return -1;				/* errno is set for us.  */

      *dpp++ = (ctf_id_t) (uintptr_t) type;

      /* When emitting unindexed output, all later symbols are pads: stop
	 early.  */
      if ((flags & CTF_SYMTYPETAB_EMIT_PAD) && idx[i]->st_symidx == outmax)
	break;
    }

  return 0;
}

/* Emit an objt or func symtypetab index into DP in a paticular order defined by
   an array of symbol names passed in.  Stop at NIDX.  The linker-reported set
   of symbols (if any) is found in SYMFP. */
static int
emit_symtypetab_index (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
		       const char **idx, uint32_t nidx, int size, int flags)
{
  uint32_t i;
  uint32_t *dpp = dp;
  ctf_dynhash_t *symhash;

  ctf_dprintf ("Emitting index of size %i, %u entries reported by linker, "
	       "flags %i\n", size, nidx, flags);

  /* Empty table? Nothing to do.  */
  if (size == 0)
    return 0;

  if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
    symhash = fp->ctf_funchash;
  else
    symhash = fp->ctf_objthash;

  /* Indexes should always be unpadded.  */
  if (!ctf_assert (fp, !(flags & CTF_SYMTYPETAB_EMIT_PAD)))
    return -1;					/* errno is set for us.  */

  for (i = 0; i < nidx; i++)
    {
      const char *sym_name;
      void *type;

      if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
	{
	  ctf_link_sym_t *this_link_sym;

	  this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, idx[i]);

	  /* This is an index: unreported symbols should never appear in it.  */
	  if (!ctf_assert (fp, this_link_sym != NULL))
	    return -1;				/* errno is set for us.  */

	  /* Symbol of the wrong type, or skippable?  This symbol is not in this
	     table.  */
	  if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
	       && this_link_sym->st_type != STT_FUNC)
	      || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
		  && this_link_sym->st_type != STT_OBJECT))
	    continue;

	  if (ctf_symtab_skippable (this_link_sym))
	    continue;

	  sym_name = this_link_sym->st_name;

	  /* Linker reports symbol of a different type to the symbol we actually
	     added?  Skip the symbol.  */
	  if ((this_link_sym->st_type == STT_FUNC)
	      && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
	    continue;

	  if ((this_link_sym->st_type == STT_OBJECT)
	      && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
	    continue;
	}
      else
	sym_name = idx[i];

      /* Symbol in index and reported by linker, but no type set? Silently skip
	 and (optionally) pad.  (In force-indexed mode, this is also where we
	 track symbols of the wrong type for this round of insertion.)  */
      if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
	continue;

      ctf_str_add_ref (fp, sym_name, dpp++);

      if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) <= size))
	return -1;				/* errno is set for us.  */
    }

  return 0;
}

/* Delete symbols that have been assigned names from the variable section.  Must
   be called from within ctf_serialize, because that is the only place you can
   safely delete variables without messing up ctf_rollback.  */

static int
symtypetab_delete_nonstatics (ctf_dict_t *fp, ctf_dict_t *symfp)
{
  ctf_dvdef_t *dvd, *nvd;
  ctf_id_t type;

  for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
    {
      nvd = ctf_list_next (dvd);

      if ((((type = (ctf_id_t) (uintptr_t)
	     ctf_dynhash_lookup (fp->ctf_objthash, dvd->dvd_name)) > 0)
	   || (type = (ctf_id_t) (uintptr_t)
	       ctf_dynhash_lookup (fp->ctf_funchash, dvd->dvd_name)) > 0)
	  && ctf_dynhash_lookup (symfp->ctf_dynsyms, dvd->dvd_name) != NULL
	  && type == dvd->dvd_type)
	ctf_dvd_delete (fp, dvd);
    }

  return 0;
}

/* Figure out the sizes of the symtypetab sections, their indexed state,
   etc.  */
static int
ctf_symtypetab_sect_sizes (ctf_dict_t *fp, emit_symtypetab_state_t *s,
			   ctf_header_t *hdr, size_t *objt_size,
			   size_t *func_size, size_t *objtidx_size,
			   size_t *funcidx_size)
{
  size_t nfuncs, nobjts;
  size_t objt_unpadsize, func_unpadsize, objt_padsize, func_padsize;

  /* If doing a writeout as part of linking, and the link flags request it,
     filter out reported symbols from the variable section, and filter out all
     other symbols from the symtypetab sections.  (If we are not linking, the
     symbols are sorted; if we are linking, don't bother sorting if we are not
     filtering out reported symbols: this is almost certaily an ld -r and only
     the linker is likely to consume these symtypetabs again.  The linker
     doesn't care what order the symtypetab entries is in, since it only
     iterates over symbols and does not use the ctf_lookup_by_symbol* API.)  */

  s->sort_syms = 1;
  if (fp->ctf_flags & LCTF_LINKING)
    {
      s->filter_syms = !(fp->ctf_link_flags & CTF_LINK_NO_FILTER_REPORTED_SYMS);
      if (!s->filter_syms)
	s->sort_syms = 0;
    }

  /* Find the dict to which the linker has reported symbols, if any.  */

  if (s->filter_syms)
    {
      if (!fp->ctf_dynsyms && fp->ctf_parent && fp->ctf_parent->ctf_dynsyms)
	s->symfp = fp->ctf_parent;
      else
	s->symfp = fp;
    }

  /* If not filtering, keep all potential symbols in an unsorted, indexed
     dict.  */
  if (!s->filter_syms)
    s->symflags = CTF_SYMTYPETAB_FORCE_INDEXED;
  else
    hdr->cth_flags |= CTF_F_IDXSORTED;

  if (!ctf_assert (fp, (s->filter_syms && s->symfp)
		   || (!s->filter_syms && !s->symfp
		       && ((s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED) != 0))))
    return -1;

  /* Work out the sizes of the object and function sections, and work out the
     number of pad (unassigned) symbols in each, and the overall size of the
     sections.  */

  if (symtypetab_density (fp, s->symfp, fp->ctf_objthash, &nobjts, &s->maxobjt,
			  &objt_unpadsize, &objt_padsize, objtidx_size,
			  s->symflags) < 0)
    return -1;					/* errno is set for us.  */

  ctf_dprintf ("Object symtypetab: %i objects, max %i, unpadded size %i, "
	       "%i bytes of pads, index size %i\n", (int) nobjts,
	       (int) s->maxobjt, (int) objt_unpadsize, (int) objt_padsize,
	       (int) *objtidx_size);

  if (symtypetab_density (fp, s->symfp, fp->ctf_funchash, &nfuncs, &s->maxfunc,
			  &func_unpadsize, &func_padsize, funcidx_size,
			  s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
    return -1;					/* errno is set for us.  */

  ctf_dprintf ("Function symtypetab: %i functions, max %i, unpadded size %i, "
	       "%i bytes of pads, index size %i\n", (int) nfuncs,
	       (int) s->maxfunc, (int) func_unpadsize, (int) func_padsize,
	       (int) *funcidx_size);

  /* It is worth indexing each section if it would save space to do so, due to
     reducing the number of pads sufficiently.  A pad is the same size as a
     single index entry: but index sections compress relatively poorly compared
     to constant pads, so it takes a lot of contiguous padding to equal one
     index section entry.  It would be nice to be able to *verify* whether we
     would save space after compression rather than guessing, but this seems
     difficult, since it would require complete reserialization.  Regardless, if
     the linker has not reported any symbols (e.g. if this is not a final link
     but just an ld -r), we must emit things in indexed fashion just as the
     compiler does.  */

  *objt_size = objt_unpadsize;
  if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
      && ((objt_padsize + objt_unpadsize) * CTF_INDEX_PAD_THRESHOLD
	  > objt_padsize))
    {
      *objt_size += objt_padsize;
      *objtidx_size = 0;
    }

  *func_size = func_unpadsize;
  if (!(s->symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
      && ((func_padsize + func_unpadsize) * CTF_INDEX_PAD_THRESHOLD
	  > func_padsize))
    {
      *func_size += func_padsize;
      *funcidx_size = 0;
    }

  /* If we are filtering symbols out, those symbols that the linker has not
     reported have now been removed from the ctf_objthash and ctf_funchash.
     Delete entries from the variable section that duplicate newly-added
     symbols.  There's no need to migrate new ones in: we do that (if necessary)
     in ctf_link_deduplicating_variables.  */

  if (s->filter_syms && s->symfp->ctf_dynsyms &&
      symtypetab_delete_nonstatics (fp, s->symfp) < 0)
    return -1;

  return 0;
}

static int
ctf_emit_symtypetab_sects (ctf_dict_t *fp, emit_symtypetab_state_t *s,
			   unsigned char **tptr, size_t objt_size,
			   size_t func_size, size_t objtidx_size,
			   size_t funcidx_size)
{
  unsigned char *t = *tptr;
  size_t nsymtypes = 0;
  const char **sym_name_order = NULL;
  int err;

  /* Sort the linker's symbols into name order if need be.  */

  if ((objtidx_size != 0) || (funcidx_size != 0))
    {
      ctf_next_t *i = NULL;
      void *symname;
      const char **walk;

      if (s->filter_syms)
	{
	  if (s->symfp->ctf_dynsyms)
	    nsymtypes = ctf_dynhash_elements (s->symfp->ctf_dynsyms);
	  else
	    nsymtypes = 0;
	}
      else
	nsymtypes = ctf_dynhash_elements (fp->ctf_objthash)
	  + ctf_dynhash_elements (fp->ctf_funchash);

      if ((sym_name_order = calloc (nsymtypes, sizeof (const char *))) == NULL)
	goto oom;

      walk = sym_name_order;

      if (s->filter_syms)
	{
	  if (s->symfp->ctf_dynsyms)
	    {
	      while ((err = ctf_dynhash_next_sorted (s->symfp->ctf_dynsyms, &i,
						     &symname, NULL,
						     ctf_dynhash_sort_by_name,
						     NULL)) == 0)
		*walk++ = (const char *) symname;
	      if (err != ECTF_NEXT_END)
		goto symerr;
	    }
	}
      else
	{
	  ctf_hash_sort_f sort_fun = NULL;

	  /* Since we partition the set of symbols back into objt and func,
	     we can sort the two independently without harm.  */
	  if (s->sort_syms)
	    sort_fun = ctf_dynhash_sort_by_name;

	  while ((err = ctf_dynhash_next_sorted (fp->ctf_objthash, &i, &symname,
						 NULL, sort_fun, NULL)) == 0)
	    *walk++ = (const char *) symname;
	  if (err != ECTF_NEXT_END)
	    goto symerr;

	  while ((err = ctf_dynhash_next_sorted (fp->ctf_funchash, &i, &symname,
						 NULL, sort_fun, NULL)) == 0)
	    *walk++ = (const char *) symname;
	  if (err != ECTF_NEXT_END)
	    goto symerr;
	}
    }

  /* Emit the object and function sections, and if necessary their indexes.
     Emission is done in symtab order if there is no index, and in index
     (name) order otherwise.  */

  if ((objtidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx)
    {
      ctf_dprintf ("Emitting unindexed objt symtypetab\n");
      if (emit_symtypetab (fp, s->symfp, (uint32_t *) t,
			   s->symfp->ctf_dynsymidx, NULL,
			   s->symfp->ctf_dynsymmax + 1, s->maxobjt,
			   objt_size, s->symflags | CTF_SYMTYPETAB_EMIT_PAD) < 0)
	goto err;				/* errno is set for us.  */
    }
  else
    {
      ctf_dprintf ("Emitting indexed objt symtypetab\n");
      if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL,
			   sym_name_order, nsymtypes, s->maxobjt,
			   objt_size, s->symflags) < 0)
	goto err;				/* errno is set for us.  */
    }

  t += objt_size;

  if ((funcidx_size == 0) && s->symfp && s->symfp->ctf_dynsymidx)
    {
      ctf_dprintf ("Emitting unindexed func symtypetab\n");
      if (emit_symtypetab (fp, s->symfp, (uint32_t *) t,
			   s->symfp->ctf_dynsymidx, NULL,
			   s->symfp->ctf_dynsymmax + 1, s->maxfunc,
			   func_size, s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION
			   | CTF_SYMTYPETAB_EMIT_PAD) < 0)
	goto err;				/* errno is set for us.  */
    }
  else
    {
      ctf_dprintf ("Emitting indexed func symtypetab\n");
      if (emit_symtypetab (fp, s->symfp, (uint32_t *) t, NULL, sym_name_order,
			   nsymtypes, s->maxfunc, func_size,
			   s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
	goto err;				/* errno is set for us.  */
    }

  t += func_size;

  if (objtidx_size > 0)
    if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order,
			       nsymtypes, objtidx_size, s->symflags) < 0)
      goto err;

  t += objtidx_size;

  if (funcidx_size > 0)
    if (emit_symtypetab_index (fp, s->symfp, (uint32_t *) t, sym_name_order,
			       nsymtypes, funcidx_size,
			       s->symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
      goto err;

  t += funcidx_size;
  free (sym_name_order);
  *tptr = t;

  return 0;

 oom:
  ctf_set_errno (fp, EAGAIN);
  goto err;
symerr:
  ctf_err_warn (fp, 0, err, _("error serializing symtypetabs"));
 err:
  free (sym_name_order);
  return -1;
}

/* Type section.  */

/* Iterate through the dynamic type definition list and compute the
   size of the CTF type section.  */

static size_t
ctf_type_sect_size (ctf_dict_t *fp)
{
  ctf_dtdef_t *dtd;
  size_t type_size;

  for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
       dtd != NULL; dtd = ctf_list_next (dtd))
    {
      uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
      uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
      size_t type_ctt_size = dtd->dtd_data.ctt_size;

      /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
	 if possible.  */

      if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
	{
	  size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);

	  if (lsize <= CTF_MAX_SIZE)
	    type_ctt_size = lsize;
	}

      if (type_ctt_size != CTF_LSIZE_SENT)
	type_size += sizeof (ctf_stype_t);
      else
	type_size += sizeof (ctf_type_t);

      switch (kind)
	{
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	  type_size += sizeof (uint32_t);
	  break;
	case CTF_K_ARRAY:
	  type_size += sizeof (ctf_array_t);
	  break;
	case CTF_K_SLICE:
	  type_size += sizeof (ctf_slice_t);
	  break;
	case CTF_K_FUNCTION:
	  type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
	  break;
	case CTF_K_STRUCT:
	case CTF_K_UNION:
	  if (type_ctt_size < CTF_LSTRUCT_THRESH)
	    type_size += sizeof (ctf_member_t) * vlen;
	  else
	    type_size += sizeof (ctf_lmember_t) * vlen;
	  break;
	case CTF_K_ENUM:
	  type_size += sizeof (ctf_enum_t) * vlen;
	  break;
	}
    }

  return type_size;
}

/* Take a final lap through the dynamic type definition list and copy the
   appropriate type records to the output buffer, noting down the strings as
   we go.  */

static void
ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr)
{
  unsigned char *t = *tptr;
  ctf_dtdef_t *dtd;

  for (dtd = ctf_list_next (&fp->ctf_dtdefs);
       dtd != NULL; dtd = ctf_list_next (dtd))
    {
      uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
      uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
      size_t type_ctt_size = dtd->dtd_data.ctt_size;
      size_t len;
      ctf_stype_t *copied;
      const char *name;
      size_t i;

      /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
	 if possible.  */

      if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
	{
	  size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);

	  if (lsize <= CTF_MAX_SIZE)
	    type_ctt_size = lsize;
	}

      if (type_ctt_size != CTF_LSIZE_SENT)
	len = sizeof (ctf_stype_t);
      else
	len = sizeof (ctf_type_t);

      memcpy (t, &dtd->dtd_data, len);
      copied = (ctf_stype_t *) t;  /* name is at the start: constant offset.  */
      if (copied->ctt_name
	  && (name = ctf_strraw (fp, copied->ctt_name)) != NULL)
	{
	  ctf_str_add_ref (fp, name, &copied->ctt_name);
	  ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
	}
      copied->ctt_size = type_ctt_size;
      t += len;

      switch (kind)
	{
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	  memcpy (t, dtd->dtd_vlen, sizeof (uint32_t));
	  t += sizeof (uint32_t);
	  break;

	case CTF_K_SLICE:
	  memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_slice));
	  t += sizeof (struct ctf_slice);
	  break;

	case CTF_K_ARRAY:
	  memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_array));
	  t += sizeof (struct ctf_array);
	  break;

	case CTF_K_FUNCTION:
	  /* Functions with no args also have no vlen.  */
	  if (dtd->dtd_vlen)
	    memcpy (t, dtd->dtd_vlen, sizeof (uint32_t) * (vlen + (vlen & 1)));
	  t += sizeof (uint32_t) * (vlen + (vlen & 1));
	  break;

	  /* These need to be copied across element by element, depending on
	     their ctt_size.  */
	case CTF_K_STRUCT:
	case CTF_K_UNION:
	  {
	    ctf_lmember_t *dtd_vlen = (ctf_lmember_t *) dtd->dtd_vlen;
	    ctf_lmember_t *t_lvlen = (ctf_lmember_t *) t;
	    ctf_member_t *t_vlen = (ctf_member_t *) t;

	    for (i = 0; i < vlen; i++)
	      {
		const char *name = ctf_strraw (fp, dtd_vlen[i].ctlm_name);

		ctf_str_add_ref (fp, name, &dtd_vlen[i].ctlm_name);

		if (type_ctt_size < CTF_LSTRUCT_THRESH)
		  {
		    t_vlen[i].ctm_name = dtd_vlen[i].ctlm_name;
		    t_vlen[i].ctm_type = dtd_vlen[i].ctlm_type;
		    t_vlen[i].ctm_offset = CTF_LMEM_OFFSET (&dtd_vlen[i]);
		    ctf_str_add_ref (fp, name, &t_vlen[i].ctm_name);
		  }
		else
		  {
		    t_lvlen[i] = dtd_vlen[i];
		    ctf_str_add_ref (fp, name, &t_lvlen[i].ctlm_name);
		  }
	      }
	  }

	  if (type_ctt_size < CTF_LSTRUCT_THRESH)
	    t += sizeof (ctf_member_t) * vlen;
	  else
	    t += sizeof (ctf_lmember_t) * vlen;
	  break;

	case CTF_K_ENUM:
	  {
	    ctf_enum_t *dtd_vlen = (struct ctf_enum *) dtd->dtd_vlen;
	    ctf_enum_t *t_vlen = (struct ctf_enum *) t;

	    memcpy (t, dtd->dtd_vlen, sizeof (struct ctf_enum) * vlen);
	    for (i = 0; i < vlen; i++)
	      {
		const char *name = ctf_strraw (fp, dtd_vlen[i].cte_name);

		ctf_str_add_ref (fp, name, &t_vlen[i].cte_name);
		ctf_str_add_ref (fp, name, &dtd_vlen[i].cte_name);
	      }
	    t += sizeof (struct ctf_enum) * vlen;

	    break;
	  }
	}
    }

  *tptr = t;
}

/* Variable section.  */

/* Sort a newly-constructed static variable array.  */

typedef struct ctf_sort_var_arg_cb
{
  ctf_dict_t *fp;
  ctf_strs_t *strtab;
} ctf_sort_var_arg_cb_t;

static int
ctf_sort_var (const void *one_, const void *two_, void *arg_)
{
  const ctf_varent_t *one = one_;
  const ctf_varent_t *two = two_;
  ctf_sort_var_arg_cb_t *arg = arg_;

  return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
		  ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
}

/* Overall serialization.  */

/* If the specified CTF dict is writable and has been modified, reload this dict
   with the updated type definitions, ready for serialization.  In order to make
   this code and the rest of libctf as simple as possible, we perform updates by
   taking the dynamic type definitions and creating an in-memory CTF dict
   containing the definitions, and then call ctf_simple_open_internal() on it.
   We perform one extra trick here for the benefit of callers and to keep our
   code simple: ctf_simple_open_internal() will return a new ctf_dict_t, but we
   want to keep the fp constant for the caller, so after
   ctf_simple_open_internal() returns, we use memcpy to swap the interior of the
   old and new ctf_dict_t's, and then free the old.  */
int
ctf_serialize (ctf_dict_t *fp)
{
  ctf_dict_t ofp, *nfp;
  ctf_header_t hdr, *hdrp;
  ctf_dvdef_t *dvd;
  ctf_varent_t *dvarents;
  ctf_strs_writable_t strtab;
  int err;
  int num_missed_str_refs;

  unsigned char *t;
  unsigned long i;
  size_t buf_size, type_size, objt_size, func_size;
  size_t funcidx_size, objtidx_size;
  size_t nvars;
  unsigned char *buf = NULL, *newbuf;

  emit_symtypetab_state_t symstate;
  memset (&symstate, 0, sizeof (emit_symtypetab_state_t));

  if (!(fp->ctf_flags & LCTF_RDWR))
    return (ctf_set_errno (fp, ECTF_RDONLY));

  /* Update required?  */
  if (!(fp->ctf_flags & LCTF_DIRTY))
    return 0;

  /* The strtab refs table must be empty at this stage.  Any refs already added
     will be corrupted by any modifications, including reserialization, after
     strtab finalization is complete.  Only this function, and functions it
     calls, may add refs, and all memory locations (including in the dtds)
     containing strtab offsets must be traversed as part of serialization, and
     refs added.  */

  if (!ctf_assert (fp, fp->ctf_str_num_refs == 0))
    return -1;					/* errno is set for us.  */

  /* Fill in an initial CTF header.  We will leave the label, object,
     and function sections empty and only output a header, type section,
     and string table.  The type section begins at a 4-byte aligned
     boundary past the CTF header itself (at relative offset zero).  The flag
     indicating a new-style function info section (an array of CTF_K_FUNCTION
     type IDs in the types section) is flipped on.  */

  memset (&hdr, 0, sizeof (hdr));
  hdr.cth_magic = CTF_MAGIC;
  hdr.cth_version = CTF_VERSION;

  /* This is a new-format func info section, and the symtab and strtab come out
     of the dynsym and dynstr these days.  */
  hdr.cth_flags = (CTF_F_NEWFUNCINFO | CTF_F_DYNSTR);

  if (ctf_symtypetab_sect_sizes (fp, &symstate, &hdr, &objt_size, &func_size,
				 &objtidx_size, &funcidx_size) < 0)
    return -1;					/* errno is set for us.  */

  for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
       dvd != NULL; dvd = ctf_list_next (dvd), nvars++);

  type_size = ctf_type_sect_size (fp);

  /* Compute the size of the CTF buffer we need, sans only the string table,
     then allocate a new buffer and memcpy the finished header to the start of
     the buffer.  (We will adjust this later with strtab length info.)  */

  hdr.cth_lbloff = hdr.cth_objtoff = 0;
  hdr.cth_funcoff = hdr.cth_objtoff + objt_size;
  hdr.cth_objtidxoff = hdr.cth_funcoff + func_size;
  hdr.cth_funcidxoff = hdr.cth_objtidxoff + objtidx_size;
  hdr.cth_varoff = hdr.cth_funcidxoff + funcidx_size;
  hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
  hdr.cth_stroff = hdr.cth_typeoff + type_size;
  hdr.cth_strlen = 0;

  buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;

  if ((buf = malloc (buf_size)) == NULL)
    return (ctf_set_errno (fp, EAGAIN));

  memcpy (buf, &hdr, sizeof (ctf_header_t));
  t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_objtoff;

  hdrp = (ctf_header_t *) buf;
  if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
    ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
  if (fp->ctf_cuname != NULL)
    ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);

  if (ctf_emit_symtypetab_sects (fp, &symstate, &t, objt_size, func_size,
				 objtidx_size, funcidx_size) < 0)
    goto err;

  assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff);

  /* Work over the variable list, translating everything into ctf_varent_t's and
     prepping the string table.  */

  dvarents = (ctf_varent_t *) t;
  for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
       dvd = ctf_list_next (dvd), i++)
    {
      ctf_varent_t *var = &dvarents[i];

      ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
      var->ctv_type = (uint32_t) dvd->dvd_type;
    }
  assert (i == nvars);

  t += sizeof (ctf_varent_t) * nvars;

  assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);

  ctf_emit_type_sect (fp, &t);

  assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);

  /* Every string added outside serialization by ctf_str_add_pending should
     now have been added by ctf_add_ref.  */
  num_missed_str_refs = ctf_dynset_elements (fp->ctf_str_pending_ref);
  if (!ctf_assert (fp, num_missed_str_refs == 0))
    goto err;					/* errno is set for us.  */

  /* Construct the final string table and fill out all the string refs with the
     final offsets.  Then purge the refs list, because we're about to move this
     strtab onto the end of the buf, invalidating all the offsets.  */
  strtab = ctf_str_write_strtab (fp);
  ctf_str_purge_refs (fp);

  if (strtab.cts_strs == NULL)
    goto oom;

  /* Now the string table is constructed, we can sort the buffer of
     ctf_varent_t's.  */
  ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) &strtab };
  ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
	       &sort_var_arg);

  if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
    {
      free (strtab.cts_strs);
      goto oom;
    }
  buf = newbuf;
  memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
  hdrp = (ctf_header_t *) buf;
  hdrp->cth_strlen = strtab.cts_len;
  buf_size += hdrp->cth_strlen;
  free (strtab.cts_strs);

  /* Finally, we are ready to ctf_simple_open() the new dict.  If this is
     successful, we then switch nfp and fp and free the old dict.  */

  if ((nfp = ctf_simple_open_internal ((char *) buf, buf_size, NULL, 0,
				       0, NULL, 0, fp->ctf_syn_ext_strtab,
				       1, &err)) == NULL)
    {
      free (buf);
      return (ctf_set_errno (fp, err));
    }

  (void) ctf_setmodel (nfp, ctf_getmodel (fp));

  nfp->ctf_parent = fp->ctf_parent;
  nfp->ctf_parent_unreffed = fp->ctf_parent_unreffed;
  nfp->ctf_refcnt = fp->ctf_refcnt;
  nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
  if (nfp->ctf_dynbase == NULL)
    nfp->ctf_dynbase = buf;		/* Make sure buf is freed on close.  */
  nfp->ctf_dthash = fp->ctf_dthash;
  nfp->ctf_dtdefs = fp->ctf_dtdefs;
  nfp->ctf_dvhash = fp->ctf_dvhash;
  nfp->ctf_dvdefs = fp->ctf_dvdefs;
  nfp->ctf_dtoldid = fp->ctf_dtoldid;
  nfp->ctf_add_processing = fp->ctf_add_processing;
  nfp->ctf_snapshots = fp->ctf_snapshots + 1;
  nfp->ctf_specific = fp->ctf_specific;
  nfp->ctf_nfuncidx = fp->ctf_nfuncidx;
  nfp->ctf_nobjtidx = fp->ctf_nobjtidx;
  nfp->ctf_objthash = fp->ctf_objthash;
  nfp->ctf_funchash = fp->ctf_funchash;
  nfp->ctf_dynsyms = fp->ctf_dynsyms;
  nfp->ctf_ptrtab = fp->ctf_ptrtab;
  nfp->ctf_pptrtab = fp->ctf_pptrtab;
  nfp->ctf_typemax = fp->ctf_typemax;
  nfp->ctf_dynsymidx = fp->ctf_dynsymidx;
  nfp->ctf_dynsymmax = fp->ctf_dynsymmax;
  nfp->ctf_ptrtab_len = fp->ctf_ptrtab_len;
  nfp->ctf_pptrtab_len = fp->ctf_pptrtab_len;
  nfp->ctf_link_inputs = fp->ctf_link_inputs;
  nfp->ctf_link_outputs = fp->ctf_link_outputs;
  nfp->ctf_errs_warnings = fp->ctf_errs_warnings;
  nfp->ctf_funcidx_names = fp->ctf_funcidx_names;
  nfp->ctf_objtidx_names = fp->ctf_objtidx_names;
  nfp->ctf_funcidx_sxlate = fp->ctf_funcidx_sxlate;
  nfp->ctf_objtidx_sxlate = fp->ctf_objtidx_sxlate;
  nfp->ctf_str_prov_offset = fp->ctf_str_prov_offset;
  nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
  nfp->ctf_pptrtab_typemax = fp->ctf_pptrtab_typemax;
  nfp->ctf_in_flight_dynsyms = fp->ctf_in_flight_dynsyms;
  nfp->ctf_link_in_cu_mapping = fp->ctf_link_in_cu_mapping;
  nfp->ctf_link_out_cu_mapping = fp->ctf_link_out_cu_mapping;
  nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
  nfp->ctf_link_memb_name_changer = fp->ctf_link_memb_name_changer;
  nfp->ctf_link_memb_name_changer_arg = fp->ctf_link_memb_name_changer_arg;
  nfp->ctf_link_variable_filter = fp->ctf_link_variable_filter;
  nfp->ctf_link_variable_filter_arg = fp->ctf_link_variable_filter_arg;
  nfp->ctf_symsect_little_endian = fp->ctf_symsect_little_endian;
  nfp->ctf_link_flags = fp->ctf_link_flags;
  nfp->ctf_dedup_atoms = fp->ctf_dedup_atoms;
  nfp->ctf_dedup_atoms_alloc = fp->ctf_dedup_atoms_alloc;
  memcpy (&nfp->ctf_dedup, &fp->ctf_dedup, sizeof (fp->ctf_dedup));

  nfp->ctf_snapshot_lu = fp->ctf_snapshots;

  memcpy (&nfp->ctf_lookups, fp->ctf_lookups, sizeof (fp->ctf_lookups));
  nfp->ctf_structs = fp->ctf_structs;
  nfp->ctf_unions = fp->ctf_unions;
  nfp->ctf_enums = fp->ctf_enums;
  nfp->ctf_names = fp->ctf_names;

  fp->ctf_dthash = NULL;
  ctf_str_free_atoms (nfp);
  nfp->ctf_str_atoms = fp->ctf_str_atoms;
  nfp->ctf_prov_strtab = fp->ctf_prov_strtab;
  nfp->ctf_str_pending_ref = fp->ctf_str_pending_ref;
  fp->ctf_str_atoms = NULL;
  fp->ctf_prov_strtab = NULL;
  fp->ctf_str_pending_ref = NULL;
  memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
  memset (&fp->ctf_errs_warnings, 0, sizeof (ctf_list_t));
  fp->ctf_add_processing = NULL;
  fp->ctf_ptrtab = NULL;
  fp->ctf_pptrtab = NULL;
  fp->ctf_funcidx_names = NULL;
  fp->ctf_objtidx_names = NULL;
  fp->ctf_funcidx_sxlate = NULL;
  fp->ctf_objtidx_sxlate = NULL;
  fp->ctf_objthash = NULL;
  fp->ctf_funchash = NULL;
  fp->ctf_dynsyms = NULL;
  fp->ctf_dynsymidx = NULL;
  fp->ctf_link_inputs = NULL;
  fp->ctf_link_outputs = NULL;
  fp->ctf_syn_ext_strtab = NULL;
  fp->ctf_link_in_cu_mapping = NULL;
  fp->ctf_link_out_cu_mapping = NULL;
  fp->ctf_link_type_mapping = NULL;
  fp->ctf_dedup_atoms = NULL;
  fp->ctf_dedup_atoms_alloc = NULL;
  fp->ctf_parent_unreffed = 1;

  fp->ctf_dvhash = NULL;
  memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
  memset (fp->ctf_lookups, 0, sizeof (fp->ctf_lookups));
  memset (&fp->ctf_in_flight_dynsyms, 0, sizeof (fp->ctf_in_flight_dynsyms));
  memset (&fp->ctf_dedup, 0, sizeof (fp->ctf_dedup));
  fp->ctf_structs.ctn_writable = NULL;
  fp->ctf_unions.ctn_writable = NULL;
  fp->ctf_enums.ctn_writable = NULL;
  fp->ctf_names.ctn_writable = NULL;

  memcpy (&ofp, fp, sizeof (ctf_dict_t));
  memcpy (fp, nfp, sizeof (ctf_dict_t));
  memcpy (nfp, &ofp, sizeof (ctf_dict_t));

  nfp->ctf_refcnt = 1;				/* Force nfp to be freed.  */
  ctf_dict_close (nfp);

  return 0;

oom:
  free (buf);
  return (ctf_set_errno (fp, EAGAIN));
err:
  free (buf);
  return -1;					/* errno is set for us.  */
}

/* File writing.  */

/* Write the compressed CTF data stream to the specified gzFile descriptor.  The
   whole stream is compressed, and cannot be read by CTF opening functions in
   this library until it is decompressed.  (The functions below this one leave
   the header uncompressed, and the CTF opening functions work on them without
   manual decompression.)

   No support for (testing-only) endian-flipping.  */
int
ctf_gzwrite (ctf_dict_t *fp, gzFile fd)
{
  const unsigned char *buf;
  ssize_t resid;
  ssize_t len;

  resid = sizeof (ctf_header_t);
  buf = (unsigned char *) fp->ctf_header;
  while (resid != 0)
    {
      if ((len = gzwrite (fd, buf, resid)) <= 0)
	return (ctf_set_errno (fp, errno));
      resid -= len;
      buf += len;
    }

  resid = fp->ctf_size;
  buf = fp->ctf_buf;
  while (resid != 0)
    {
      if ((len = gzwrite (fd, buf, resid)) <= 0)
	return (ctf_set_errno (fp, errno));
      resid -= len;
      buf += len;
    }

  return 0;
}

/* Optionally compress the specified CTF data stream and return it as a new
   dynamically-allocated string.  Possibly write it with reversed
   endianness.  */
unsigned char *
ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold)
{
  unsigned char *buf;
  unsigned char *bp;
  ctf_header_t *hp;
  unsigned char *flipped, *src;
  ssize_t header_len = sizeof (ctf_header_t);
  ssize_t compress_len;
  int flip_endian;
  int uncompressed;
  int rc;

  flip_endian = getenv ("LIBCTF_WRITE_FOREIGN_ENDIAN") != NULL;
  uncompressed = (fp->ctf_size < threshold);

  if (ctf_serialize (fp) < 0)
    return NULL;				/* errno is set for us.  */

  compress_len = compressBound (fp->ctf_size);
  if (fp->ctf_size < threshold)
    compress_len = fp->ctf_size;
  if ((buf = malloc (compress_len
		     + sizeof (struct ctf_header))) == NULL)
    {
      ctf_set_errno (fp, ENOMEM);
      ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
		    (unsigned long) (compress_len + sizeof (struct ctf_header)));
      return NULL;
    }

  hp = (ctf_header_t *) buf;
  memcpy (hp, fp->ctf_header, header_len);
  bp = buf + sizeof (struct ctf_header);
  *size = sizeof (struct ctf_header);

  if (uncompressed)
    hp->cth_flags &= ~CTF_F_COMPRESS;
  else
    hp->cth_flags |= CTF_F_COMPRESS;

  src = fp->ctf_buf;
  flipped = NULL;

  if (flip_endian)
    {
      if ((flipped = malloc (fp->ctf_size)) == NULL)
	{
	  ctf_set_errno (fp, ENOMEM);
	  ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
			(unsigned long) (fp->ctf_size + sizeof (struct ctf_header)));
	  return NULL;
	}
      ctf_flip_header (hp);
      memcpy (flipped, fp->ctf_buf, fp->ctf_size);
      if (ctf_flip (fp, fp->ctf_header, flipped, 1) < 0)
	{
	  free (buf);
	  free (flipped);
	  return NULL;				/* errno is set for us.  */
	}
      src = flipped;
    }

  if (uncompressed)
    {
      memcpy (bp, src, fp->ctf_size);
      *size += fp->ctf_size;
    }
  else
    {
      if ((rc = compress (bp, (uLongf *) &compress_len,
			  src, fp->ctf_size)) != Z_OK)
	{
	  ctf_set_errno (fp, ECTF_COMPRESS);
	  ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
	  free (buf);
	  return NULL;
	}
      *size += compress_len;
    }

  free (flipped);

  return buf;
}

/* Compress the specified CTF data stream and write it to the specified file
   descriptor.  */
int
ctf_compress_write (ctf_dict_t *fp, int fd)
{
  unsigned char *buf;
  unsigned char *bp;
  size_t tmp;
  ssize_t buf_len;
  ssize_t len;
  int err = 0;

  if ((buf = ctf_write_mem (fp, &tmp, 0)) == NULL)
    return -1;					/* errno is set for us.  */

  buf_len = tmp;
  bp = buf;

  while (buf_len > 0)
    {
      if ((len = write (fd, bp, buf_len)) < 0)
	{
	  err = ctf_set_errno (fp, errno);
	  ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
	  goto ret;
	}
      buf_len -= len;
      bp += len;
    }

ret:
  free (buf);
  return err;
}

/* Write the uncompressed CTF data stream to the specified file descriptor.  */
int
ctf_write (ctf_dict_t *fp, int fd)
{
  unsigned char *buf;
  unsigned char *bp;
  size_t tmp;
  ssize_t buf_len;
  ssize_t len;
  int err = 0;

  if ((buf = ctf_write_mem (fp, &tmp, (size_t) -1)) == NULL)
    return -1;					/* errno is set for us.  */

  buf_len = tmp;
  bp = buf;

  while (buf_len > 0)
    {
      if ((len = write (fd, bp, buf_len)) < 0)
	{
	  err = ctf_set_errno (fp, errno);
	  ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
	  goto ret;
	}
      buf_len -= len;
      bp += len;
    }

ret:
  free (buf);
  return err;
}
