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