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