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