libctf: add a deduplicator-specific type mapping table
[deliverable/binutils-gdb.git] / libctf / ctf-create.c
CommitLineData
47d546f4 1/* CTF file creation.
250d07de 2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
47d546f4
NA
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 <sys/param.h>
22#include <assert.h>
23#include <string.h>
c1401ecc 24#include <unistd.h>
47d546f4
NA
25#include <zlib.h>
26
1136c379
NA
27#include <elf.h>
28#include "elf-bfd.h"
29
555adca2
EZ
30#ifndef EOVERFLOW
31#define EOVERFLOW ERANGE
32#endif
33
a0486bac
JM
34#ifndef roundup
35#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
36#endif
37
676c3ecb
NA
38/* Make sure the ptrtab has enough space for at least one more type.
39
40 We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
41 at a time. */
42
43static int
139633c3 44ctf_grow_ptrtab (ctf_dict_t *fp)
676c3ecb
NA
45{
46 size_t new_ptrtab_len = fp->ctf_ptrtab_len;
47
48 /* We allocate one more ptrtab entry than we need, for the initial zero,
49 plus one because the caller will probably allocate a new type. */
50
51 if (fp->ctf_ptrtab == NULL)
52 new_ptrtab_len = 1024;
53 else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
54 new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
55
56 if (new_ptrtab_len != fp->ctf_ptrtab_len)
57 {
58 uint32_t *new_ptrtab;
59
60 if ((new_ptrtab = realloc (fp->ctf_ptrtab,
61 new_ptrtab_len * sizeof (uint32_t))) == NULL)
62 return (ctf_set_errno (fp, ENOMEM));
63
64 fp->ctf_ptrtab = new_ptrtab;
65 memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
66 (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
67 fp->ctf_ptrtab_len = new_ptrtab_len;
68 }
69 return 0;
70}
71
139633c3
NA
72/* To create an empty CTF dict, we just declare a zeroed header and call
73 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new dict r/w and
74 initialize the dynamic members. We start assigning type IDs at 1 because
f5e9c9bd 75 type ID 0 is used as a sentinel and a not-found indicator. */
47d546f4 76
139633c3 77ctf_dict_t *
47d546f4
NA
78ctf_create (int *errp)
79{
80 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
81
82 ctf_dynhash_t *dthash;
83 ctf_dynhash_t *dvhash;
676c3ecb 84 ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
1136c379 85 ctf_dynhash_t *objthash = NULL, *funchash = NULL;
47d546f4 86 ctf_sect_t cts;
139633c3 87 ctf_dict_t *fp;
47d546f4
NA
88
89 libctf_init_debug();
90 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
91 NULL, NULL);
92 if (dthash == NULL)
93 {
94 ctf_set_open_errno (errp, EAGAIN);
95 goto err;
96 }
97
98 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
99 NULL, NULL);
100 if (dvhash == NULL)
101 {
102 ctf_set_open_errno (errp, EAGAIN);
103 goto err_dt;
104 }
105
676c3ecb
NA
106 structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
107 NULL, NULL);
108 unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
109 NULL, NULL);
110 enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
111 NULL, NULL);
112 names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
113 NULL, NULL);
1136c379
NA
114 objthash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
115 free, NULL);
116 funchash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
117 free, NULL);
676c3ecb 118 if (!structs || !unions || !enums || !names)
47d546f4
NA
119 {
120 ctf_set_open_errno (errp, EAGAIN);
121 goto err_dv;
122 }
123
124 cts.cts_name = _CTF_SECTION;
47d546f4
NA
125 cts.cts_data = &hdr;
126 cts.cts_size = sizeof (hdr);
127 cts.cts_entsize = 1;
47d546f4 128
676c3ecb
NA
129 if ((fp = ctf_bufopen_internal (&cts, NULL, NULL, NULL, 1, errp)) == NULL)
130 goto err_dv;
47d546f4 131
676c3ecb
NA
132 fp->ctf_structs.ctn_writable = structs;
133 fp->ctf_unions.ctn_writable = unions;
134 fp->ctf_enums.ctn_writable = enums;
135 fp->ctf_names.ctn_writable = names;
1136c379
NA
136 fp->ctf_objthash = objthash;
137 fp->ctf_funchash = funchash;
47d546f4
NA
138 fp->ctf_dthash = dthash;
139 fp->ctf_dvhash = dvhash;
47d546f4 140 fp->ctf_dtoldid = 0;
f57cf0e3 141 fp->ctf_snapshots = 1;
47d546f4 142 fp->ctf_snapshot_lu = 0;
dd987f00 143 fp->ctf_flags |= LCTF_DIRTY;
47d546f4 144
676c3ecb
NA
145 ctf_set_ctl_hashes (fp);
146 ctf_setmodel (fp, CTF_MODEL_NATIVE);
147 if (ctf_grow_ptrtab (fp) < 0)
148 {
149 ctf_set_open_errno (errp, ctf_errno (fp));
139633c3 150 ctf_dict_close (fp);
676c3ecb
NA
151 return NULL;
152 }
153
47d546f4
NA
154 return fp;
155
47d546f4 156 err_dv:
676c3ecb
NA
157 ctf_dynhash_destroy (structs);
158 ctf_dynhash_destroy (unions);
159 ctf_dynhash_destroy (enums);
160 ctf_dynhash_destroy (names);
1136c379
NA
161 ctf_dynhash_destroy (objthash);
162 ctf_dynhash_destroy (funchash);
47d546f4
NA
163 ctf_dynhash_destroy (dvhash);
164 err_dt:
165 ctf_dynhash_destroy (dthash);
166 err:
167 return NULL;
168}
169
1136c379
NA
170/* Delete data symbols that have been assigned names from the variable section.
171 Must be called from within ctf_serialize, because that is the only place
172 you can safely delete variables without messing up ctf_rollback. */
173
174static int
35a01a04 175symtypetab_delete_nonstatic_vars (ctf_dict_t *fp, ctf_dict_t *symfp)
1136c379
NA
176{
177 ctf_dvdef_t *dvd, *nvd;
178 ctf_id_t type;
179
180 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
181 {
182 nvd = ctf_list_next (dvd);
183
184 if (((type = (ctf_id_t) (uintptr_t)
185 ctf_dynhash_lookup (fp->ctf_objthash, dvd->dvd_name)) > 0)
35a01a04 186 && ctf_dynhash_lookup (symfp->ctf_dynsyms, dvd->dvd_name) != NULL
1136c379
NA
187 && type == dvd->dvd_type)
188 ctf_dvd_delete (fp, dvd);
189 }
190
191 return 0;
192}
193
194/* Determine if a symbol is "skippable" and should never appear in the
195 symtypetab sections. */
196
197int
198ctf_symtab_skippable (ctf_link_sym_t *sym)
199{
200 /* Never skip symbols whose name is not yet known. */
201 if (sym->st_nameidx_set)
202 return 0;
203
204 return (sym->st_name == NULL || sym->st_name[0] == 0
205 || sym->st_shndx == SHN_UNDEF
206 || strcmp (sym->st_name, "_START_") == 0
207 || strcmp (sym->st_name, "_END_") == 0
208 || (sym->st_type == STT_OBJECT && sym->st_shndx == SHN_EXTABS
209 && sym->st_value == 0));
210}
211
212/* Symtypetab emission flags. */
213
214#define CTF_SYMTYPETAB_EMIT_FUNCTION 0x1
215#define CTF_SYMTYPETAB_EMIT_PAD 0x2
216#define CTF_SYMTYPETAB_FORCE_INDEXED 0x4
217
218/* Get the number of symbols in a symbol hash, the count of symbols, the maximum
219 seen, the eventual size, without any padding elements, of the func/data and
220 (if generated) index sections, and the size of accumulated padding elements.
35a01a04
NA
221 The linker-reported set of symbols is found in SYMFP: it may be NULL if
222 symbol filtering is not desired, in which case CTF_SYMTYPETAB_FORCE_INDEXED
223 will always be set in the flags.
1136c379
NA
224
225 Also figure out if any symbols need to be moved to the variable section, and
226 add them (if not already present). */
227
35a01a04 228_libctf_nonnull_ ((1,3,4,5,6,7,8))
1136c379
NA
229static int
230symtypetab_density (ctf_dict_t *fp, ctf_dict_t *symfp, ctf_dynhash_t *symhash,
231 size_t *count, size_t *max, size_t *unpadsize,
232 size_t *padsize, size_t *idxsize, int flags)
233{
234 ctf_next_t *i = NULL;
235 const void *name;
236 const void *ctf_sym;
237 ctf_dynhash_t *linker_known = NULL;
238 int err;
239 int beyond_max = 0;
240
241 *count = 0;
242 *max = 0;
243 *unpadsize = 0;
244 *idxsize = 0;
245 *padsize = 0;
246
247 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
248 {
249 /* Make a dynhash citing only symbols reported by the linker of the
250 appropriate type, then traverse all potential-symbols we know the types
251 of, removing them from linker_known as we go. Once this is done, the
252 only symbols remaining in linker_known are symbols we don't know the
253 types of: we must emit pads for those symbols that are below the
35a01a04
NA
254 maximum symbol we will emit (any beyond that are simply skipped).
255
256 If there are none, this symtypetab will be empty: just report that. */
257
258 if (!symfp->ctf_dynsyms)
259 return 0;
1136c379
NA
260
261 if ((linker_known = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
262 NULL, NULL)) == NULL)
263 return (ctf_set_errno (fp, ENOMEM));
264
265 while ((err = ctf_dynhash_cnext (symfp->ctf_dynsyms, &i,
266 &name, &ctf_sym)) == 0)
267 {
268 ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;
269
270 if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
271 && sym->st_type != STT_FUNC)
272 || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
273 && sym->st_type != STT_OBJECT))
274 continue;
275
276 if (ctf_symtab_skippable (sym))
277 continue;
278
279 /* This should only be true briefly before all the names are
280 finalized, long before we get this far. */
281 if (!ctf_assert (fp, !sym->st_nameidx_set))
282 return -1; /* errno is set for us. */
283
284 if (ctf_dynhash_cinsert (linker_known, name, ctf_sym) < 0)
285 {
286 ctf_dynhash_destroy (linker_known);
287 return (ctf_set_errno (fp, ENOMEM));
288 }
289 }
290 if (err != ECTF_NEXT_END)
291 {
292 ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols during "
293 "serialization"));
294 ctf_dynhash_destroy (linker_known);
295 return (ctf_set_errno (fp, err));
296 }
297 }
298
299 while ((err = ctf_dynhash_cnext (symhash, &i, &name, NULL)) == 0)
300 {
301 ctf_link_sym_t *sym;
302
303 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
304 {
305 /* Linker did not report symbol in symtab. Remove it from the
306 set of known data symbols and continue. */
307 if ((sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, name)) == NULL)
308 {
309 ctf_dynhash_remove (symhash, name);
310 continue;
311 }
312
313 /* We don't remove skippable symbols from the symhash because we don't
314 want them to be migrated into variables. */
315 if (ctf_symtab_skippable (sym))
316 continue;
317
318 if ((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
319 && sym->st_type != STT_FUNC)
320 {
321 ctf_err_warn (fp, 1, 0, _("Symbol %x added to CTF as a function "
322 "but is of type %x\n"),
323 sym->st_symidx, sym->st_type);
324 ctf_dynhash_remove (symhash, name);
325 continue;
326 }
327 else if (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
328 && sym->st_type != STT_OBJECT)
329 {
330 ctf_err_warn (fp, 1, 0, _("Symbol %x added to CTF as a data "
331 "object but is of type %x\n"),
332 sym->st_symidx, sym->st_type);
333 ctf_dynhash_remove (symhash, name);
334 continue;
335 }
336
337 ctf_dynhash_remove (linker_known, name);
338 }
339 *unpadsize += sizeof (uint32_t);
340 (*count)++;
341
342 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
343 {
344 if (*max < sym->st_symidx)
345 *max = sym->st_symidx;
346 }
347 else
348 (*max)++;
349 }
350 if (err != ECTF_NEXT_END)
351 {
352 ctf_err_warn (fp, 0, err, _("iterating over CTF symtypetab during "
353 "serialization"));
354 ctf_dynhash_destroy (linker_known);
355 return (ctf_set_errno (fp, err));
356 }
357
358 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
359 {
360 while ((err = ctf_dynhash_cnext (linker_known, &i, NULL, &ctf_sym)) == 0)
361 {
362 ctf_link_sym_t *sym = (ctf_link_sym_t *) ctf_sym;
363
364 if (sym->st_symidx > *max)
365 beyond_max++;
366 }
367 if (err != ECTF_NEXT_END)
368 {
369 ctf_err_warn (fp, 0, err, _("iterating over linker-known symbols "
370 "during CTF serialization"));
371 ctf_dynhash_destroy (linker_known);
372 return (ctf_set_errno (fp, err));
373 }
374 }
375
376 *idxsize = *count * sizeof (uint32_t);
377 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
378 *padsize = (ctf_dynhash_elements (linker_known) - beyond_max) * sizeof (uint32_t);
379
380 ctf_dynhash_destroy (linker_known);
381 return 0;
382}
383
384/* Emit an objt or func symtypetab into DP in a particular order defined by an
385 array of ctf_link_sym_t or symbol names passed in. The index has NIDX
386 elements in it: unindexed output would terminate at symbol OUTMAX and is in
387 any case no larger than SIZE bytes. Some index elements are expected to be
388 skipped: see symtypetab_density. The linker-reported set of symbols (if any)
389 is found in SYMFP. */
390static int
391emit_symtypetab (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
392 ctf_link_sym_t **idx, const char **nameidx, uint32_t nidx,
393 uint32_t outmax, int size, int flags)
394{
395 uint32_t i;
396 uint32_t *dpp = dp;
397 ctf_dynhash_t *symhash;
398
399 ctf_dprintf ("Emitting table of size %i, outmax %u, %u symtypetab entries, "
400 "flags %i\n", size, outmax, nidx, flags);
401
402 /* Empty table? Nothing to do. */
403 if (size == 0)
404 return 0;
405
406 if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
407 symhash = fp->ctf_funchash;
408 else
409 symhash = fp->ctf_objthash;
410
411 for (i = 0; i < nidx; i++)
412 {
413 const char *sym_name;
414 void *type;
415
416 /* If we have a linker-reported set of symbols, we may be given that set
417 to work from, or a set of symbol names. In both cases we want to look
418 at the corresponding linker-reported symbol (if any). */
419 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
420 {
421 ctf_link_sym_t *this_link_sym;
422
423 if (idx)
424 this_link_sym = idx[i];
425 else
426 this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, nameidx[i]);
427
428 /* Unreported symbol number. No pad, no nothing. */
429 if (!this_link_sym)
430 continue;
431
432 /* Symbol of the wrong type, or skippable? This symbol is not in this
433 table. */
434 if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
435 && this_link_sym->st_type != STT_FUNC)
436 || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
437 && this_link_sym->st_type != STT_OBJECT))
438 continue;
439
440 if (ctf_symtab_skippable (this_link_sym))
441 continue;
442
443 sym_name = this_link_sym->st_name;
444
445 /* Linker reports symbol of a different type to the symbol we actually
446 added? Skip the symbol. No pad, since the symbol doesn't actually
447 belong in this table at all. (Warned about in
448 symtypetab_density.) */
449 if ((this_link_sym->st_type == STT_FUNC)
450 && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
451 continue;
452
453 if ((this_link_sym->st_type == STT_OBJECT)
454 && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
455 continue;
456 }
457 else
458 sym_name = nameidx[i];
459
460 /* Symbol in index but no type set? Silently skip and (optionally)
461 pad. (In force-indexed mode, this is also where we track symbols of
462 the wrong type for this round of insertion.) */
463 if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
464 {
465 if (flags & CTF_SYMTYPETAB_EMIT_PAD)
466 *dpp++ = 0;
467 continue;
468 }
469
470 if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) < size))
471 return -1; /* errno is set for us. */
472
473 *dpp++ = (ctf_id_t) (uintptr_t) type;
474
475 /* When emitting unindexed output, all later symbols are pads: stop
476 early. */
477 if ((flags & CTF_SYMTYPETAB_EMIT_PAD) && idx[i]->st_symidx == outmax)
478 break;
479 }
480
481 return 0;
482}
483
484/* Emit an objt or func symtypetab index into DP in a paticular order defined by
485 an array of symbol names passed in. Stop at NIDX. The linker-reported set
486 of symbols (if any) is found in SYMFP. */
487static int
488emit_symtypetab_index (ctf_dict_t *fp, ctf_dict_t *symfp, uint32_t *dp,
489 const char **idx, uint32_t nidx, int size, int flags)
490{
491 uint32_t i;
492 uint32_t *dpp = dp;
493 ctf_dynhash_t *symhash;
494
495 ctf_dprintf ("Emitting index of size %i, %u entries reported by linker, "
496 "flags %i\n", size, nidx, flags);
497
498 /* Empty table? Nothing to do. */
499 if (size == 0)
500 return 0;
501
502 if (flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
503 symhash = fp->ctf_funchash;
504 else
505 symhash = fp->ctf_objthash;
506
507 /* Indexes should always be unpadded. */
508 if (!ctf_assert (fp, !(flags & CTF_SYMTYPETAB_EMIT_PAD)))
509 return -1; /* errno is set for us. */
510
511 for (i = 0; i < nidx; i++)
512 {
513 const char *sym_name;
514 void *type;
515
516 if (!(flags & CTF_SYMTYPETAB_FORCE_INDEXED))
517 {
518 ctf_link_sym_t *this_link_sym;
519
520 this_link_sym = ctf_dynhash_lookup (symfp->ctf_dynsyms, idx[i]);
521
522 /* This is an index: unreported symbols should never appear in it. */
523 if (!ctf_assert (fp, this_link_sym != NULL))
524 return -1; /* errno is set for us. */
525
526 /* Symbol of the wrong type, or skippable? This symbol is not in this
527 table. */
528 if (((flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
529 && this_link_sym->st_type != STT_FUNC)
530 || (!(flags & CTF_SYMTYPETAB_EMIT_FUNCTION)
531 && this_link_sym->st_type != STT_OBJECT))
532 continue;
533
534 if (ctf_symtab_skippable (this_link_sym))
535 continue;
536
537 sym_name = this_link_sym->st_name;
538
539 /* Linker reports symbol of a different type to the symbol we actually
540 added? Skip the symbol. */
541 if ((this_link_sym->st_type == STT_FUNC)
542 && (ctf_dynhash_lookup (fp->ctf_objthash, sym_name)))
543 continue;
544
545 if ((this_link_sym->st_type == STT_OBJECT)
546 && (ctf_dynhash_lookup (fp->ctf_funchash, sym_name)))
547 continue;
548 }
549 else
550 sym_name = idx[i];
551
552 /* Symbol in index and reported by linker, but no type set? Silently skip
553 and (optionally) pad. (In force-indexed mode, this is also where we
554 track symbols of the wrong type for this round of insertion.) */
555 if ((type = ctf_dynhash_lookup (symhash, sym_name)) == NULL)
556 continue;
557
558 ctf_str_add_ref (fp, sym_name, dpp++);
559
560 if (!ctf_assert (fp, (((char *) dpp) - (char *) dp) <= size))
561 return -1; /* errno is set for us. */
562 }
563
564 return 0;
565}
566
47d546f4 567static unsigned char *
139633c3 568ctf_copy_smembers (ctf_dict_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
569{
570 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
571 ctf_member_t ctm;
572
573 for (; dmd != NULL; dmd = ctf_list_next (dmd))
574 {
f5e9c9bd 575 ctf_member_t *copied;
47d546f4 576
f5e9c9bd 577 ctm.ctm_name = 0;
47d546f4
NA
578 ctm.ctm_type = (uint32_t) dmd->dmd_type;
579 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
580
581 memcpy (t, &ctm, sizeof (ctm));
f5e9c9bd
NA
582 copied = (ctf_member_t *) t;
583 if (dmd->dmd_name)
584 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctm_name);
585
47d546f4
NA
586 t += sizeof (ctm);
587 }
588
589 return t;
590}
591
592static unsigned char *
139633c3 593ctf_copy_lmembers (ctf_dict_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
594{
595 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
596 ctf_lmember_t ctlm;
597
598 for (; dmd != NULL; dmd = ctf_list_next (dmd))
599 {
f5e9c9bd 600 ctf_lmember_t *copied;
47d546f4 601
f5e9c9bd 602 ctlm.ctlm_name = 0;
47d546f4
NA
603 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
604 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
605 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
606
607 memcpy (t, &ctlm, sizeof (ctlm));
f5e9c9bd
NA
608 copied = (ctf_lmember_t *) t;
609 if (dmd->dmd_name)
610 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctlm_name);
611
47d546f4
NA
612 t += sizeof (ctlm);
613 }
614
615 return t;
616}
617
618static unsigned char *
139633c3 619ctf_copy_emembers (ctf_dict_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
620{
621 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
622 ctf_enum_t cte;
623
624 for (; dmd != NULL; dmd = ctf_list_next (dmd))
625 {
f5e9c9bd
NA
626 ctf_enum_t *copied;
627
47d546f4 628 cte.cte_value = dmd->dmd_value;
47d546f4 629 memcpy (t, &cte, sizeof (cte));
f5e9c9bd
NA
630 copied = (ctf_enum_t *) t;
631 ctf_str_add_ref (fp, dmd->dmd_name, &copied->cte_name);
47d546f4
NA
632 t += sizeof (cte);
633 }
634
635 return t;
636}
637
47d546f4
NA
638/* Sort a newly-constructed static variable array. */
639
d851ecd3
NA
640typedef struct ctf_sort_var_arg_cb
641{
139633c3 642 ctf_dict_t *fp;
d851ecd3
NA
643 ctf_strs_t *strtab;
644} ctf_sort_var_arg_cb_t;
645
47d546f4 646static int
d851ecd3 647ctf_sort_var (const void *one_, const void *two_, void *arg_)
47d546f4
NA
648{
649 const ctf_varent_t *one = one_;
650 const ctf_varent_t *two = two_;
d851ecd3 651 ctf_sort_var_arg_cb_t *arg = arg_;
47d546f4 652
d851ecd3
NA
653 return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
654 ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
47d546f4
NA
655}
656
676c3ecb 657/* Compatibility: just update the threshold for ctf_discard. */
47d546f4 658int
139633c3 659ctf_update (ctf_dict_t *fp)
676c3ecb
NA
660{
661 if (!(fp->ctf_flags & LCTF_RDWR))
662 return (ctf_set_errno (fp, ECTF_RDONLY));
663
664 fp->ctf_dtoldid = fp->ctf_typemax;
665 return 0;
666}
667
139633c3
NA
668/* If the specified CTF dict is writable and has been modified, reload this dict
669 with the updated type definitions, ready for serialization. In order to make
670 this code and the rest of libctf as simple as possible, we perform updates by
671 taking the dynamic type definitions and creating an in-memory CTF dict
672 containing the definitions, and then call ctf_simple_open_internal() on it.
673 We perform one extra trick here for the benefit of callers and to keep our
674 code simple: ctf_simple_open_internal() will return a new ctf_dict_t, but we
675 want to keep the fp constant for the caller, so after
676 ctf_simple_open_internal() returns, we use memcpy to swap the interior of the
677 old and new ctf_dict_t's, and then free the old. */
676c3ecb 678int
139633c3 679ctf_serialize (ctf_dict_t *fp)
47d546f4 680{
139633c3 681 ctf_dict_t ofp, *nfp;
f5e9c9bd 682 ctf_header_t hdr, *hdrp;
47d546f4
NA
683 ctf_dtdef_t *dtd;
684 ctf_dvdef_t *dvd;
685 ctf_varent_t *dvarents;
f5e9c9bd 686 ctf_strs_writable_t strtab;
47d546f4 687
f5e9c9bd 688 unsigned char *t;
47d546f4 689 unsigned long i;
1136c379
NA
690 size_t buf_size, type_size, objt_size, func_size;
691 size_t objt_unpadsize, func_unpadsize, objt_padsize, func_padsize;
692 size_t funcidx_size, objtidx_size;
693 size_t nvars, nfuncs, nobjts, maxobjt, maxfunc;
35a01a04 694 size_t nsymtypes = 0;
1136c379
NA
695 const char **sym_name_order = NULL;
696 unsigned char *buf = NULL, *newbuf;
47d546f4
NA
697 int err;
698
35a01a04
NA
699 /* Symtab filtering. If filter_syms is true, symfp is set: otherwise,
700 CTF_SYMTYPETAB_FORCE_INDEXED is set in symflags. */
701 int filter_syms = 0;
702 int sort_syms = 1;
703 int symflags = 0;
704 ctf_dict_t *symfp = NULL;
705
47d546f4
NA
706 if (!(fp->ctf_flags & LCTF_RDWR))
707 return (ctf_set_errno (fp, ECTF_RDONLY));
708
709 /* Update required? */
710 if (!(fp->ctf_flags & LCTF_DIRTY))
711 return 0;
712
35a01a04
NA
713 /* If doing a writeout as part of linking, and the link flags request it,
714 filter out reported symbols from the variable section, and filter out all
715 other symbols from the symtypetab sections. (If we are not linking, the
716 symbols are sorted; if we are linking, don't bother sorting if we are not
717 filtering out reported symbols: this is almost certaily an ld -r and only
718 the linker is likely to consume these symtypetabs again. The linker
719 doesn't care what order the symtypetab entries is in, since it only
720 iterates over symbols and does not use the ctf_lookup_by_symbol* API.) */
721
722 if (fp->ctf_flags & LCTF_LINKING)
723 {
724 filter_syms = !(fp->ctf_link_flags & CTF_LINK_NO_FILTER_REPORTED_SYMS);
725 if (!filter_syms)
726 sort_syms = 0;
727 }
728
47d546f4
NA
729 /* Fill in an initial CTF header. We will leave the label, object,
730 and function sections empty and only output a header, type section,
731 and string table. The type section begins at a 4-byte aligned
1136c379
NA
732 boundary past the CTF header itself (at relative offset zero). The flag
733 indicating a new-style function info section (an array of CTF_K_FUNCTION
734 type IDs in the types section) is flipped on. */
47d546f4
NA
735
736 memset (&hdr, 0, sizeof (hdr));
737 hdr.cth_magic = CTF_MAGIC;
738 hdr.cth_version = CTF_VERSION;
739
1136c379
NA
740 /* This is a new-format func info section, and the symtab and strtab come out
741 of the dynsym and dynstr these days. */
742 hdr.cth_flags = (CTF_F_NEWFUNCINFO | CTF_F_DYNSTR);
3d16b64e 743
47d546f4
NA
744 /* Iterate through the dynamic type definition list and compute the
745 size of the CTF type section we will need to generate. */
746
747 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
748 dtd != NULL; dtd = ctf_list_next (dtd))
749 {
750 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
751 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
752
753 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
754 type_size += sizeof (ctf_stype_t);
755 else
756 type_size += sizeof (ctf_type_t);
757
758 switch (kind)
759 {
760 case CTF_K_INTEGER:
761 case CTF_K_FLOAT:
762 type_size += sizeof (uint32_t);
763 break;
764 case CTF_K_ARRAY:
765 type_size += sizeof (ctf_array_t);
766 break;
767 case CTF_K_SLICE:
768 type_size += sizeof (ctf_slice_t);
769 break;
770 case CTF_K_FUNCTION:
771 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
772 break;
773 case CTF_K_STRUCT:
774 case CTF_K_UNION:
775 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
776 type_size += sizeof (ctf_member_t) * vlen;
777 else
778 type_size += sizeof (ctf_lmember_t) * vlen;
779 break;
780 case CTF_K_ENUM:
781 type_size += sizeof (ctf_enum_t) * vlen;
782 break;
783 }
784 }
785
35a01a04 786 /* Find the dict to which the linker has reported symbols, if any. */
1136c379 787
35a01a04
NA
788 if (filter_syms)
789 {
790 if (!fp->ctf_dynsyms && fp->ctf_parent && fp->ctf_parent->ctf_dynsyms)
791 symfp = fp->ctf_parent;
792 else
793 symfp = fp;
794 }
1136c379 795
35a01a04
NA
796 /* If not filtering, keep all potential symbols in an unsorted, indexed
797 dict. */
798 if (!filter_syms)
1136c379
NA
799 symflags = CTF_SYMTYPETAB_FORCE_INDEXED;
800 else
801 hdr.cth_flags |= CTF_F_IDXSORTED;
802
35a01a04
NA
803 if (!ctf_assert (fp, (filter_syms && symfp)
804 || (!filter_syms && !symfp
805 && ((symflags & CTF_SYMTYPETAB_FORCE_INDEXED) != 0))))
806 return -1;
807
1136c379
NA
808 /* Work out the sizes of the object and function sections, and work out the
809 number of pad (unassigned) symbols in each, and the overall size of the
810 sections. */
811
812 if (symtypetab_density (fp, symfp, fp->ctf_objthash, &nobjts, &maxobjt,
813 &objt_unpadsize, &objt_padsize, &objtidx_size,
814 symflags) < 0)
815 return -1; /* errno is set for us. */
816
817 ctf_dprintf ("Object symtypetab: %i objects, max %i, unpadded size %i, "
818 "%i bytes of pads, index size %i\n", (int) nobjts, (int) maxobjt,
819 (int) objt_unpadsize, (int) objt_padsize, (int) objtidx_size);
820
821 if (symtypetab_density (fp, symfp, fp->ctf_funchash, &nfuncs, &maxfunc,
822 &func_unpadsize, &func_padsize, &funcidx_size,
823 symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
824 return -1; /* errno is set for us. */
825
826 ctf_dprintf ("Function symtypetab: %i functions, max %i, unpadded size %i, "
827 "%i bytes of pads, index size %i\n", (int) nfuncs, (int) maxfunc,
828 (int) func_unpadsize, (int) func_padsize, (int) funcidx_size);
829
35a01a04
NA
830 /* If we are filtering symbols out, those symbols that the linker has not
831 reported have now been removed from the ctf_objthash and ctf_funchash.
832 Delete entries from the variable section that duplicate newly-added data
833 symbols. There's no need to migrate new ones in, because the compiler
834 always emits both a variable and a data symbol simultaneously, and
835 filtering only happens at final link time. */
1136c379 836
35a01a04
NA
837 if (filter_syms && symfp->ctf_dynsyms &&
838 symtypetab_delete_nonstatic_vars (fp, symfp) < 0)
1136c379
NA
839 return -1;
840
841 /* It is worth indexing each section if it would save space to do so, due to
842 reducing the number of pads sufficiently. A pad is the same size as a
843 single index entry: but index sections compress relatively poorly compared
844 to constant pads, so it takes a lot of contiguous padding to equal one
845 index section entry. It would be nice to be able to *verify* whether we
846 would save space after compression rather than guessing, but this seems
847 difficult, since it would require complete reserialization. Regardless, if
848 the linker has not reported any symbols (e.g. if this is not a final link
849 but just an ld -r), we must emit things in indexed fashion just as the
850 compiler does. */
851
852 objt_size = objt_unpadsize;
853 if (!(symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
854 && ((objt_padsize + objt_unpadsize) * CTF_INDEX_PAD_THRESHOLD
855 > objt_padsize))
856 {
857 objt_size += objt_padsize;
858 objtidx_size = 0;
859 }
860
861 func_size = func_unpadsize;
862 if (!(symflags & CTF_SYMTYPETAB_FORCE_INDEXED)
863 && ((func_padsize + func_unpadsize) * CTF_INDEX_PAD_THRESHOLD
864 > func_padsize))
865 {
866 func_size += func_padsize;
867 funcidx_size = 0;
868 }
869
47d546f4
NA
870 /* Computing the number of entries in the CTF variable section is much
871 simpler. */
872
873 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
874 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
875
f5e9c9bd
NA
876 /* Compute the size of the CTF buffer we need, sans only the string table,
877 then allocate a new buffer and memcpy the finished header to the start of
878 the buffer. (We will adjust this later with strtab length info.) */
47d546f4 879
1136c379
NA
880 hdr.cth_lbloff = hdr.cth_objtoff = 0;
881 hdr.cth_funcoff = hdr.cth_objtoff + objt_size;
882 hdr.cth_objtidxoff = hdr.cth_funcoff + func_size;
883 hdr.cth_funcidxoff = hdr.cth_objtidxoff + objtidx_size;
884 hdr.cth_varoff = hdr.cth_funcidxoff + funcidx_size;
47d546f4
NA
885 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
886 hdr.cth_stroff = hdr.cth_typeoff + type_size;
f5e9c9bd 887 hdr.cth_strlen = 0;
47d546f4
NA
888
889 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
890
65365aa8 891 if ((buf = malloc (buf_size)) == NULL)
47d546f4
NA
892 return (ctf_set_errno (fp, EAGAIN));
893
894 memcpy (buf, &hdr, sizeof (ctf_header_t));
1136c379 895 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_objtoff;
47d546f4 896
f5e9c9bd
NA
897 hdrp = (ctf_header_t *) buf;
898 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
899 ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
fd55eae8
NA
900 if (fp->ctf_cuname != NULL)
901 ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);
47d546f4 902
35a01a04 903 /* Sort the linker's symbols into name order if need be. */
1136c379
NA
904
905 if ((objtidx_size != 0) || (funcidx_size != 0))
906 {
907 ctf_next_t *i = NULL;
908 void *symname;
909 const char **walk;
1136c379 910
35a01a04
NA
911 if (filter_syms)
912 {
913 if (symfp->ctf_dynsyms)
914 nsymtypes = ctf_dynhash_elements (symfp->ctf_dynsyms);
915 else
916 nsymtypes = 0;
917 }
1136c379 918 else
35a01a04
NA
919 nsymtypes = ctf_dynhash_elements (fp->ctf_objthash)
920 + ctf_dynhash_elements (fp->ctf_funchash);
1136c379 921
35a01a04 922 if ((sym_name_order = calloc (nsymtypes, sizeof (const char *))) == NULL)
1136c379
NA
923 goto oom;
924
925 walk = sym_name_order;
926
35a01a04 927 if (filter_syms)
1136c379 928 {
35a01a04
NA
929 if (symfp->ctf_dynsyms)
930 {
931 while ((err = ctf_dynhash_next_sorted (symfp->ctf_dynsyms, &i,
932 &symname, NULL,
933 ctf_dynhash_sort_by_name,
934 NULL)) == 0)
935 *walk++ = (const char *) symname;
936 if (err != ECTF_NEXT_END)
937 goto symerr;
938 }
1136c379
NA
939 }
940 else
941 {
35a01a04
NA
942 ctf_hash_sort_f sort_fun = NULL;
943
944 /* Since we partition the set of symbols back into objt and func,
945 we can sort the two independently without harm. */
946 if (sort_syms)
947 sort_fun = ctf_dynhash_sort_by_name;
948
949 while ((err = ctf_dynhash_next_sorted (fp->ctf_objthash, &i, &symname,
950 NULL, sort_fun, NULL)) == 0)
1136c379
NA
951 *walk++ = (const char *) symname;
952 if (err != ECTF_NEXT_END)
953 goto symerr;
954
35a01a04
NA
955 while ((err = ctf_dynhash_next_sorted (fp->ctf_funchash, &i, &symname,
956 NULL, sort_fun, NULL)) == 0)
1136c379
NA
957 *walk++ = (const char *) symname;
958 if (err != ECTF_NEXT_END)
959 goto symerr;
960 }
961 }
962
963 /* Emit the object and function sections, and if necessary their indexes.
964 Emission is done in symtab order if there is no index, and in index
965 (name) order otherwise. */
966
35a01a04 967 if ((objtidx_size == 0) && symfp && symfp->ctf_dynsymidx)
1136c379
NA
968 {
969 ctf_dprintf ("Emitting unindexed objt symtypetab\n");
970 if (emit_symtypetab (fp, symfp, (uint32_t *) t, symfp->ctf_dynsymidx,
971 NULL, symfp->ctf_dynsymmax + 1, maxobjt, objt_size,
972 symflags | CTF_SYMTYPETAB_EMIT_PAD) < 0)
973 goto err; /* errno is set for us. */
974 }
975 else
976 {
977 ctf_dprintf ("Emitting indexed objt symtypetab\n");
978 if (emit_symtypetab (fp, symfp, (uint32_t *) t, NULL, sym_name_order,
35a01a04 979 nsymtypes, maxobjt, objt_size, symflags) < 0)
1136c379
NA
980 goto err; /* errno is set for us. */
981 }
982
983 t += objt_size;
984
35a01a04 985 if ((funcidx_size == 0) && symfp && symfp->ctf_dynsymidx)
1136c379
NA
986 {
987 ctf_dprintf ("Emitting unindexed func symtypetab\n");
988 if (emit_symtypetab (fp, symfp, (uint32_t *) t, symfp->ctf_dynsymidx,
989 NULL, symfp->ctf_dynsymmax + 1, maxfunc,
990 func_size, symflags | CTF_SYMTYPETAB_EMIT_FUNCTION
991 | CTF_SYMTYPETAB_EMIT_PAD) < 0)
992 goto err; /* errno is set for us. */
993 }
994 else
995 {
996 ctf_dprintf ("Emitting indexed func symtypetab\n");
997 if (emit_symtypetab (fp, symfp, (uint32_t *) t, NULL, sym_name_order,
35a01a04 998 nsymtypes, maxfunc, func_size,
1136c379
NA
999 symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
1000 goto err; /* errno is set for us. */
1001 }
1002
1003 t += func_size;
1004
1005 if (objtidx_size > 0)
1006 if (emit_symtypetab_index (fp, symfp, (uint32_t *) t, sym_name_order,
35a01a04 1007 nsymtypes, objtidx_size, symflags) < 0)
1136c379
NA
1008 goto err;
1009
1010 t += objtidx_size;
1011
1012 if (funcidx_size > 0)
1013 if (emit_symtypetab_index (fp, symfp, (uint32_t *) t, sym_name_order,
35a01a04 1014 nsymtypes, funcidx_size,
1136c379
NA
1015 symflags | CTF_SYMTYPETAB_EMIT_FUNCTION) < 0)
1016 goto err;
1017
1018 t += funcidx_size;
1019 free (sym_name_order);
1020 sym_name_order = NULL;
1021
f5e9c9bd
NA
1022 /* Work over the variable list, translating everything into ctf_varent_t's and
1023 prepping the string table. */
47d546f4
NA
1024
1025 dvarents = (ctf_varent_t *) t;
1026 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
1027 dvd = ctf_list_next (dvd), i++)
1028 {
1029 ctf_varent_t *var = &dvarents[i];
47d546f4 1030
f5e9c9bd 1031 ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
9943fa3a 1032 var->ctv_type = (uint32_t) dvd->dvd_type;
47d546f4
NA
1033 }
1034 assert (i == nvars);
1035
47d546f4
NA
1036 t += sizeof (ctf_varent_t) * nvars;
1037
1038 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
1039
f5e9c9bd
NA
1040 /* We now take a final lap through the dynamic type definition list and copy
1041 the appropriate type records to the output buffer, noting down the
1042 strings as we go. */
47d546f4
NA
1043
1044 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
1045 dtd != NULL; dtd = ctf_list_next (dtd))
1046 {
47d546f4
NA
1047 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1048 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1049
1050 ctf_array_t cta;
1051 uint32_t encoding;
1052 size_t len;
f5e9c9bd 1053 ctf_stype_t *copied;
676c3ecb 1054 const char *name;
47d546f4
NA
1055
1056 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
1057 len = sizeof (ctf_stype_t);
1058 else
1059 len = sizeof (ctf_type_t);
1060
1061 memcpy (t, &dtd->dtd_data, len);
f5e9c9bd 1062 copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */
676c3ecb
NA
1063 if (copied->ctt_name
1064 && (name = ctf_strraw (fp, copied->ctt_name)) != NULL)
1065 ctf_str_add_ref (fp, name, &copied->ctt_name);
47d546f4
NA
1066 t += len;
1067
1068 switch (kind)
1069 {
1070 case CTF_K_INTEGER:
1071 case CTF_K_FLOAT:
1072 if (kind == CTF_K_INTEGER)
1073 {
1074 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
1075 dtd->dtd_u.dtu_enc.cte_offset,
1076 dtd->dtd_u.dtu_enc.cte_bits);
1077 }
1078 else
1079 {
1080 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
1081 dtd->dtd_u.dtu_enc.cte_offset,
1082 dtd->dtd_u.dtu_enc.cte_bits);
1083 }
1084 memcpy (t, &encoding, sizeof (encoding));
1085 t += sizeof (encoding);
1086 break;
1087
1088 case CTF_K_SLICE:
1089 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
1090 t += sizeof (struct ctf_slice);
1091 break;
1092
1093 case CTF_K_ARRAY:
1094 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
1095 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
1096 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
1097 memcpy (t, &cta, sizeof (cta));
1098 t += sizeof (cta);
1099 break;
1100
1101 case CTF_K_FUNCTION:
1102 {
1103 uint32_t *argv = (uint32_t *) (uintptr_t) t;
1104 uint32_t argc;
1105
1106 for (argc = 0; argc < vlen; argc++)
afd78bd6 1107 *argv++ = dtd->dtd_u.dtu_argv[argc];
47d546f4
NA
1108
1109 if (vlen & 1)
1110 *argv++ = 0; /* Pad to 4-byte boundary. */
1111
1112 t = (unsigned char *) argv;
1113 break;
1114 }
1115
1116 case CTF_K_STRUCT:
1117 case CTF_K_UNION:
1118 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
f5e9c9bd 1119 t = ctf_copy_smembers (fp, dtd, t);
47d546f4 1120 else
f5e9c9bd 1121 t = ctf_copy_lmembers (fp, dtd, t);
47d546f4
NA
1122 break;
1123
1124 case CTF_K_ENUM:
f5e9c9bd 1125 t = ctf_copy_emembers (fp, dtd, t);
47d546f4
NA
1126 break;
1127 }
1128 }
1129 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
1130
f5e9c9bd
NA
1131 /* Construct the final string table and fill out all the string refs with the
1132 final offsets. Then purge the refs list, because we're about to move this
1133 strtab onto the end of the buf, invalidating all the offsets. */
1134 strtab = ctf_str_write_strtab (fp);
1135 ctf_str_purge_refs (fp);
1136
d851ecd3 1137 if (strtab.cts_strs == NULL)
1136c379 1138 goto oom;
d851ecd3 1139
f5e9c9bd
NA
1140 /* Now the string table is constructed, we can sort the buffer of
1141 ctf_varent_t's. */
d851ecd3 1142 ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) &strtab };
f5e9c9bd 1143 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
d851ecd3 1144 &sort_var_arg);
f5e9c9bd
NA
1145
1146 if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
1147 {
de07e349 1148 free (strtab.cts_strs);
1136c379 1149 goto oom;
f5e9c9bd
NA
1150 }
1151 buf = newbuf;
1152 memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
1153 hdrp = (ctf_header_t *) buf;
1154 hdrp->cth_strlen = strtab.cts_len;
1155 buf_size += hdrp->cth_strlen;
de07e349 1156 free (strtab.cts_strs);
f5e9c9bd 1157
139633c3
NA
1158 /* Finally, we are ready to ctf_simple_open() the new dict. If this is
1159 successful, we then switch nfp and fp and free the old dict. */
47d546f4 1160
d851ecd3
NA
1161 if ((nfp = ctf_simple_open_internal ((char *) buf, buf_size, NULL, 0,
1162 0, NULL, 0, fp->ctf_syn_ext_strtab,
676c3ecb 1163 1, &err)) == NULL)
47d546f4 1164 {
de07e349 1165 free (buf);
47d546f4
NA
1166 return (ctf_set_errno (fp, err));
1167 }
1168
1169 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
47d546f4 1170
1fa7a0c2
NA
1171 nfp->ctf_parent = fp->ctf_parent;
1172 nfp->ctf_parent_unreffed = fp->ctf_parent_unreffed;
47d546f4
NA
1173 nfp->ctf_refcnt = fp->ctf_refcnt;
1174 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
fd55eae8
NA
1175 if (nfp->ctf_dynbase == NULL)
1176 nfp->ctf_dynbase = buf; /* Make sure buf is freed on close. */
47d546f4
NA
1177 nfp->ctf_dthash = fp->ctf_dthash;
1178 nfp->ctf_dtdefs = fp->ctf_dtdefs;
47d546f4
NA
1179 nfp->ctf_dvhash = fp->ctf_dvhash;
1180 nfp->ctf_dvdefs = fp->ctf_dvdefs;
676c3ecb 1181 nfp->ctf_dtoldid = fp->ctf_dtoldid;
99dc3ebd 1182 nfp->ctf_add_processing = fp->ctf_add_processing;
47d546f4
NA
1183 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
1184 nfp->ctf_specific = fp->ctf_specific;
1136c379
NA
1185 nfp->ctf_nfuncidx = fp->ctf_nfuncidx;
1186 nfp->ctf_nobjtidx = fp->ctf_nobjtidx;
1187 nfp->ctf_objthash = fp->ctf_objthash;
1188 nfp->ctf_funchash = fp->ctf_funchash;
1189 nfp->ctf_dynsyms = fp->ctf_dynsyms;
676c3ecb 1190 nfp->ctf_ptrtab = fp->ctf_ptrtab;
abe4ca69 1191 nfp->ctf_pptrtab = fp->ctf_pptrtab;
1136c379
NA
1192 nfp->ctf_dynsymidx = fp->ctf_dynsymidx;
1193 nfp->ctf_dynsymmax = fp->ctf_dynsymmax;
676c3ecb 1194 nfp->ctf_ptrtab_len = fp->ctf_ptrtab_len;
abe4ca69 1195 nfp->ctf_pptrtab_len = fp->ctf_pptrtab_len;
72c83edd
NA
1196 nfp->ctf_link_inputs = fp->ctf_link_inputs;
1197 nfp->ctf_link_outputs = fp->ctf_link_outputs;
8b37e7b6 1198 nfp->ctf_errs_warnings = fp->ctf_errs_warnings;
1136c379
NA
1199 nfp->ctf_funcidx_names = fp->ctf_funcidx_names;
1200 nfp->ctf_objtidx_names = fp->ctf_objtidx_names;
1201 nfp->ctf_funcidx_sxlate = fp->ctf_funcidx_sxlate;
1202 nfp->ctf_objtidx_sxlate = fp->ctf_objtidx_sxlate;
676c3ecb 1203 nfp->ctf_str_prov_offset = fp->ctf_str_prov_offset;
d851ecd3 1204 nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
abe4ca69 1205 nfp->ctf_pptrtab_typemax = fp->ctf_pptrtab_typemax;
1136c379 1206 nfp->ctf_in_flight_dynsyms = fp->ctf_in_flight_dynsyms;
5f54462c
NA
1207 nfp->ctf_link_in_cu_mapping = fp->ctf_link_in_cu_mapping;
1208 nfp->ctf_link_out_cu_mapping = fp->ctf_link_out_cu_mapping;
886453cb 1209 nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
49ea9b45
NA
1210 nfp->ctf_link_memb_name_changer = fp->ctf_link_memb_name_changer;
1211 nfp->ctf_link_memb_name_changer_arg = fp->ctf_link_memb_name_changer_arg;
6dd2819f
NA
1212 nfp->ctf_link_variable_filter = fp->ctf_link_variable_filter;
1213 nfp->ctf_link_variable_filter_arg = fp->ctf_link_variable_filter_arg;
53651de8 1214 nfp->ctf_symsect_little_endian = fp->ctf_symsect_little_endian;
8d2229ad 1215 nfp->ctf_link_flags = fp->ctf_link_flags;
0f0c11f7
NA
1216 nfp->ctf_dedup_atoms = fp->ctf_dedup_atoms;
1217 nfp->ctf_dedup_atoms_alloc = fp->ctf_dedup_atoms_alloc;
1218 memcpy (&nfp->ctf_dedup, &fp->ctf_dedup, sizeof (fp->ctf_dedup));
47d546f4
NA
1219
1220 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
1221
676c3ecb
NA
1222 memcpy (&nfp->ctf_lookups, fp->ctf_lookups, sizeof (fp->ctf_lookups));
1223 nfp->ctf_structs = fp->ctf_structs;
1224 nfp->ctf_unions = fp->ctf_unions;
1225 nfp->ctf_enums = fp->ctf_enums;
1226 nfp->ctf_names = fp->ctf_names;
1227
47d546f4 1228 fp->ctf_dthash = NULL;
f5e9c9bd
NA
1229 ctf_str_free_atoms (nfp);
1230 nfp->ctf_str_atoms = fp->ctf_str_atoms;
676c3ecb 1231 nfp->ctf_prov_strtab = fp->ctf_prov_strtab;
f5e9c9bd 1232 fp->ctf_str_atoms = NULL;
676c3ecb 1233 fp->ctf_prov_strtab = NULL;
47d546f4 1234 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
8b37e7b6 1235 memset (&fp->ctf_errs_warnings, 0, sizeof (ctf_list_t));
99dc3ebd 1236 fp->ctf_add_processing = NULL;
676c3ecb 1237 fp->ctf_ptrtab = NULL;
abe4ca69 1238 fp->ctf_pptrtab = NULL;
1136c379
NA
1239 fp->ctf_funcidx_names = NULL;
1240 fp->ctf_objtidx_names = NULL;
1241 fp->ctf_funcidx_sxlate = NULL;
1242 fp->ctf_objtidx_sxlate = NULL;
1243 fp->ctf_objthash = NULL;
1244 fp->ctf_funchash = NULL;
1245 fp->ctf_dynsyms = NULL;
1246 fp->ctf_dynsymidx = NULL;
72c83edd
NA
1247 fp->ctf_link_inputs = NULL;
1248 fp->ctf_link_outputs = NULL;
d851ecd3 1249 fp->ctf_syn_ext_strtab = NULL;
5f54462c
NA
1250 fp->ctf_link_in_cu_mapping = NULL;
1251 fp->ctf_link_out_cu_mapping = NULL;
886453cb 1252 fp->ctf_link_type_mapping = NULL;
0f0c11f7
NA
1253 fp->ctf_dedup_atoms = NULL;
1254 fp->ctf_dedup_atoms_alloc = NULL;
1fa7a0c2 1255 fp->ctf_parent_unreffed = 1;
47d546f4
NA
1256
1257 fp->ctf_dvhash = NULL;
1258 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
676c3ecb 1259 memset (fp->ctf_lookups, 0, sizeof (fp->ctf_lookups));
1136c379 1260 memset (&fp->ctf_in_flight_dynsyms, 0, sizeof (fp->ctf_in_flight_dynsyms));
0f0c11f7 1261 memset (&fp->ctf_dedup, 0, sizeof (fp->ctf_dedup));
676c3ecb
NA
1262 fp->ctf_structs.ctn_writable = NULL;
1263 fp->ctf_unions.ctn_writable = NULL;
1264 fp->ctf_enums.ctn_writable = NULL;
1265 fp->ctf_names.ctn_writable = NULL;
47d546f4 1266
139633c3
NA
1267 memcpy (&ofp, fp, sizeof (ctf_dict_t));
1268 memcpy (fp, nfp, sizeof (ctf_dict_t));
1269 memcpy (nfp, &ofp, sizeof (ctf_dict_t));
47d546f4 1270
1136c379 1271 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
139633c3 1272 ctf_dict_close (nfp);
47d546f4
NA
1273
1274 return 0;
1136c379
NA
1275
1276symerr:
1277 ctf_err_warn (fp, 0, err, _("error serializing symtypetabs"));
1278 goto err;
1279oom:
1280 free (buf);
1281 free (sym_name_order);
1282 return (ctf_set_errno (fp, EAGAIN));
1283err:
1284 free (buf);
1285 free (sym_name_order);
1286 return -1; /* errno is set for us. */
47d546f4
NA
1287}
1288
676c3ecb 1289ctf_names_t *
139633c3 1290ctf_name_table (ctf_dict_t *fp, int kind)
47d546f4 1291{
47d546f4
NA
1292 switch (kind)
1293 {
1294 case CTF_K_STRUCT:
676c3ecb 1295 return &fp->ctf_structs;
47d546f4 1296 case CTF_K_UNION:
676c3ecb 1297 return &fp->ctf_unions;
47d546f4 1298 case CTF_K_ENUM:
676c3ecb 1299 return &fp->ctf_enums;
47d546f4 1300 default:
676c3ecb 1301 return &fp->ctf_names;
47d546f4 1302 }
47d546f4
NA
1303}
1304
24865428 1305int
139633c3 1306ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
47d546f4 1307{
676c3ecb 1308 const char *name;
8c419a91
NA
1309 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
1310 dtd) < 0)
8f235c90
NA
1311 {
1312 ctf_set_errno (fp, ENOMEM);
1313 return -1;
1314 }
24865428 1315
fe4c2d55 1316 if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
676c3ecb 1317 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
47d546f4 1318 {
676c3ecb 1319 if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable,
8c419a91
NA
1320 (char *) name, (void *) (uintptr_t)
1321 dtd->dtd_type) < 0)
676c3ecb 1322 {
8c419a91
NA
1323 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
1324 dtd->dtd_type);
8f235c90 1325 ctf_set_errno (fp, ENOMEM);
676c3ecb
NA
1326 return -1;
1327 }
47d546f4 1328 }
24865428
NA
1329 ctf_list_append (&fp->ctf_dtdefs, dtd);
1330 return 0;
47d546f4
NA
1331}
1332
1333void
139633c3 1334ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
47d546f4
NA
1335{
1336 ctf_dmdef_t *dmd, *nmd;
1337 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
8ffcdf18 1338 int name_kind = kind;
676c3ecb 1339 const char *name;
47d546f4 1340
8c419a91 1341 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
47d546f4
NA
1342
1343 switch (kind)
1344 {
1345 case CTF_K_STRUCT:
1346 case CTF_K_UNION:
1347 case CTF_K_ENUM:
1348 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1349 dmd != NULL; dmd = nmd)
1350 {
1351 if (dmd->dmd_name != NULL)
de07e349 1352 free (dmd->dmd_name);
47d546f4 1353 nmd = ctf_list_next (dmd);
de07e349 1354 free (dmd);
47d546f4
NA
1355 }
1356 break;
1357 case CTF_K_FUNCTION:
de07e349 1358 free (dtd->dtd_u.dtu_argv);
47d546f4 1359 break;
8ffcdf18
NA
1360 case CTF_K_FORWARD:
1361 name_kind = dtd->dtd_data.ctt_type;
1362 break;
47d546f4
NA
1363 }
1364
676c3ecb 1365 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
1366 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
1367 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
47d546f4 1368 {
8ffcdf18 1369 ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
676c3ecb
NA
1370 name);
1371 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
1372 }
1373
1374 ctf_list_delete (&fp->ctf_dtdefs, dtd);
de07e349 1375 free (dtd);
47d546f4
NA
1376}
1377
1378ctf_dtdef_t *
139633c3 1379ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
47d546f4 1380{
8c419a91
NA
1381 return (ctf_dtdef_t *)
1382 ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
47d546f4
NA
1383}
1384
47d546f4 1385ctf_dtdef_t *
139633c3 1386ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
47d546f4
NA
1387{
1388 ctf_id_t idx;
1389
676c3ecb
NA
1390 if (!(fp->ctf_flags & LCTF_RDWR))
1391 return NULL;
1392
47d546f4
NA
1393 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
1394 fp = fp->ctf_parent;
1395
1396 idx = LCTF_TYPE_TO_INDEX(fp, id);
1397
676c3ecb 1398 if ((unsigned long) idx <= fp->ctf_typemax)
47d546f4
NA
1399 return ctf_dtd_lookup (fp, id);
1400 return NULL;
1401}
1402
24865428 1403int
139633c3 1404ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
47d546f4 1405{
24865428 1406 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
8f235c90
NA
1407 {
1408 ctf_set_errno (fp, ENOMEM);
1409 return -1;
1410 }
47d546f4 1411 ctf_list_append (&fp->ctf_dvdefs, dvd);
24865428 1412 return 0;
47d546f4
NA
1413}
1414
1415void
139633c3 1416ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
47d546f4
NA
1417{
1418 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
de07e349 1419 free (dvd->dvd_name);
47d546f4
NA
1420
1421 ctf_list_delete (&fp->ctf_dvdefs, dvd);
de07e349 1422 free (dvd);
47d546f4
NA
1423}
1424
1425ctf_dvdef_t *
139633c3 1426ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
47d546f4
NA
1427{
1428 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
1429}
1430
1431/* Discard all of the dynamic type definitions and variable definitions that
139633c3
NA
1432 have been added to the dict since the last call to ctf_update(). We locate
1433 such types by scanning the dtd list and deleting elements that have type IDs
1434 greater than ctf_dtoldid, which is set by ctf_update(), above, and by
1435 scanning the variable list and deleting elements that have update IDs equal
1436 to the current value of the last-update snapshot count (indicating that they
1437 were added after the most recent call to ctf_update()). */
47d546f4 1438int
139633c3 1439ctf_discard (ctf_dict_t *fp)
47d546f4
NA
1440{
1441 ctf_snapshot_id_t last_update =
1442 { fp->ctf_dtoldid,
1443 fp->ctf_snapshot_lu + 1 };
1444
1445 /* Update required? */
1446 if (!(fp->ctf_flags & LCTF_DIRTY))
1447 return 0;
1448
1449 return (ctf_rollback (fp, last_update));
1450}
1451
1452ctf_snapshot_id_t
139633c3 1453ctf_snapshot (ctf_dict_t *fp)
47d546f4
NA
1454{
1455 ctf_snapshot_id_t snapid;
676c3ecb 1456 snapid.dtd_id = fp->ctf_typemax;
47d546f4
NA
1457 snapid.snapshot_id = fp->ctf_snapshots++;
1458 return snapid;
1459}
1460
1461/* Like ctf_discard(), only discards everything after a particular ID. */
1462int
139633c3 1463ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
47d546f4
NA
1464{
1465 ctf_dtdef_t *dtd, *ntd;
1466 ctf_dvdef_t *dvd, *nvd;
1467
1468 if (!(fp->ctf_flags & LCTF_RDWR))
1469 return (ctf_set_errno (fp, ECTF_RDONLY));
1470
47d546f4
NA
1471 if (fp->ctf_snapshot_lu >= id.snapshot_id)
1472 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
1473
1474 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
1475 {
676c3ecb
NA
1476 int kind;
1477 const char *name;
1478
47d546f4
NA
1479 ntd = ctf_list_next (dtd);
1480
1481 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
1482 continue;
1483
676c3ecb 1484 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
8ffcdf18
NA
1485 if (kind == CTF_K_FORWARD)
1486 kind = dtd->dtd_data.ctt_type;
676c3ecb
NA
1487
1488 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
1489 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
1490 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
676c3ecb
NA
1491 {
1492 ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
1493 name);
1494 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
1495 }
1496
8c419a91 1497 ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
47d546f4
NA
1498 ctf_dtd_delete (fp, dtd);
1499 }
1500
1501 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
1502 {
1503 nvd = ctf_list_next (dvd);
1504
1505 if (dvd->dvd_snapshots <= id.snapshot_id)
1506 continue;
1507
1508 ctf_dvd_delete (fp, dvd);
1509 }
1510
676c3ecb 1511 fp->ctf_typemax = id.dtd_id;
47d546f4
NA
1512 fp->ctf_snapshots = id.snapshot_id;
1513
1514 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
1515 fp->ctf_flags &= ~LCTF_DIRTY;
1516
1517 return 0;
1518}
1519
1520static ctf_id_t
139633c3 1521ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
47d546f4
NA
1522 ctf_dtdef_t **rp)
1523{
1524 ctf_dtdef_t *dtd;
1525 ctf_id_t type;
47d546f4
NA
1526
1527 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
1528 return (ctf_set_errno (fp, EINVAL));
1529
1530 if (!(fp->ctf_flags & LCTF_RDWR))
1531 return (ctf_set_errno (fp, ECTF_RDONLY));
1532
676c3ecb 1533 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
47d546f4
NA
1534 return (ctf_set_errno (fp, ECTF_FULL));
1535
676c3ecb 1536 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
47d546f4
NA
1537 return (ctf_set_errno (fp, ECTF_FULL));
1538
676c3ecb
NA
1539 /* Make sure ptrtab always grows to be big enough for all types. */
1540 if (ctf_grow_ptrtab (fp) < 0)
1541 return CTF_ERR; /* errno is set for us. */
1542
de07e349 1543 if ((dtd = malloc (sizeof (ctf_dtdef_t))) == NULL)
47d546f4
NA
1544 return (ctf_set_errno (fp, EAGAIN));
1545
676c3ecb 1546 type = ++fp->ctf_typemax;
47d546f4
NA
1547 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
1548
1549 memset (dtd, 0, sizeof (ctf_dtdef_t));
676c3ecb 1550 dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
1551 dtd->dtd_type = type;
1552
676c3ecb
NA
1553 if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
1554 {
de07e349 1555 free (dtd);
676c3ecb
NA
1556 return (ctf_set_errno (fp, EAGAIN));
1557 }
1558
fe4c2d55 1559 if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
24865428 1560 {
de07e349 1561 free (dtd);
24865428
NA
1562 return CTF_ERR; /* errno is set for us. */
1563 }
47d546f4
NA
1564 fp->ctf_flags |= LCTF_DIRTY;
1565
1566 *rp = dtd;
1567 return type;
1568}
1569
1570/* When encoding integer sizes, we want to convert a byte count in the range
1571 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
1572 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
1573static size_t
1574clp2 (size_t x)
1575{
1576 x--;
1577
1578 x |= (x >> 1);
1579 x |= (x >> 2);
1580 x |= (x >> 4);
1581 x |= (x >> 8);
1582 x |= (x >> 16);
1583
1584 return (x + 1);
1585}
1586
0f0c11f7 1587ctf_id_t
139633c3 1588ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
47d546f4
NA
1589 const char *name, const ctf_encoding_t *ep, uint32_t kind)
1590{
1591 ctf_dtdef_t *dtd;
1592 ctf_id_t type;
1593
1594 if (ep == NULL)
1595 return (ctf_set_errno (fp, EINVAL));
1596
caa17049
NA
1597 if (name == NULL || name[0] == '\0')
1598 return (ctf_set_errno (fp, ECTF_NONAME));
1599
676c3ecb 1600 if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
47d546f4
NA
1601 return CTF_ERR; /* errno is set for us. */
1602
1603 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
76fad999
TT
1604 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
1605 / CHAR_BIT);
47d546f4
NA
1606 dtd->dtd_u.dtu_enc = *ep;
1607
1608 return type;
1609}
1610
0f0c11f7 1611ctf_id_t
139633c3 1612ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
47d546f4
NA
1613{
1614 ctf_dtdef_t *dtd;
1615 ctf_id_t type;
139633c3 1616 ctf_dict_t *tmp = fp;
676c3ecb 1617 int child = fp->ctf_flags & LCTF_CHILD;
47d546f4 1618
a0486bac 1619 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1620 return (ctf_set_errno (fp, EINVAL));
1621
2361f1c8 1622 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
47d546f4
NA
1623 return CTF_ERR; /* errno is set for us. */
1624
676c3ecb 1625 if ((type = ctf_add_generic (fp, flag, NULL, kind, &dtd)) == CTF_ERR)
47d546f4
NA
1626 return CTF_ERR; /* errno is set for us. */
1627
1628 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
1629 dtd->dtd_data.ctt_type = (uint32_t) ref;
1630
676c3ecb
NA
1631 if (kind != CTF_K_POINTER)
1632 return type;
1633
78f28b89
NA
1634 /* If we are adding a pointer, update the ptrtab, pointing at this type from
1635 the type it points to. Note that ctf_typemax is at this point one higher
1636 than we want to check against, because it's just been incremented for the
1637 addition of this type. The pptrtab is lazily-updated as needed, so is not
1638 touched here. */
676c3ecb
NA
1639
1640 uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
1641 uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
1642
1643 if (LCTF_TYPE_ISCHILD (fp, ref) == child
1644 && ref_idx < fp->ctf_typemax)
78f28b89 1645 fp->ctf_ptrtab[ref_idx] = type_idx;
676c3ecb 1646
47d546f4
NA
1647 return type;
1648}
1649
1650ctf_id_t
139633c3 1651ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
47d546f4
NA
1652 const ctf_encoding_t *ep)
1653{
1654 ctf_dtdef_t *dtd;
502e838e 1655 ctf_id_t resolved_ref = ref;
47d546f4
NA
1656 ctf_id_t type;
1657 int kind;
1658 const ctf_type_t *tp;
139633c3 1659 ctf_dict_t *tmp = fp;
47d546f4
NA
1660
1661 if (ep == NULL)
1662 return (ctf_set_errno (fp, EINVAL));
1663
1664 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
1665 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
1666
a0486bac 1667 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1668 return (ctf_set_errno (fp, EINVAL));
1669
2361f1c8 1670 if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
47d546f4
NA
1671 return CTF_ERR; /* errno is set for us. */
1672
502e838e
NA
1673 /* Make sure we ultimately point to an integral type. We also allow slices to
1674 point to the unimplemented type, for now, because the compiler can emit
1675 such slices, though they're not very much use. */
1676
1677 resolved_ref = ctf_type_resolve_unsliced (tmp, ref);
1678 kind = ctf_type_kind_unsliced (tmp, resolved_ref);
1679
47d546f4 1680 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
2361f1c8
NA
1681 (kind != CTF_K_ENUM)
1682 && (ref != 0))
47d546f4
NA
1683 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1684
676c3ecb 1685 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE, &dtd)) == CTF_ERR)
47d546f4
NA
1686 return CTF_ERR; /* errno is set for us. */
1687
1688 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
76fad999
TT
1689 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
1690 / CHAR_BIT);
9943fa3a 1691 dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref;
47d546f4
NA
1692 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
1693 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
1694
1695 return type;
1696}
1697
1698ctf_id_t
139633c3 1699ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
47d546f4
NA
1700 const char *name, const ctf_encoding_t *ep)
1701{
1702 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
1703}
1704
1705ctf_id_t
139633c3 1706ctf_add_float (ctf_dict_t *fp, uint32_t flag,
47d546f4
NA
1707 const char *name, const ctf_encoding_t *ep)
1708{
1709 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
1710}
1711
1712ctf_id_t
139633c3 1713ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
47d546f4
NA
1714{
1715 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
1716}
1717
1718ctf_id_t
139633c3 1719ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
47d546f4
NA
1720{
1721 ctf_dtdef_t *dtd;
1722 ctf_id_t type;
139633c3 1723 ctf_dict_t *tmp = fp;
47d546f4
NA
1724
1725 if (arp == NULL)
1726 return (ctf_set_errno (fp, EINVAL));
1727
2361f1c8
NA
1728 if (arp->ctr_contents != 0
1729 && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
47d546f4
NA
1730 return CTF_ERR; /* errno is set for us. */
1731
1732 tmp = fp;
1733 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
1734 return CTF_ERR; /* errno is set for us. */
1735
ffeece6a
NA
1736 if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
1737 {
1738 ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
1739 _("ctf_add_array: index type %lx is incomplete"),
1740 arp->ctr_contents);
1741 return (ctf_set_errno (fp, ECTF_INCOMPLETE));
1742 }
1743
676c3ecb 1744 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY, &dtd)) == CTF_ERR)
47d546f4
NA
1745 return CTF_ERR; /* errno is set for us. */
1746
1747 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
1748 dtd->dtd_data.ctt_size = 0;
1749 dtd->dtd_u.dtu_arr = *arp;
1750
1751 return type;
1752}
1753
1754int
139633c3 1755ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
47d546f4
NA
1756{
1757 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1758
1759 if (!(fp->ctf_flags & LCTF_RDWR))
1760 return (ctf_set_errno (fp, ECTF_RDONLY));
1761
1762 if (dtd == NULL
1763 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
1764 return (ctf_set_errno (fp, ECTF_BADID));
1765
1766 fp->ctf_flags |= LCTF_DIRTY;
1767 dtd->dtd_u.dtu_arr = *arp;
1768
1769 return 0;
1770}
1771
1772ctf_id_t
139633c3 1773ctf_add_function (ctf_dict_t *fp, uint32_t flag,
47d546f4
NA
1774 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
1775{
1776 ctf_dtdef_t *dtd;
1777 ctf_id_t type;
1778 uint32_t vlen;
afd78bd6 1779 uint32_t *vdat = NULL;
139633c3 1780 ctf_dict_t *tmp = fp;
47d546f4
NA
1781 size_t i;
1782
8f235c90
NA
1783 if (!(fp->ctf_flags & LCTF_RDWR))
1784 return (ctf_set_errno (fp, ECTF_RDONLY));
1785
47d546f4
NA
1786 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
1787 || (ctc->ctc_argc != 0 && argv == NULL))
1788 return (ctf_set_errno (fp, EINVAL));
1789
1790 vlen = ctc->ctc_argc;
1791 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1792 vlen++; /* Add trailing zero to indicate varargs (see below). */
1793
2361f1c8
NA
1794 if (ctc->ctc_return != 0
1795 && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
47d546f4
NA
1796 return CTF_ERR; /* errno is set for us. */
1797
47d546f4
NA
1798 if (vlen > CTF_MAX_VLEN)
1799 return (ctf_set_errno (fp, EOVERFLOW));
1800
de07e349 1801 if (vlen != 0 && (vdat = malloc (sizeof (ctf_id_t) * vlen)) == NULL)
47d546f4
NA
1802 return (ctf_set_errno (fp, EAGAIN));
1803
afd78bd6
NA
1804 for (i = 0; i < ctc->ctc_argc; i++)
1805 {
1806 tmp = fp;
1807 if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
1808 {
1809 free (vdat);
1810 return CTF_ERR; /* errno is set for us. */
1811 }
1812 vdat[i] = (uint32_t) argv[i];
1813 }
1814
676c3ecb
NA
1815 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
1816 &dtd)) == CTF_ERR)
47d546f4 1817 {
de07e349 1818 free (vdat);
47d546f4
NA
1819 return CTF_ERR; /* errno is set for us. */
1820 }
1821
1822 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
1823 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
1824
47d546f4
NA
1825 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1826 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
1827 dtd->dtd_u.dtu_argv = vdat;
1828
1829 return type;
1830}
1831
1832ctf_id_t
139633c3 1833ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
47d546f4
NA
1834 size_t size)
1835{
47d546f4
NA
1836 ctf_dtdef_t *dtd;
1837 ctf_id_t type = 0;
1838
fe4c2d55 1839 /* Promote root-visible forwards to structs. */
47d546f4 1840 if (name != NULL)
676c3ecb 1841 type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
47d546f4
NA
1842
1843 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1844 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1845 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
1846 &dtd)) == CTF_ERR)
47d546f4
NA
1847 return CTF_ERR; /* errno is set for us. */
1848
1849 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1850
1851 if (size > CTF_MAX_SIZE)
1852 {
1853 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1854 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1855 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1856 }
1857 else
1858 dtd->dtd_data.ctt_size = (uint32_t) size;
1859
1860 return type;
1861}
1862
1863ctf_id_t
139633c3 1864ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
47d546f4
NA
1865{
1866 return (ctf_add_struct_sized (fp, flag, name, 0));
1867}
1868
1869ctf_id_t
139633c3 1870ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
47d546f4
NA
1871 size_t size)
1872{
47d546f4
NA
1873 ctf_dtdef_t *dtd;
1874 ctf_id_t type = 0;
1875
fe4c2d55 1876 /* Promote root-visible forwards to unions. */
47d546f4 1877 if (name != NULL)
676c3ecb 1878 type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
47d546f4
NA
1879
1880 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1881 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1882 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
1883 &dtd)) == CTF_ERR)
47d546f4
NA
1884 return CTF_ERR; /* errno is set for us */
1885
1886 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1887
1888 if (size > CTF_MAX_SIZE)
1889 {
1890 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1891 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1892 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1893 }
1894 else
1895 dtd->dtd_data.ctt_size = (uint32_t) size;
1896
1897 return type;
1898}
1899
1900ctf_id_t
139633c3 1901ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
47d546f4
NA
1902{
1903 return (ctf_add_union_sized (fp, flag, name, 0));
1904}
1905
1906ctf_id_t
139633c3 1907ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
47d546f4 1908{
47d546f4
NA
1909 ctf_dtdef_t *dtd;
1910 ctf_id_t type = 0;
1911
fe4c2d55 1912 /* Promote root-visible forwards to enums. */
47d546f4 1913 if (name != NULL)
676c3ecb 1914 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1915
1916 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1917 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1918 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
1919 &dtd)) == CTF_ERR)
47d546f4
NA
1920 return CTF_ERR; /* errno is set for us. */
1921
1922 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1923 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1924
1925 return type;
1926}
1927
1928ctf_id_t
139633c3 1929ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
47d546f4
NA
1930 const ctf_encoding_t *ep)
1931{
47d546f4
NA
1932 ctf_id_t type = 0;
1933
1934 /* First, create the enum if need be, using most of the same machinery as
1935 ctf_add_enum(), to ensure that we do not allow things past that are not
1936 enums or forwards to them. (This includes other slices: you cannot slice a
1937 slice, which would be a useless thing to do anyway.) */
1938
1939 if (name != NULL)
676c3ecb 1940 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1941
1942 if (type != 0)
1943 {
1944 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1945 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1946 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1947 }
1948 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1949 return CTF_ERR; /* errno is set for us. */
1950
1951 /* Now attach a suitable slice to it. */
1952
1953 return ctf_add_slice (fp, flag, type, ep);
1954}
1955
1956ctf_id_t
139633c3 1957ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
47d546f4
NA
1958 uint32_t kind)
1959{
47d546f4
NA
1960 ctf_dtdef_t *dtd;
1961 ctf_id_t type = 0;
1962
9850ce4d 1963 if (!ctf_forwardable_kind (kind))
676c3ecb 1964 return (ctf_set_errno (fp, ECTF_NOTSUE));
47d546f4 1965
caa17049
NA
1966 if (name == NULL || name[0] == '\0')
1967 return (ctf_set_errno (fp, ECTF_NONAME));
1968
47d546f4
NA
1969 /* If the type is already defined or exists as a forward tag, just
1970 return the ctf_id_t of the existing definition. */
1971
caa17049 1972 type = ctf_lookup_by_rawname (fp, kind, name);
47d546f4 1973
6bbf9da8
NA
1974 if (type)
1975 return type;
1976
8ffcdf18 1977 if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
47d546f4
NA
1978 return CTF_ERR; /* errno is set for us. */
1979
1980 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1981 dtd->dtd_data.ctt_type = kind;
1982
1983 return type;
1984}
1985
1986ctf_id_t
139633c3 1987ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
47d546f4
NA
1988 ctf_id_t ref)
1989{
1990 ctf_dtdef_t *dtd;
1991 ctf_id_t type;
139633c3 1992 ctf_dict_t *tmp = fp;
47d546f4 1993
a0486bac 1994 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1995 return (ctf_set_errno (fp, EINVAL));
1996
caa17049
NA
1997 if (name == NULL || name[0] == '\0')
1998 return (ctf_set_errno (fp, ECTF_NONAME));
1999
2361f1c8 2000 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
47d546f4
NA
2001 return CTF_ERR; /* errno is set for us. */
2002
676c3ecb
NA
2003 if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF,
2004 &dtd)) == CTF_ERR)
47d546f4
NA
2005 return CTF_ERR; /* errno is set for us. */
2006
2007 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
2008 dtd->dtd_data.ctt_type = (uint32_t) ref;
2009
2010 return type;
2011}
2012
2013ctf_id_t
139633c3 2014ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
47d546f4
NA
2015{
2016 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
2017}
2018
2019ctf_id_t
139633c3 2020ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
47d546f4
NA
2021{
2022 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
2023}
2024
2025ctf_id_t
139633c3 2026ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
47d546f4
NA
2027{
2028 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
2029}
2030
2031int
139633c3 2032ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
47d546f4
NA
2033 int value)
2034{
2035 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
2036 ctf_dmdef_t *dmd;
2037
2038 uint32_t kind, vlen, root;
2039 char *s;
2040
2041 if (name == NULL)
2042 return (ctf_set_errno (fp, EINVAL));
2043
2044 if (!(fp->ctf_flags & LCTF_RDWR))
2045 return (ctf_set_errno (fp, ECTF_RDONLY));
2046
2047 if (dtd == NULL)
2048 return (ctf_set_errno (fp, ECTF_BADID));
2049
2050 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
2051 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
2052 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
2053
2054 if (kind != CTF_K_ENUM)
2055 return (ctf_set_errno (fp, ECTF_NOTENUM));
2056
2057 if (vlen == CTF_MAX_VLEN)
2058 return (ctf_set_errno (fp, ECTF_DTFULL));
2059
2060 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
2061 dmd != NULL; dmd = ctf_list_next (dmd))
2062 {
2063 if (strcmp (dmd->dmd_name, name) == 0)
2064 return (ctf_set_errno (fp, ECTF_DUPLICATE));
2065 }
2066
de07e349 2067 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
2068 return (ctf_set_errno (fp, EAGAIN));
2069
de07e349 2070 if ((s = strdup (name)) == NULL)
47d546f4 2071 {
de07e349 2072 free (dmd);
47d546f4
NA
2073 return (ctf_set_errno (fp, EAGAIN));
2074 }
2075
2076 dmd->dmd_name = s;
2077 dmd->dmd_type = CTF_ERR;
2078 dmd->dmd_offset = 0;
2079 dmd->dmd_value = value;
2080
2081 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
2082 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
2083
47d546f4
NA
2084 fp->ctf_flags |= LCTF_DIRTY;
2085
2086 return 0;
2087}
2088
2089int
139633c3 2090ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
47d546f4
NA
2091 ctf_id_t type, unsigned long bit_offset)
2092{
2093 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
2094 ctf_dmdef_t *dmd;
2095
2096 ssize_t msize, malign, ssize;
2097 uint32_t kind, vlen, root;
2098 char *s = NULL;
ffeece6a 2099 int is_incomplete = 0;
47d546f4
NA
2100
2101 if (!(fp->ctf_flags & LCTF_RDWR))
2102 return (ctf_set_errno (fp, ECTF_RDONLY));
2103
2104 if (dtd == NULL)
2105 return (ctf_set_errno (fp, ECTF_BADID));
2106
ab769488
NA
2107 if (name != NULL && name[0] == '\0')
2108 name = NULL;
2109
47d546f4
NA
2110 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
2111 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
2112 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
2113
2114 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
2115 return (ctf_set_errno (fp, ECTF_NOTSOU));
2116
2117 if (vlen == CTF_MAX_VLEN)
2118 return (ctf_set_errno (fp, ECTF_DTFULL));
2119
2120 if (name != NULL)
2121 {
2122 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
2123 dmd != NULL; dmd = ctf_list_next (dmd))
2124 {
2125 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
2126 return (ctf_set_errno (fp, ECTF_DUPLICATE));
2127 }
2128 }
2129
a0486bac
JM
2130 if ((msize = ctf_type_size (fp, type)) < 0 ||
2131 (malign = ctf_type_align (fp, type)) < 0)
2361f1c8
NA
2132 {
2133 /* The unimplemented type, and any type that resolves to it, has no size
2134 and no alignment: it can correspond to any number of compiler-inserted
ffeece6a
NA
2135 types. We allow incomplete types through since they are routinely
2136 added to the ends of structures, and can even be added elsewhere in
2137 structures by the deduplicator. They are assumed to be zero-size with
2138 no alignment: this is often wrong, but problems can be avoided in this
2139 case by explicitly specifying the size of the structure via the _sized
2140 functions. The deduplicator always does this. */
2141
2142 msize = 0;
2143 malign = 0;
2361f1c8 2144 if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
ffeece6a
NA
2145 ctf_set_errno (fp, 0);
2146 else if (ctf_errno (fp) == ECTF_INCOMPLETE)
2147 is_incomplete = 1;
2361f1c8
NA
2148 else
2149 return -1; /* errno is set for us. */
2150 }
47d546f4 2151
de07e349 2152 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
2153 return (ctf_set_errno (fp, EAGAIN));
2154
de07e349 2155 if (name != NULL && (s = strdup (name)) == NULL)
47d546f4 2156 {
de07e349 2157 free (dmd);
47d546f4
NA
2158 return (ctf_set_errno (fp, EAGAIN));
2159 }
2160
2161 dmd->dmd_name = s;
2162 dmd->dmd_type = type;
2163 dmd->dmd_value = -1;
2164
2165 if (kind == CTF_K_STRUCT && vlen != 0)
2166 {
2167 if (bit_offset == (unsigned long) - 1)
2168 {
2169 /* Natural alignment. */
2170
2171 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
2172 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
2173 size_t off = lmd->dmd_offset;
2174
2175 ctf_encoding_t linfo;
2176 ssize_t lsize;
2177
2361f1c8
NA
2178 /* Propagate any error from ctf_type_resolve. If the last member was
2179 of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
2180 cannot insert right after such a member without explicit offset
2181 specification, because its alignment and size is not known. */
2182 if (ltype == CTF_ERR)
2183 {
2184 free (dmd);
2185 return -1; /* errno is set for us. */
2186 }
2187
ffeece6a
NA
2188 if (is_incomplete)
2189 {
2190 ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
2191 _("ctf_add_member_offset: cannot add member %s of "
2192 "incomplete type %lx to struct %lx without "
2193 "specifying explicit offset\n"),
2194 name ? name : _("(unnamed member)"), type, souid);
2195 return (ctf_set_errno (fp, ECTF_INCOMPLETE));
2196 }
2197
a0486bac 2198 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
47d546f4 2199 off += linfo.cte_bits;
a0486bac 2200 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
76fad999 2201 off += lsize * CHAR_BIT;
ffeece6a
NA
2202 else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
2203 {
2204 ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
2205 _("ctf_add_member_offset: cannot add member %s of "
2206 "type %lx to struct %lx without specifying "
2207 "explicit offset after member %s of type %lx, "
2208 "which is an incomplete type\n"),
2209 name ? name : _("(unnamed member)"), type, souid,
2210 lmd->dmd_name ? lmd->dmd_name
2211 : _("(unnamed member)"), ltype);
2212 return -1; /* errno is set for us. */
2213 }
47d546f4
NA
2214
2215 /* Round up the offset of the end of the last member to
2216 the next byte boundary, convert 'off' to bytes, and
2217 then round it up again to the next multiple of the
2218 alignment required by the new member. Finally,
2219 convert back to bits and store the result in
2220 dmd_offset. Technically we could do more efficient
2221 packing if the new member is a bit-field, but we're
2222 the "compiler" and ANSI says we can do as we choose. */
2223
76fad999 2224 off = roundup (off, CHAR_BIT) / CHAR_BIT;
47d546f4 2225 off = roundup (off, MAX (malign, 1));
76fad999 2226 dmd->dmd_offset = off * CHAR_BIT;
47d546f4
NA
2227 ssize = off + msize;
2228 }
2229 else
2230 {
2231 /* Specified offset in bits. */
2232
2233 dmd->dmd_offset = bit_offset;
2234 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
76fad999 2235 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
47d546f4
NA
2236 }
2237 }
2238 else
2239 {
2240 dmd->dmd_offset = 0;
2241 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
2242 ssize = MAX (ssize, msize);
2243 }
2244
a0486bac 2245 if ((size_t) ssize > CTF_MAX_SIZE)
47d546f4
NA
2246 {
2247 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2248 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
2249 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
2250 }
2251 else
2252 dtd->dtd_data.ctt_size = (uint32_t) ssize;
2253
2254 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
2255 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
2256
47d546f4
NA
2257 fp->ctf_flags |= LCTF_DIRTY;
2258 return 0;
2259}
2260
2261int
139633c3 2262ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
47d546f4
NA
2263 ctf_id_t type, unsigned long bit_offset,
2264 const ctf_encoding_t encoding)
2265{
2266 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
2267 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
2268 int otype = type;
2269
2270 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
2271 return (ctf_set_errno (fp, ECTF_NOTINTFP));
2272
2273 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
a0486bac 2274 return -1; /* errno is set for us. */
47d546f4
NA
2275
2276 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
2277}
2278
2279int
139633c3 2280ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
47d546f4
NA
2281 ctf_id_t type)
2282{
2283 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
2284}
2285
2286int
139633c3 2287ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
47d546f4
NA
2288{
2289 ctf_dvdef_t *dvd;
139633c3 2290 ctf_dict_t *tmp = fp;
47d546f4
NA
2291
2292 if (!(fp->ctf_flags & LCTF_RDWR))
2293 return (ctf_set_errno (fp, ECTF_RDONLY));
2294
2295 if (ctf_dvd_lookup (fp, name) != NULL)
2296 return (ctf_set_errno (fp, ECTF_DUPLICATE));
2297
2298 if (ctf_lookup_by_id (&tmp, ref) == NULL)
a0486bac 2299 return -1; /* errno is set for us. */
47d546f4 2300
791915db
NA
2301 /* Make sure this type is representable. */
2302 if ((ctf_type_resolve (fp, ref) == CTF_ERR)
2303 && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
2304 return -1;
2305
de07e349 2306 if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
47d546f4
NA
2307 return (ctf_set_errno (fp, EAGAIN));
2308
de07e349 2309 if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
47d546f4 2310 {
de07e349 2311 free (dvd);
47d546f4
NA
2312 return (ctf_set_errno (fp, EAGAIN));
2313 }
2314 dvd->dvd_type = ref;
2315 dvd->dvd_snapshots = fp->ctf_snapshots;
2316
24865428
NA
2317 if (ctf_dvd_insert (fp, dvd) < 0)
2318 {
de07e349
NA
2319 free (dvd->dvd_name);
2320 free (dvd);
24865428
NA
2321 return -1; /* errno is set for us. */
2322 }
47d546f4 2323
47d546f4
NA
2324 fp->ctf_flags |= LCTF_DIRTY;
2325 return 0;
2326}
2327
1136c379
NA
2328int
2329ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
2330{
2331 ctf_dict_t *tmp = fp;
2332 char *dupname;
2333 ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
2334
2335 if (!(fp->ctf_flags & LCTF_RDWR))
2336 return (ctf_set_errno (fp, ECTF_RDONLY));
2337
2338 if (ctf_dynhash_lookup (fp->ctf_objthash, name) != NULL ||
2339 ctf_dynhash_lookup (fp->ctf_funchash, name) != NULL)
2340 return (ctf_set_errno (fp, ECTF_DUPLICATE));
2341
2342 if (ctf_lookup_by_id (&tmp, id) == NULL)
2343 return -1; /* errno is set for us. */
2344
2345 if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
2346 return (ctf_set_errno (fp, ECTF_NOTFUNC));
2347
2348 if ((dupname = strdup (name)) == NULL)
2349 return (ctf_set_errno (fp, ENOMEM));
2350
2351 if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
2352 {
2353 free (dupname);
2354 return (ctf_set_errno (fp, ENOMEM));
2355 }
2356 return 0;
2357}
2358
2359int
2360ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
2361{
2362 return (ctf_add_funcobjt_sym (fp, 0, name, id));
2363}
2364
2365int
2366ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
2367{
2368 return (ctf_add_funcobjt_sym (fp, 1, name, id));
2369}
2370
926c9e76
NA
2371typedef struct ctf_bundle
2372{
139633c3 2373 ctf_dict_t *ctb_dict; /* CTF dict handle. */
926c9e76
NA
2374 ctf_id_t ctb_type; /* CTF type identifier. */
2375 ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
2376} ctf_bundle_t;
2377
c499eb68
NA
2378static int
2379enumcmp (const char *name, int value, void *arg)
2380{
2381 ctf_bundle_t *ctb = arg;
2382 int bvalue;
2383
139633c3 2384 if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
c499eb68 2385 {
139633c3 2386 ctf_err_warn (ctb->ctb_dict, 0, 0,
926c9e76 2387 _("conflict due to enum %s iteration error"), name);
c499eb68
NA
2388 return 1;
2389 }
2390 if (value != bvalue)
2391 {
139633c3 2392 ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
926c9e76
NA
2393 _("conflict due to enum value change: %i versus %i"),
2394 value, bvalue);
c499eb68
NA
2395 return 1;
2396 }
2397 return 0;
2398}
2399
2400static int
2401enumadd (const char *name, int value, void *arg)
2402{
2403 ctf_bundle_t *ctb = arg;
2404
139633c3 2405 return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
a0486bac 2406 name, value) < 0);
c499eb68
NA
2407}
2408
2409static int
2410membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
2411 void *arg)
2412{
2413 ctf_bundle_t *ctb = arg;
2414 ctf_membinfo_t ctm;
2415
f47ca311
NA
2416 /* Don't check nameless members (e.g. anonymous structs/unions) against each
2417 other. */
2418 if (name[0] == 0)
2419 return 0;
2420
139633c3 2421 if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
c499eb68 2422 {
139633c3 2423 ctf_err_warn (ctb->ctb_dict, 0, 0,
926c9e76
NA
2424 _("conflict due to struct member %s iteration error"),
2425 name);
c499eb68
NA
2426 return 1;
2427 }
2428 if (ctm.ctm_offset != offset)
2429 {
139633c3 2430 ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
926c9e76
NA
2431 _("conflict due to struct member %s offset change: "
2432 "%lx versus %lx"),
2433 name, ctm.ctm_offset, offset);
c499eb68
NA
2434 return 1;
2435 }
2436 return 0;
2437}
2438
2439static int
2440membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
2441{
2442 ctf_bundle_t *ctb = arg;
2443 ctf_dmdef_t *dmd;
2444 char *s = NULL;
2445
de07e349 2446 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
139633c3 2447 return (ctf_set_errno (ctb->ctb_dict, EAGAIN));
c499eb68 2448
26503e2f
NA
2449 /* Unnamed members in non-dynamic dicts have a name of "", while dynamic dicts
2450 use NULL. Adapt. */
2451
2452 if (name[0] == 0)
2453 name = NULL;
2454
de07e349 2455 if (name != NULL && (s = strdup (name)) == NULL)
c499eb68 2456 {
de07e349 2457 free (dmd);
139633c3 2458 return (ctf_set_errno (ctb->ctb_dict, EAGAIN));
c499eb68
NA
2459 }
2460
2461 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
2462 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
2463 dmd->dmd_name = s;
2464 dmd->dmd_type = type;
2465 dmd->dmd_offset = offset;
2466 dmd->dmd_value = -1;
2467
2468 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
2469
139633c3 2470 ctb->ctb_dict->ctf_flags |= LCTF_DIRTY;
c499eb68
NA
2471 return 0;
2472}
2473
f5060e56
NA
2474/* Record the correspondence between a source and ctf_add_type()-added
2475 destination type: both types are translated into parent type IDs if need be,
2476 so they relate to the actual dictionary they are in. Outside controlled
2477 circumstances (like linking) it is probably not useful to do more than
2478 compare these pointers, since there is nothing stopping the user closing the
2479 source dict whenever they want to.
2480
2481 Our OOM handling here is just to not do anything, because this is called deep
2482 enough in the call stack that doing anything useful is painfully difficult:
2483 the worst consequence if we do OOM is a bit of type duplication anyway. */
2484
2485static void
2486ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
2487 ctf_dict_t *dst_fp, ctf_id_t dst_type)
2488{
2489 if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
2490 src_fp = src_fp->ctf_parent;
2491
2492 src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
2493
2494 if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
2495 dst_fp = dst_fp->ctf_parent;
2496
2497 dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
2498
2499 if (dst_fp->ctf_link_type_mapping == NULL)
2500 {
2501 ctf_hash_fun f = ctf_hash_type_key;
2502 ctf_hash_eq_fun e = ctf_hash_eq_type_key;
2503
2504 if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
2505 NULL)) == NULL)
2506 return;
2507 }
2508
2509 ctf_link_type_key_t *key;
2510 key = calloc (1, sizeof (struct ctf_link_type_key));
2511 if (!key)
2512 return;
2513
2514 key->cltk_fp = src_fp;
2515 key->cltk_idx = src_type;
2516
2517 /* No OOM checking needed, because if this doesn't work the worst we'll do is
2518 add a few more duplicate types (which will probably run out of memory
2519 anyway). */
2520 ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
2521 (void *) (uintptr_t) dst_type);
2522}
2523
2524/* Look up a type mapping: return 0 if none. The DST_FP is modified to point to
2525 the parent if need be. The ID returned is from the dst_fp's perspective. */
2526static ctf_id_t
2527ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
2528{
2529 ctf_link_type_key_t key;
2530 ctf_dict_t *target_fp = *dst_fp;
2531 ctf_id_t dst_type = 0;
2532
2533 if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
2534 src_fp = src_fp->ctf_parent;
2535
2536 src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
2537 key.cltk_fp = src_fp;
2538 key.cltk_idx = src_type;
2539
2540 if (target_fp->ctf_link_type_mapping)
2541 dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
2542 &key);
2543
2544 if (dst_type != 0)
2545 {
2546 dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
2547 target_fp->ctf_parent != NULL);
2548 *dst_fp = target_fp;
2549 return dst_type;
2550 }
2551
2552 if (target_fp->ctf_parent)
2553 target_fp = target_fp->ctf_parent;
2554 else
2555 return 0;
2556
2557 if (target_fp->ctf_link_type_mapping)
2558 dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
2559 &key);
2560
2561 if (dst_type)
2562 dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
2563 target_fp->ctf_parent != NULL);
2564
2565 *dst_fp = target_fp;
2566 return dst_type;
2567}
2568
139633c3
NA
2569/* The ctf_add_type routine is used to copy a type from a source CTF dictionary
2570 to a dynamic destination dictionary. This routine operates recursively by
c499eb68 2571 following the source type's links and embedded member types. If the
139633c3
NA
2572 destination dict already contains a named type which has the same attributes,
2573 then we succeed and return this type but no changes occur. */
99dc3ebd 2574static ctf_id_t
139633c3
NA
2575ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
2576 ctf_dict_t *proc_tracking_fp)
c499eb68
NA
2577{
2578 ctf_id_t dst_type = CTF_ERR;
2579 uint32_t dst_kind = CTF_K_UNKNOWN;
139633c3 2580 ctf_dict_t *tmp_fp = dst_fp;
c499eb68
NA
2581 ctf_id_t tmp;
2582
2583 const char *name;
5de9eada 2584 uint32_t kind, forward_kind, flag, vlen;
c499eb68
NA
2585
2586 const ctf_type_t *src_tp, *dst_tp;
2587 ctf_bundle_t src, dst;
2588 ctf_encoding_t src_en, dst_en;
2589 ctf_arinfo_t src_ar, dst_ar;
2590
c499eb68 2591 ctf_funcinfo_t ctc;
c499eb68 2592
886453cb 2593 ctf_id_t orig_src_type = src_type;
c499eb68
NA
2594
2595 if (!(dst_fp->ctf_flags & LCTF_RDWR))
2596 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
2597
2598 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
2599 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
2600
791915db
NA
2601 if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
2602 && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
2603 return (ctf_set_errno (dst_fp, ECTF_NONREPRESENTABLE));
2604
c499eb68
NA
2605 name = ctf_strptr (src_fp, src_tp->ctt_name);
2606 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
2607 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
2608 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
2609
99dc3ebd
NA
2610 /* If this is a type we are currently in the middle of adding, hand it
2611 straight back. (This lets us handle self-referential structures without
2612 considering forwards and empty structures the same as their completed
2613 forms.) */
2614
2615 tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
2616
2617 if (tmp != 0)
2618 {
2619 if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
2620 (void *) (uintptr_t) src_type))
2621 return tmp;
2622
139633c3
NA
2623 /* If this type has already been added from this dictionary, and is the
2624 same kind and (if a struct or union) has the same number of members,
2625 hand it straight back. */
99dc3ebd 2626
d04a47ac 2627 if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
99dc3ebd 2628 {
d04a47ac
NA
2629 if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
2630 || kind == CTF_K_ENUM)
2631 {
2632 if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
2633 if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
2634 return tmp;
2635 }
2636 else
2637 return tmp;
99dc3ebd
NA
2638 }
2639 }
2640
5de9eada
NA
2641 forward_kind = kind;
2642 if (kind == CTF_K_FORWARD)
2643 forward_kind = src_tp->ctt_type;
2644
139633c3
NA
2645 /* If the source type has a name and is a root type (visible at the top-level
2646 scope), lookup the name in the destination dictionary and verify that it is
2647 of the same kind before we do anything else. */
c499eb68
NA
2648
2649 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
676c3ecb 2650 && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
c499eb68
NA
2651 {
2652 dst_type = tmp;
2653 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
2654 }
2655
2656 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
2657 unless dst_type is a forward declaration and src_type is a struct,
5de9eada 2658 union, or enum (i.e. the definition of the previous forward decl).
c499eb68 2659
5de9eada
NA
2660 We also allow addition in the opposite order (addition of a forward when a
2661 struct, union, or enum already exists), which is a NOP and returns the
2662 already-present struct, union, or enum. */
2663
2664 if (dst_type != CTF_ERR && dst_kind != kind)
c499eb68 2665 {
5de9eada
NA
2666 if (kind == CTF_K_FORWARD
2667 && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
2668 || dst_kind == CTF_K_UNION))
2669 {
2670 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
2671 return dst_type;
2672 }
2673
2674 if (dst_kind != CTF_K_FORWARD
2675 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
2676 && kind != CTF_K_UNION))
2677 {
926c9e76 2678 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
139633c3 2679 _("ctf_add_type: conflict for type %s: "
926c9e76
NA
2680 "kinds differ, new: %i; old (ID %lx): %i"),
2681 name, kind, dst_type, dst_kind);
5de9eada
NA
2682 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2683 }
c499eb68
NA
2684 }
2685
2686 /* We take special action for an integer, float, or slice since it is
2687 described not only by its name but also its encoding. For integers,
2688 bit-fields exploit this degeneracy. */
2689
2690 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
2691 {
2692 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
2693 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
2694
2695 if (dst_type != CTF_ERR)
2696 {
139633c3 2697 ctf_dict_t *fp = dst_fp;
c499eb68
NA
2698
2699 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
2700 return CTF_ERR;
2701
99dc3ebd
NA
2702 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
2703 return CTF_ERR; /* errno set for us. */
2704
c499eb68
NA
2705 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
2706 {
2707 /* The type that we found in the hash is also root-visible. If
2708 the two types match then use the existing one; otherwise,
2709 declare a conflict. Note: slices are not certain to match
2710 even if there is no conflict: we must check the contained type
2711 too. */
2712
c499eb68
NA
2713 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
2714 {
2715 if (kind != CTF_K_SLICE)
886453cb
NA
2716 {
2717 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
2718 return dst_type;
2719 }
c499eb68
NA
2720 }
2721 else
2722 {
2723 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2724 }
2725 }
2726 else
2727 {
99dc3ebd
NA
2728 /* We found a non-root-visible type in the hash. If its encoding
2729 is the same, we can reuse it, unless it is a slice. */
c499eb68 2730
99dc3ebd 2731 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
c499eb68
NA
2732 {
2733 if (kind != CTF_K_SLICE)
886453cb 2734 {
99dc3ebd
NA
2735 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
2736 return dst_type;
886453cb 2737 }
c499eb68 2738 }
c499eb68
NA
2739 }
2740 }
2741 }
2742
139633c3 2743 src.ctb_dict = src_fp;
c499eb68
NA
2744 src.ctb_type = src_type;
2745 src.ctb_dtd = NULL;
2746
139633c3 2747 dst.ctb_dict = dst_fp;
c499eb68
NA
2748 dst.ctb_type = dst_type;
2749 dst.ctb_dtd = NULL;
2750
99dc3ebd
NA
2751 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
2752 a new type with the same properties as src_type to dst_fp. If dst_type is
2753 not CTF_ERR, then we verify that dst_type has the same attributes as
2754 src_type. We recurse for embedded references. Before we start, we note
2755 that we are processing this type, to prevent infinite recursion: we do not
2756 re-process any type that appears in this list. The list is emptied
2757 wholesale at the end of processing everything in this recursive stack. */
2758
2759 if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
2760 (void *) (uintptr_t) src_type, (void *) 1) < 0)
2761 return ctf_set_errno (dst_fp, ENOMEM);
2762
c499eb68
NA
2763 switch (kind)
2764 {
2765 case CTF_K_INTEGER:
2766 /* If we found a match we will have either returned it or declared a
2767 conflict. */
2768 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
2769 break;
2770
2771 case CTF_K_FLOAT:
2772 /* If we found a match we will have either returned it or declared a
2773 conflict. */
2774 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
2775 break;
2776
2777 case CTF_K_SLICE:
2778 /* We have checked for conflicting encodings: now try to add the
2779 contained type. */
2780 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
2781 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2782 proc_tracking_fp);
c499eb68
NA
2783
2784 if (src_type == CTF_ERR)
2785 return CTF_ERR; /* errno is set for us. */
2786
2787 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
2788 break;
2789
2790 case CTF_K_POINTER:
2791 case CTF_K_VOLATILE:
2792 case CTF_K_CONST:
2793 case CTF_K_RESTRICT:
2794 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
2795 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2796 proc_tracking_fp);
c499eb68
NA
2797
2798 if (src_type == CTF_ERR)
2799 return CTF_ERR; /* errno is set for us. */
2800
2801 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
2802 break;
2803
2804 case CTF_K_ARRAY:
a0486bac 2805 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
c499eb68
NA
2806 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
2807
2808 src_ar.ctr_contents =
99dc3ebd
NA
2809 ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
2810 proc_tracking_fp);
2811 src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
2812 src_ar.ctr_index,
2813 proc_tracking_fp);
c499eb68
NA
2814 src_ar.ctr_nelems = src_ar.ctr_nelems;
2815
2816 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
2817 return CTF_ERR; /* errno is set for us. */
2818
2819 if (dst_type != CTF_ERR)
2820 {
2821 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
2822 return CTF_ERR; /* errno is set for us. */
2823
2824 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
2825 {
926c9e76
NA
2826 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
2827 _("conflict for type %s against ID %lx: array info "
2828 "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
2829 name, dst_type, src_ar.ctr_contents,
2830 src_ar.ctr_index, src_ar.ctr_nelems,
2831 dst_ar.ctr_contents, dst_ar.ctr_index,
2832 dst_ar.ctr_nelems);
c499eb68
NA
2833 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2834 }
2835 }
2836 else
2837 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
2838 break;
2839
2840 case CTF_K_FUNCTION:
99dc3ebd
NA
2841 ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
2842 src_tp->ctt_type,
2843 proc_tracking_fp);
c499eb68
NA
2844 ctc.ctc_argc = 0;
2845 ctc.ctc_flags = 0;
2846
2847 if (ctc.ctc_return == CTF_ERR)
2848 return CTF_ERR; /* errno is set for us. */
2849
2850 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
2851 break;
2852
2853 case CTF_K_STRUCT:
2854 case CTF_K_UNION:
2855 {
2856 ctf_dmdef_t *dmd;
2857 int errs = 0;
a0486bac
JM
2858 size_t size;
2859 ssize_t ssize;
99dc3ebd 2860 ctf_dtdef_t *dtd;
c499eb68
NA
2861
2862 /* Technically to match a struct or union we need to check both
2863 ways (src members vs. dst, dst members vs. src) but we make
2864 this more optimal by only checking src vs. dst and comparing
2865 the total size of the structure (which we must do anyway)
2866 which covers the possibility of dst members not in src.
2867 This optimization can be defeated for unions, but is so
2868 pathological as to render it irrelevant for our purposes. */
2869
99dc3ebd
NA
2870 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
2871 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
2872 {
2873 if (ctf_type_size (src_fp, src_type) !=
2874 ctf_type_size (dst_fp, dst_type))
2875 {
926c9e76
NA
2876 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
2877 _("conflict for type %s against ID %lx: union "
2878 "size differs, old %li, new %li"), name,
2879 dst_type, (long) ctf_type_size (src_fp, src_type),
2880 (long) ctf_type_size (dst_fp, dst_type));
c499eb68
NA
2881 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2882 }
2883
2884 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
2885 {
926c9e76
NA
2886 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
2887 _("conflict for type %s against ID %lx: members "
2888 "differ, see above"), name, dst_type);
c499eb68
NA
2889 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2890 }
2891
2892 break;
2893 }
2894
2895 /* Unlike the other cases, copying structs and unions is done
2896 manually so as to avoid repeated lookups in ctf_add_member
2897 and to ensure the exact same member offsets as in src_type. */
2898
676c3ecb 2899 dst_type = ctf_add_generic (dst_fp, flag, name, kind, &dtd);
c499eb68
NA
2900 if (dst_type == CTF_ERR)
2901 return CTF_ERR; /* errno is set for us. */
2902
2903 dst.ctb_type = dst_type;
2904 dst.ctb_dtd = dtd;
2905
99dc3ebd
NA
2906 /* Pre-emptively add this struct to the type mapping so that
2907 structures that refer to themselves work. */
2908 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
2909
c499eb68
NA
2910 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
2911 errs++; /* Increment errs and fail at bottom of case. */
2912
a0486bac
JM
2913 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
2914 return CTF_ERR; /* errno is set for us. */
2915
2916 size = (size_t) ssize;
2917 if (size > CTF_MAX_SIZE)
c499eb68
NA
2918 {
2919 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2920 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
2921 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
2922 }
2923 else
2924 dtd->dtd_data.ctt_size = (uint32_t) size;
2925
2926 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
2927
2928 /* Make a final pass through the members changing each dmd_type (a
2929 src_fp type) to an equivalent type in dst_fp. We pass through all
791915db
NA
2930 members, leaving any that fail set to CTF_ERR, unless they fail
2931 because they are marking a member of type not representable in this
2932 version of CTF, in which case we just want to silently omit them:
2933 no consumer can do anything with them anyway. */
c499eb68
NA
2934 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
2935 dmd != NULL; dmd = ctf_list_next (dmd))
2936 {
139633c3 2937 ctf_dict_t *dst = dst_fp;
99dc3ebd
NA
2938 ctf_id_t memb_type;
2939
2940 memb_type = ctf_type_mapping (src_fp, dmd->dmd_type, &dst);
2941 if (memb_type == 0)
791915db 2942 {
99dc3ebd
NA
2943 if ((dmd->dmd_type =
2944 ctf_add_type_internal (dst_fp, src_fp, dmd->dmd_type,
2945 proc_tracking_fp)) == CTF_ERR)
2946 {
2947 if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
2948 errs++;
2949 }
791915db 2950 }
99dc3ebd
NA
2951 else
2952 dmd->dmd_type = memb_type;
c499eb68
NA
2953 }
2954
2955 if (errs)
2956 return CTF_ERR; /* errno is set for us. */
2957 break;
2958 }
2959
2960 case CTF_K_ENUM:
99dc3ebd
NA
2961 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
2962 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
2963 {
2964 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
2965 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
2966 {
926c9e76
NA
2967 ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
2968 _("conflict for enum %s against ID %lx: members "
2969 "differ, see above"), name, dst_type);
c499eb68
NA
2970 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2971 }
2972 }
2973 else
2974 {
2975 dst_type = ctf_add_enum (dst_fp, flag, name);
2976 if ((dst.ctb_type = dst_type) == CTF_ERR
2977 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
2978 return CTF_ERR; /* errno is set for us */
2979 }
2980 break;
2981
2982 case CTF_K_FORWARD:
2983 if (dst_type == CTF_ERR)
5de9eada 2984 dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
c499eb68
NA
2985 break;
2986
2987 case CTF_K_TYPEDEF:
2988 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
2989 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2990 proc_tracking_fp);
c499eb68
NA
2991
2992 if (src_type == CTF_ERR)
2993 return CTF_ERR; /* errno is set for us. */
2994
2995 /* If dst_type is not CTF_ERR at this point, we should check if
2996 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
2997 ECTF_CONFLICT. However, this causes problems with bitness typedefs
2998 that vary based on things like if 32-bit then pid_t is int otherwise
2999 long. We therefore omit this check and assume that if the identically
3000 named typedef already exists in dst_fp, it is correct or
3001 equivalent. */
3002
3003 if (dst_type == CTF_ERR)
c499eb68 3004 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
99dc3ebd 3005
c499eb68
NA
3006 break;
3007
3008 default:
3009 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
3010 }
3011
886453cb
NA
3012 if (dst_type != CTF_ERR)
3013 ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
c499eb68
NA
3014 return dst_type;
3015}
3016
99dc3ebd 3017ctf_id_t
139633c3 3018ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
99dc3ebd
NA
3019{
3020 ctf_id_t id;
3021
3022 if (!src_fp->ctf_add_processing)
3023 src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
3024 ctf_hash_eq_integer,
3025 NULL, NULL);
3026
3027 /* We store the hash on the source, because it contains only source type IDs:
3028 but callers will invariably expect errors to appear on the dest. */
3029 if (!src_fp->ctf_add_processing)
3030 return (ctf_set_errno (dst_fp, ENOMEM));
3031
3032 id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
3033 ctf_dynhash_empty (src_fp->ctf_add_processing);
3034
3035 return id;
3036}
3037
fd55eae8 3038/* Write the compressed CTF data stream to the specified gzFile descriptor. */
47d546f4 3039int
139633c3 3040ctf_gzwrite (ctf_dict_t *fp, gzFile fd)
47d546f4 3041{
fd55eae8
NA
3042 const unsigned char *buf;
3043 ssize_t resid;
47d546f4
NA
3044 ssize_t len;
3045
fd55eae8
NA
3046 resid = sizeof (ctf_header_t);
3047 buf = (unsigned char *) fp->ctf_header;
3048 while (resid != 0)
3049 {
3050 if ((len = gzwrite (fd, buf, resid)) <= 0)
3051 return (ctf_set_errno (fp, errno));
3052 resid -= len;
3053 buf += len;
3054 }
3055
3056 resid = fp->ctf_size;
3057 buf = fp->ctf_buf;
47d546f4
NA
3058 while (resid != 0)
3059 {
3060 if ((len = gzwrite (fd, buf, resid)) <= 0)
3061 return (ctf_set_errno (fp, errno));
3062 resid -= len;
3063 buf += len;
3064 }
3065
3066 return 0;
3067}
3068
3069/* Compress the specified CTF data stream and write it to the specified file
3070 descriptor. */
3071int
139633c3 3072ctf_compress_write (ctf_dict_t *fp, int fd)
47d546f4
NA
3073{
3074 unsigned char *buf;
3075 unsigned char *bp;
3076 ctf_header_t h;
3077 ctf_header_t *hp = &h;
3078 ssize_t header_len = sizeof (ctf_header_t);
3079 ssize_t compress_len;
47d546f4
NA
3080 ssize_t len;
3081 int rc;
3082 int err = 0;
3083
676c3ecb
NA
3084 if (ctf_serialize (fp) < 0)
3085 return -1; /* errno is set for us. */
3086
fd55eae8 3087 memcpy (hp, fp->ctf_header, header_len);
47d546f4 3088 hp->cth_flags |= CTF_F_COMPRESS;
676c3ecb 3089 compress_len = compressBound (fp->ctf_size);
47d546f4 3090
de07e349 3091 if ((buf = malloc (compress_len)) == NULL)
926c9e76
NA
3092 {
3093 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: cannot allocate %li bytes"),
3094 (unsigned long) compress_len);
3095 return (ctf_set_errno (fp, ECTF_ZALLOC));
3096 }
47d546f4 3097
65365aa8 3098 if ((rc = compress (buf, (uLongf *) &compress_len,
fd55eae8 3099 fp->ctf_buf, fp->ctf_size)) != Z_OK)
47d546f4 3100 {
47d546f4 3101 err = ctf_set_errno (fp, ECTF_COMPRESS);
926c9e76 3102 ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
47d546f4
NA
3103 goto ret;
3104 }
3105
3106 while (header_len > 0)
3107 {
3108 if ((len = write (fd, hp, header_len)) < 0)
3109 {
3110 err = ctf_set_errno (fp, errno);
926c9e76 3111 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing header"));
47d546f4
NA
3112 goto ret;
3113 }
3114 header_len -= len;
3115 hp += len;
3116 }
3117
3118 bp = buf;
3119 while (compress_len > 0)
3120 {
3121 if ((len = write (fd, bp, compress_len)) < 0)
3122 {
3123 err = ctf_set_errno (fp, errno);
926c9e76 3124 ctf_err_warn (fp, 0, 0, _("ctf_compress_write: error writing"));
47d546f4
NA
3125 goto ret;
3126 }
3127 compress_len -= len;
3128 bp += len;
3129 }
3130
3131ret:
de07e349 3132 free (buf);
47d546f4
NA
3133 return err;
3134}
3135
5537f9b9
NA
3136/* Optionally compress the specified CTF data stream and return it as a new
3137 dynamically-allocated string. */
3138unsigned char *
139633c3 3139ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold)
5537f9b9
NA
3140{
3141 unsigned char *buf;
3142 unsigned char *bp;
3143 ctf_header_t *hp;
3144 ssize_t header_len = sizeof (ctf_header_t);
3145 ssize_t compress_len;
5537f9b9
NA
3146 int rc;
3147
676c3ecb
NA
3148 if (ctf_serialize (fp) < 0)
3149 return NULL; /* errno is set for us. */
3150
3151 compress_len = compressBound (fp->ctf_size);
5537f9b9 3152 if (fp->ctf_size < threshold)
676c3ecb
NA
3153 compress_len = fp->ctf_size;
3154 if ((buf = malloc (compress_len
5537f9b9
NA
3155 + sizeof (struct ctf_header))) == NULL)
3156 {
3157 ctf_set_errno (fp, ENOMEM);
926c9e76
NA
3158 ctf_err_warn (fp, 0, 0, _("ctf_write_mem: cannot allocate %li bytes"),
3159 (unsigned long) (compress_len + sizeof (struct ctf_header)));
5537f9b9
NA
3160 return NULL;
3161 }
3162
3163 hp = (ctf_header_t *) buf;
3164 memcpy (hp, fp->ctf_header, header_len);
3165 bp = buf + sizeof (struct ctf_header);
3166 *size = sizeof (struct ctf_header);
3167
5537f9b9
NA
3168 if (fp->ctf_size < threshold)
3169 {
3170 hp->cth_flags &= ~CTF_F_COMPRESS;
3171 memcpy (bp, fp->ctf_buf, fp->ctf_size);
3172 *size += fp->ctf_size;
3173 }
3174 else
3175 {
3176 hp->cth_flags |= CTF_F_COMPRESS;
3177 if ((rc = compress (bp, (uLongf *) &compress_len,
3178 fp->ctf_buf, fp->ctf_size)) != Z_OK)
3179 {
5537f9b9 3180 ctf_set_errno (fp, ECTF_COMPRESS);
926c9e76 3181 ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc));
de07e349 3182 free (buf);
5537f9b9
NA
3183 return NULL;
3184 }
3185 *size += compress_len;
3186 }
3187 return buf;
3188}
3189
fd55eae8 3190/* Write the uncompressed CTF data stream to the specified file descriptor. */
47d546f4 3191int
139633c3 3192ctf_write (ctf_dict_t *fp, int fd)
47d546f4 3193{
fd55eae8
NA
3194 const unsigned char *buf;
3195 ssize_t resid;
47d546f4
NA
3196 ssize_t len;
3197
676c3ecb
NA
3198 if (ctf_serialize (fp) < 0)
3199 return -1; /* errno is set for us. */
3200
fd55eae8
NA
3201 resid = sizeof (ctf_header_t);
3202 buf = (unsigned char *) fp->ctf_header;
3203 while (resid != 0)
3204 {
3205 if ((len = write (fd, buf, resid)) <= 0)
926c9e76
NA
3206 {
3207 ctf_err_warn (fp, 0, errno, _("ctf_write: error writing header"));
3208 return (ctf_set_errno (fp, errno));
3209 }
fd55eae8
NA
3210 resid -= len;
3211 buf += len;
3212 }
3213
3214 resid = fp->ctf_size;
3215 buf = fp->ctf_buf;
47d546f4
NA
3216 while (resid != 0)
3217 {
fd55eae8 3218 if ((len = write (fd, buf, resid)) <= 0)
926c9e76
NA
3219 {
3220 ctf_err_warn (fp, 0, errno, _("ctf_write: error writing"));
3221 return (ctf_set_errno (fp, errno));
3222 }
47d546f4
NA
3223 resid -= len;
3224 buf += len;
3225 }
3226
3227 return 0;
3228}
This page took 0.26477 seconds and 4 git commands to generate.