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