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