]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-create.c
libctf, create: fix addition of anonymous struct/union members
[thirdparty/binutils-gdb.git] / libctf / ctf-create.c
CommitLineData
47d546f4 1/* CTF file creation.
b3adc24a 2 Copyright (C) 2019-2020 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
a0486bac
JM
27#ifndef roundup
28#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
29#endif
30
676c3ecb
NA
31/* Make sure the ptrtab has enough space for at least one more type.
32
33 We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
34 at a time. */
35
36static int
37ctf_grow_ptrtab (ctf_file_t *fp)
38{
39 size_t new_ptrtab_len = fp->ctf_ptrtab_len;
40
41 /* We allocate one more ptrtab entry than we need, for the initial zero,
42 plus one because the caller will probably allocate a new type. */
43
44 if (fp->ctf_ptrtab == NULL)
45 new_ptrtab_len = 1024;
46 else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
47 new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
48
49 if (new_ptrtab_len != fp->ctf_ptrtab_len)
50 {
51 uint32_t *new_ptrtab;
52
53 if ((new_ptrtab = realloc (fp->ctf_ptrtab,
54 new_ptrtab_len * sizeof (uint32_t))) == NULL)
55 return (ctf_set_errno (fp, ENOMEM));
56
57 fp->ctf_ptrtab = new_ptrtab;
58 memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
59 (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
60 fp->ctf_ptrtab_len = new_ptrtab_len;
61 }
62 return 0;
63}
64
47d546f4
NA
65/* To create an empty CTF container, we just declare a zeroed header and call
66 ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
f5e9c9bd
NA
67 and initialize the dynamic members. We start assigning type IDs at 1 because
68 type ID 0 is used as a sentinel and a not-found indicator. */
47d546f4
NA
69
70ctf_file_t *
71ctf_create (int *errp)
72{
73 static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
74
75 ctf_dynhash_t *dthash;
76 ctf_dynhash_t *dvhash;
676c3ecb 77 ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
47d546f4
NA
78 ctf_sect_t cts;
79 ctf_file_t *fp;
80
81 libctf_init_debug();
82 dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
83 NULL, NULL);
84 if (dthash == NULL)
85 {
86 ctf_set_open_errno (errp, EAGAIN);
87 goto err;
88 }
89
90 dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
91 NULL, NULL);
92 if (dvhash == NULL)
93 {
94 ctf_set_open_errno (errp, EAGAIN);
95 goto err_dt;
96 }
97
676c3ecb
NA
98 structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
99 NULL, NULL);
100 unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
101 NULL, NULL);
102 enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
103 NULL, NULL);
104 names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
105 NULL, NULL);
106 if (!structs || !unions || !enums || !names)
47d546f4
NA
107 {
108 ctf_set_open_errno (errp, EAGAIN);
109 goto err_dv;
110 }
111
112 cts.cts_name = _CTF_SECTION;
47d546f4
NA
113 cts.cts_data = &hdr;
114 cts.cts_size = sizeof (hdr);
115 cts.cts_entsize = 1;
47d546f4 116
676c3ecb
NA
117 if ((fp = ctf_bufopen_internal (&cts, NULL, NULL, NULL, 1, errp)) == NULL)
118 goto err_dv;
47d546f4 119
676c3ecb
NA
120 fp->ctf_structs.ctn_writable = structs;
121 fp->ctf_unions.ctn_writable = unions;
122 fp->ctf_enums.ctn_writable = enums;
123 fp->ctf_names.ctn_writable = names;
47d546f4
NA
124 fp->ctf_dthash = dthash;
125 fp->ctf_dvhash = dvhash;
47d546f4 126 fp->ctf_dtoldid = 0;
f57cf0e3 127 fp->ctf_snapshots = 1;
47d546f4
NA
128 fp->ctf_snapshot_lu = 0;
129
676c3ecb
NA
130 ctf_set_ctl_hashes (fp);
131 ctf_setmodel (fp, CTF_MODEL_NATIVE);
132 if (ctf_grow_ptrtab (fp) < 0)
133 {
134 ctf_set_open_errno (errp, ctf_errno (fp));
135 ctf_file_close (fp);
136 return NULL;
137 }
138
47d546f4
NA
139 return fp;
140
47d546f4 141 err_dv:
676c3ecb
NA
142 ctf_dynhash_destroy (structs);
143 ctf_dynhash_destroy (unions);
144 ctf_dynhash_destroy (enums);
145 ctf_dynhash_destroy (names);
47d546f4
NA
146 ctf_dynhash_destroy (dvhash);
147 err_dt:
148 ctf_dynhash_destroy (dthash);
149 err:
150 return NULL;
151}
152
153static unsigned char *
f5e9c9bd 154ctf_copy_smembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
155{
156 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
157 ctf_member_t ctm;
158
159 for (; dmd != NULL; dmd = ctf_list_next (dmd))
160 {
f5e9c9bd 161 ctf_member_t *copied;
47d546f4 162
f5e9c9bd 163 ctm.ctm_name = 0;
47d546f4
NA
164 ctm.ctm_type = (uint32_t) dmd->dmd_type;
165 ctm.ctm_offset = (uint32_t) dmd->dmd_offset;
166
167 memcpy (t, &ctm, sizeof (ctm));
f5e9c9bd
NA
168 copied = (ctf_member_t *) t;
169 if (dmd->dmd_name)
170 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctm_name);
171
47d546f4
NA
172 t += sizeof (ctm);
173 }
174
175 return t;
176}
177
178static unsigned char *
f5e9c9bd 179ctf_copy_lmembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
180{
181 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
182 ctf_lmember_t ctlm;
183
184 for (; dmd != NULL; dmd = ctf_list_next (dmd))
185 {
f5e9c9bd 186 ctf_lmember_t *copied;
47d546f4 187
f5e9c9bd 188 ctlm.ctlm_name = 0;
47d546f4
NA
189 ctlm.ctlm_type = (uint32_t) dmd->dmd_type;
190 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (dmd->dmd_offset);
191 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (dmd->dmd_offset);
192
193 memcpy (t, &ctlm, sizeof (ctlm));
f5e9c9bd
NA
194 copied = (ctf_lmember_t *) t;
195 if (dmd->dmd_name)
196 ctf_str_add_ref (fp, dmd->dmd_name, &copied->ctlm_name);
197
47d546f4
NA
198 t += sizeof (ctlm);
199 }
200
201 return t;
202}
203
204static unsigned char *
f5e9c9bd 205ctf_copy_emembers (ctf_file_t *fp, ctf_dtdef_t *dtd, unsigned char *t)
47d546f4
NA
206{
207 ctf_dmdef_t *dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
208 ctf_enum_t cte;
209
210 for (; dmd != NULL; dmd = ctf_list_next (dmd))
211 {
f5e9c9bd
NA
212 ctf_enum_t *copied;
213
47d546f4 214 cte.cte_value = dmd->dmd_value;
47d546f4 215 memcpy (t, &cte, sizeof (cte));
f5e9c9bd
NA
216 copied = (ctf_enum_t *) t;
217 ctf_str_add_ref (fp, dmd->dmd_name, &copied->cte_name);
47d546f4
NA
218 t += sizeof (cte);
219 }
220
221 return t;
222}
223
47d546f4
NA
224/* Sort a newly-constructed static variable array. */
225
d851ecd3
NA
226typedef struct ctf_sort_var_arg_cb
227{
228 ctf_file_t *fp;
229 ctf_strs_t *strtab;
230} ctf_sort_var_arg_cb_t;
231
47d546f4 232static int
d851ecd3 233ctf_sort_var (const void *one_, const void *two_, void *arg_)
47d546f4
NA
234{
235 const ctf_varent_t *one = one_;
236 const ctf_varent_t *two = two_;
d851ecd3 237 ctf_sort_var_arg_cb_t *arg = arg_;
47d546f4 238
d851ecd3
NA
239 return (strcmp (ctf_strraw_explicit (arg->fp, one->ctv_name, arg->strtab),
240 ctf_strraw_explicit (arg->fp, two->ctv_name, arg->strtab)));
47d546f4
NA
241}
242
676c3ecb 243/* Compatibility: just update the threshold for ctf_discard. */
47d546f4
NA
244int
245ctf_update (ctf_file_t *fp)
676c3ecb
NA
246{
247 if (!(fp->ctf_flags & LCTF_RDWR))
248 return (ctf_set_errno (fp, ECTF_RDONLY));
249
250 fp->ctf_dtoldid = fp->ctf_typemax;
251 return 0;
252}
253
254/* If the specified CTF container is writable and has been modified, reload this
255 container with the updated type definitions, ready for serialization. In
256 order to make this code and the rest of libctf as simple as possible, we
257 perform updates by taking the dynamic type definitions and creating an
258 in-memory CTF file containing the definitions, and then call
259 ctf_simple_open_internal() on it. We perform one extra trick here for the
260 benefit of callers and to keep our code simple: ctf_simple_open_internal()
261 will return a new ctf_file_t, but we want to keep the fp constant for the
262 caller, so after ctf_simple_open_internal() returns, we use memcpy to swap
263 the interior of the old and new ctf_file_t's, and then free the old. */
264int
265ctf_serialize (ctf_file_t *fp)
47d546f4
NA
266{
267 ctf_file_t ofp, *nfp;
f5e9c9bd 268 ctf_header_t hdr, *hdrp;
47d546f4
NA
269 ctf_dtdef_t *dtd;
270 ctf_dvdef_t *dvd;
271 ctf_varent_t *dvarents;
f5e9c9bd 272 ctf_strs_writable_t strtab;
47d546f4 273
f5e9c9bd 274 unsigned char *t;
47d546f4
NA
275 unsigned long i;
276 size_t buf_size, type_size, nvars;
f5e9c9bd 277 unsigned char *buf, *newbuf;
47d546f4
NA
278 int err;
279
280 if (!(fp->ctf_flags & LCTF_RDWR))
281 return (ctf_set_errno (fp, ECTF_RDONLY));
282
283 /* Update required? */
284 if (!(fp->ctf_flags & LCTF_DIRTY))
285 return 0;
286
287 /* Fill in an initial CTF header. We will leave the label, object,
288 and function sections empty and only output a header, type section,
289 and string table. The type section begins at a 4-byte aligned
290 boundary past the CTF header itself (at relative offset zero). */
291
292 memset (&hdr, 0, sizeof (hdr));
293 hdr.cth_magic = CTF_MAGIC;
294 hdr.cth_version = CTF_VERSION;
295
47d546f4
NA
296 /* Iterate through the dynamic type definition list and compute the
297 size of the CTF type section we will need to generate. */
298
299 for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
300 dtd != NULL; dtd = ctf_list_next (dtd))
301 {
302 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
303 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
304
305 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
306 type_size += sizeof (ctf_stype_t);
307 else
308 type_size += sizeof (ctf_type_t);
309
310 switch (kind)
311 {
312 case CTF_K_INTEGER:
313 case CTF_K_FLOAT:
314 type_size += sizeof (uint32_t);
315 break;
316 case CTF_K_ARRAY:
317 type_size += sizeof (ctf_array_t);
318 break;
319 case CTF_K_SLICE:
320 type_size += sizeof (ctf_slice_t);
321 break;
322 case CTF_K_FUNCTION:
323 type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
324 break;
325 case CTF_K_STRUCT:
326 case CTF_K_UNION:
327 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
328 type_size += sizeof (ctf_member_t) * vlen;
329 else
330 type_size += sizeof (ctf_lmember_t) * vlen;
331 break;
332 case CTF_K_ENUM:
333 type_size += sizeof (ctf_enum_t) * vlen;
334 break;
335 }
336 }
337
338 /* Computing the number of entries in the CTF variable section is much
339 simpler. */
340
341 for (nvars = 0, dvd = ctf_list_next (&fp->ctf_dvdefs);
342 dvd != NULL; dvd = ctf_list_next (dvd), nvars++);
343
f5e9c9bd
NA
344 /* Compute the size of the CTF buffer we need, sans only the string table,
345 then allocate a new buffer and memcpy the finished header to the start of
346 the buffer. (We will adjust this later with strtab length info.) */
47d546f4
NA
347
348 hdr.cth_typeoff = hdr.cth_varoff + (nvars * sizeof (ctf_varent_t));
349 hdr.cth_stroff = hdr.cth_typeoff + type_size;
f5e9c9bd 350 hdr.cth_strlen = 0;
47d546f4
NA
351
352 buf_size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
353
65365aa8 354 if ((buf = malloc (buf_size)) == NULL)
47d546f4
NA
355 return (ctf_set_errno (fp, EAGAIN));
356
357 memcpy (buf, &hdr, sizeof (ctf_header_t));
358 t = (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_varoff;
47d546f4 359
f5e9c9bd
NA
360 hdrp = (ctf_header_t *) buf;
361 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parname != NULL))
362 ctf_str_add_ref (fp, fp->ctf_parname, &hdrp->cth_parname);
fd55eae8
NA
363 if (fp->ctf_cuname != NULL)
364 ctf_str_add_ref (fp, fp->ctf_cuname, &hdrp->cth_cuname);
47d546f4 365
f5e9c9bd
NA
366 /* Work over the variable list, translating everything into ctf_varent_t's and
367 prepping the string table. */
47d546f4
NA
368
369 dvarents = (ctf_varent_t *) t;
370 for (i = 0, dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
371 dvd = ctf_list_next (dvd), i++)
372 {
373 ctf_varent_t *var = &dvarents[i];
47d546f4 374
f5e9c9bd 375 ctf_str_add_ref (fp, dvd->dvd_name, &var->ctv_name);
9943fa3a 376 var->ctv_type = (uint32_t) dvd->dvd_type;
47d546f4
NA
377 }
378 assert (i == nvars);
379
47d546f4
NA
380 t += sizeof (ctf_varent_t) * nvars;
381
382 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
383
f5e9c9bd
NA
384 /* We now take a final lap through the dynamic type definition list and copy
385 the appropriate type records to the output buffer, noting down the
386 strings as we go. */
47d546f4
NA
387
388 for (dtd = ctf_list_next (&fp->ctf_dtdefs);
389 dtd != NULL; dtd = ctf_list_next (dtd))
390 {
47d546f4
NA
391 uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
392 uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
393
394 ctf_array_t cta;
395 uint32_t encoding;
396 size_t len;
f5e9c9bd 397 ctf_stype_t *copied;
676c3ecb 398 const char *name;
47d546f4
NA
399
400 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
401 len = sizeof (ctf_stype_t);
402 else
403 len = sizeof (ctf_type_t);
404
405 memcpy (t, &dtd->dtd_data, len);
f5e9c9bd 406 copied = (ctf_stype_t *) t; /* name is at the start: constant offset. */
676c3ecb
NA
407 if (copied->ctt_name
408 && (name = ctf_strraw (fp, copied->ctt_name)) != NULL)
409 ctf_str_add_ref (fp, name, &copied->ctt_name);
47d546f4
NA
410 t += len;
411
412 switch (kind)
413 {
414 case CTF_K_INTEGER:
415 case CTF_K_FLOAT:
416 if (kind == CTF_K_INTEGER)
417 {
418 encoding = CTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format,
419 dtd->dtd_u.dtu_enc.cte_offset,
420 dtd->dtd_u.dtu_enc.cte_bits);
421 }
422 else
423 {
424 encoding = CTF_FP_DATA (dtd->dtd_u.dtu_enc.cte_format,
425 dtd->dtd_u.dtu_enc.cte_offset,
426 dtd->dtd_u.dtu_enc.cte_bits);
427 }
428 memcpy (t, &encoding, sizeof (encoding));
429 t += sizeof (encoding);
430 break;
431
432 case CTF_K_SLICE:
433 memcpy (t, &dtd->dtd_u.dtu_slice, sizeof (struct ctf_slice));
434 t += sizeof (struct ctf_slice);
435 break;
436
437 case CTF_K_ARRAY:
438 cta.cta_contents = (uint32_t) dtd->dtd_u.dtu_arr.ctr_contents;
439 cta.cta_index = (uint32_t) dtd->dtd_u.dtu_arr.ctr_index;
440 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
441 memcpy (t, &cta, sizeof (cta));
442 t += sizeof (cta);
443 break;
444
445 case CTF_K_FUNCTION:
446 {
447 uint32_t *argv = (uint32_t *) (uintptr_t) t;
448 uint32_t argc;
449
450 for (argc = 0; argc < vlen; argc++)
afd78bd6 451 *argv++ = dtd->dtd_u.dtu_argv[argc];
47d546f4
NA
452
453 if (vlen & 1)
454 *argv++ = 0; /* Pad to 4-byte boundary. */
455
456 t = (unsigned char *) argv;
457 break;
458 }
459
460 case CTF_K_STRUCT:
461 case CTF_K_UNION:
462 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
f5e9c9bd 463 t = ctf_copy_smembers (fp, dtd, t);
47d546f4 464 else
f5e9c9bd 465 t = ctf_copy_lmembers (fp, dtd, t);
47d546f4
NA
466 break;
467
468 case CTF_K_ENUM:
f5e9c9bd 469 t = ctf_copy_emembers (fp, dtd, t);
47d546f4
NA
470 break;
471 }
472 }
473 assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_stroff);
474
f5e9c9bd
NA
475 /* Construct the final string table and fill out all the string refs with the
476 final offsets. Then purge the refs list, because we're about to move this
477 strtab onto the end of the buf, invalidating all the offsets. */
478 strtab = ctf_str_write_strtab (fp);
479 ctf_str_purge_refs (fp);
480
d851ecd3
NA
481 if (strtab.cts_strs == NULL)
482 {
de07e349 483 free (buf);
d851ecd3
NA
484 return (ctf_set_errno (fp, EAGAIN));
485 }
486
f5e9c9bd
NA
487 /* Now the string table is constructed, we can sort the buffer of
488 ctf_varent_t's. */
d851ecd3 489 ctf_sort_var_arg_cb_t sort_var_arg = { fp, (ctf_strs_t *) &strtab };
f5e9c9bd 490 ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var,
d851ecd3 491 &sort_var_arg);
f5e9c9bd
NA
492
493 if ((newbuf = ctf_realloc (fp, buf, buf_size + strtab.cts_len)) == NULL)
494 {
de07e349
NA
495 free (buf);
496 free (strtab.cts_strs);
f5e9c9bd
NA
497 return (ctf_set_errno (fp, EAGAIN));
498 }
499 buf = newbuf;
500 memcpy (buf + buf_size, strtab.cts_strs, strtab.cts_len);
501 hdrp = (ctf_header_t *) buf;
502 hdrp->cth_strlen = strtab.cts_len;
503 buf_size += hdrp->cth_strlen;
de07e349 504 free (strtab.cts_strs);
f5e9c9bd 505
47d546f4
NA
506 /* Finally, we are ready to ctf_simple_open() the new container. If this
507 is successful, we then switch nfp and fp and free the old container. */
508
d851ecd3
NA
509 if ((nfp = ctf_simple_open_internal ((char *) buf, buf_size, NULL, 0,
510 0, NULL, 0, fp->ctf_syn_ext_strtab,
676c3ecb 511 1, &err)) == NULL)
47d546f4 512 {
de07e349 513 free (buf);
47d546f4
NA
514 return (ctf_set_errno (fp, err));
515 }
516
517 (void) ctf_setmodel (nfp, ctf_getmodel (fp));
518 (void) ctf_import (nfp, fp->ctf_parent);
519
520 nfp->ctf_refcnt = fp->ctf_refcnt;
521 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
fd55eae8
NA
522 if (nfp->ctf_dynbase == NULL)
523 nfp->ctf_dynbase = buf; /* Make sure buf is freed on close. */
47d546f4
NA
524 nfp->ctf_dthash = fp->ctf_dthash;
525 nfp->ctf_dtdefs = fp->ctf_dtdefs;
47d546f4
NA
526 nfp->ctf_dvhash = fp->ctf_dvhash;
527 nfp->ctf_dvdefs = fp->ctf_dvdefs;
676c3ecb 528 nfp->ctf_dtoldid = fp->ctf_dtoldid;
99dc3ebd 529 nfp->ctf_add_processing = fp->ctf_add_processing;
47d546f4
NA
530 nfp->ctf_snapshots = fp->ctf_snapshots + 1;
531 nfp->ctf_specific = fp->ctf_specific;
676c3ecb
NA
532 nfp->ctf_ptrtab = fp->ctf_ptrtab;
533 nfp->ctf_ptrtab_len = fp->ctf_ptrtab_len;
72c83edd
NA
534 nfp->ctf_link_inputs = fp->ctf_link_inputs;
535 nfp->ctf_link_outputs = fp->ctf_link_outputs;
676c3ecb 536 nfp->ctf_str_prov_offset = fp->ctf_str_prov_offset;
d851ecd3 537 nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
49ea9b45 538 nfp->ctf_link_cu_mapping = fp->ctf_link_cu_mapping;
886453cb 539 nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
49ea9b45
NA
540 nfp->ctf_link_memb_name_changer = fp->ctf_link_memb_name_changer;
541 nfp->ctf_link_memb_name_changer_arg = fp->ctf_link_memb_name_changer_arg;
47d546f4
NA
542
543 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
544
676c3ecb
NA
545 memcpy (&nfp->ctf_lookups, fp->ctf_lookups, sizeof (fp->ctf_lookups));
546 nfp->ctf_structs = fp->ctf_structs;
547 nfp->ctf_unions = fp->ctf_unions;
548 nfp->ctf_enums = fp->ctf_enums;
549 nfp->ctf_names = fp->ctf_names;
550
47d546f4 551 fp->ctf_dthash = NULL;
f5e9c9bd
NA
552 ctf_str_free_atoms (nfp);
553 nfp->ctf_str_atoms = fp->ctf_str_atoms;
676c3ecb 554 nfp->ctf_prov_strtab = fp->ctf_prov_strtab;
f5e9c9bd 555 fp->ctf_str_atoms = NULL;
676c3ecb 556 fp->ctf_prov_strtab = NULL;
47d546f4 557 memset (&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
99dc3ebd 558 fp->ctf_add_processing = NULL;
676c3ecb 559 fp->ctf_ptrtab = NULL;
72c83edd
NA
560 fp->ctf_link_inputs = NULL;
561 fp->ctf_link_outputs = NULL;
d851ecd3 562 fp->ctf_syn_ext_strtab = NULL;
49ea9b45 563 fp->ctf_link_cu_mapping = NULL;
886453cb 564 fp->ctf_link_type_mapping = NULL;
47d546f4
NA
565
566 fp->ctf_dvhash = NULL;
567 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
676c3ecb
NA
568 memset (fp->ctf_lookups, 0, sizeof (fp->ctf_lookups));
569 fp->ctf_structs.ctn_writable = NULL;
570 fp->ctf_unions.ctn_writable = NULL;
571 fp->ctf_enums.ctn_writable = NULL;
572 fp->ctf_names.ctn_writable = NULL;
47d546f4
NA
573
574 memcpy (&ofp, fp, sizeof (ctf_file_t));
575 memcpy (fp, nfp, sizeof (ctf_file_t));
576 memcpy (nfp, &ofp, sizeof (ctf_file_t));
577
47d546f4
NA
578 nfp->ctf_refcnt = 1; /* Force nfp to be freed. */
579 ctf_file_close (nfp);
580
581 return 0;
582}
583
676c3ecb
NA
584ctf_names_t *
585ctf_name_table (ctf_file_t *fp, int kind)
47d546f4 586{
47d546f4
NA
587 switch (kind)
588 {
589 case CTF_K_STRUCT:
676c3ecb 590 return &fp->ctf_structs;
47d546f4 591 case CTF_K_UNION:
676c3ecb 592 return &fp->ctf_unions;
47d546f4 593 case CTF_K_ENUM:
676c3ecb 594 return &fp->ctf_enums;
47d546f4 595 default:
676c3ecb 596 return &fp->ctf_names;
47d546f4 597 }
47d546f4
NA
598}
599
24865428 600int
fe4c2d55 601ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
47d546f4 602{
676c3ecb 603 const char *name;
24865428
NA
604 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0)
605 return -1;
606
fe4c2d55 607 if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
676c3ecb 608 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
47d546f4 609 {
676c3ecb
NA
610 if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable,
611 (char *) name, (void *) dtd->dtd_type) < 0)
612 {
613 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
614 return -1;
615 }
47d546f4 616 }
24865428
NA
617 ctf_list_append (&fp->ctf_dtdefs, dtd);
618 return 0;
47d546f4
NA
619}
620
621void
622ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
623{
624 ctf_dmdef_t *dmd, *nmd;
625 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
8ffcdf18 626 int name_kind = kind;
676c3ecb 627 const char *name;
47d546f4
NA
628
629 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
630
631 switch (kind)
632 {
633 case CTF_K_STRUCT:
634 case CTF_K_UNION:
635 case CTF_K_ENUM:
636 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
637 dmd != NULL; dmd = nmd)
638 {
639 if (dmd->dmd_name != NULL)
de07e349 640 free (dmd->dmd_name);
47d546f4 641 nmd = ctf_list_next (dmd);
de07e349 642 free (dmd);
47d546f4
NA
643 }
644 break;
645 case CTF_K_FUNCTION:
de07e349 646 free (dtd->dtd_u.dtu_argv);
47d546f4 647 break;
8ffcdf18
NA
648 case CTF_K_FORWARD:
649 name_kind = dtd->dtd_data.ctt_type;
650 break;
47d546f4
NA
651 }
652
676c3ecb 653 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
654 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
655 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
47d546f4 656 {
8ffcdf18 657 ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
676c3ecb
NA
658 name);
659 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
660 }
661
662 ctf_list_delete (&fp->ctf_dtdefs, dtd);
de07e349 663 free (dtd);
47d546f4
NA
664}
665
666ctf_dtdef_t *
667ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
668{
669 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
670}
671
47d546f4
NA
672ctf_dtdef_t *
673ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
674{
675 ctf_id_t idx;
676
676c3ecb
NA
677 if (!(fp->ctf_flags & LCTF_RDWR))
678 return NULL;
679
47d546f4
NA
680 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
681 fp = fp->ctf_parent;
682
683 idx = LCTF_TYPE_TO_INDEX(fp, id);
684
676c3ecb 685 if ((unsigned long) idx <= fp->ctf_typemax)
47d546f4
NA
686 return ctf_dtd_lookup (fp, id);
687 return NULL;
688}
689
24865428 690int
47d546f4
NA
691ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
692{
24865428
NA
693 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
694 return -1;
47d546f4 695 ctf_list_append (&fp->ctf_dvdefs, dvd);
24865428 696 return 0;
47d546f4
NA
697}
698
699void
700ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
701{
702 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
de07e349 703 free (dvd->dvd_name);
47d546f4
NA
704
705 ctf_list_delete (&fp->ctf_dvdefs, dvd);
de07e349 706 free (dvd);
47d546f4
NA
707}
708
709ctf_dvdef_t *
710ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
711{
712 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
713}
714
715/* Discard all of the dynamic type definitions and variable definitions that
716 have been added to the container since the last call to ctf_update(). We
717 locate such types by scanning the dtd list and deleting elements that have
718 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
719 by scanning the variable list and deleting elements that have update IDs
720 equal to the current value of the last-update snapshot count (indicating that
721 they were added after the most recent call to ctf_update()). */
722int
723ctf_discard (ctf_file_t *fp)
724{
725 ctf_snapshot_id_t last_update =
726 { fp->ctf_dtoldid,
727 fp->ctf_snapshot_lu + 1 };
728
729 /* Update required? */
730 if (!(fp->ctf_flags & LCTF_DIRTY))
731 return 0;
732
733 return (ctf_rollback (fp, last_update));
734}
735
736ctf_snapshot_id_t
737ctf_snapshot (ctf_file_t *fp)
738{
739 ctf_snapshot_id_t snapid;
676c3ecb 740 snapid.dtd_id = fp->ctf_typemax;
47d546f4
NA
741 snapid.snapshot_id = fp->ctf_snapshots++;
742 return snapid;
743}
744
745/* Like ctf_discard(), only discards everything after a particular ID. */
746int
747ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
748{
749 ctf_dtdef_t *dtd, *ntd;
750 ctf_dvdef_t *dvd, *nvd;
751
752 if (!(fp->ctf_flags & LCTF_RDWR))
753 return (ctf_set_errno (fp, ECTF_RDONLY));
754
47d546f4
NA
755 if (fp->ctf_snapshot_lu >= id.snapshot_id)
756 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
757
758 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
759 {
676c3ecb
NA
760 int kind;
761 const char *name;
762
47d546f4
NA
763 ntd = ctf_list_next (dtd);
764
765 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
766 continue;
767
676c3ecb 768 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
8ffcdf18
NA
769 if (kind == CTF_K_FORWARD)
770 kind = dtd->dtd_data.ctt_type;
676c3ecb
NA
771
772 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
773 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
774 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
676c3ecb
NA
775 {
776 ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
777 name);
778 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
779 }
780
781 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
47d546f4
NA
782 ctf_dtd_delete (fp, dtd);
783 }
784
785 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
786 {
787 nvd = ctf_list_next (dvd);
788
789 if (dvd->dvd_snapshots <= id.snapshot_id)
790 continue;
791
792 ctf_dvd_delete (fp, dvd);
793 }
794
676c3ecb 795 fp->ctf_typemax = id.dtd_id;
47d546f4
NA
796 fp->ctf_snapshots = id.snapshot_id;
797
798 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
799 fp->ctf_flags &= ~LCTF_DIRTY;
800
801 return 0;
802}
803
804static ctf_id_t
676c3ecb 805ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name, int kind,
47d546f4
NA
806 ctf_dtdef_t **rp)
807{
808 ctf_dtdef_t *dtd;
809 ctf_id_t type;
47d546f4
NA
810
811 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
812 return (ctf_set_errno (fp, EINVAL));
813
814 if (!(fp->ctf_flags & LCTF_RDWR))
815 return (ctf_set_errno (fp, ECTF_RDONLY));
816
676c3ecb 817 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
47d546f4
NA
818 return (ctf_set_errno (fp, ECTF_FULL));
819
676c3ecb 820 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
47d546f4
NA
821 return (ctf_set_errno (fp, ECTF_FULL));
822
676c3ecb
NA
823 /* Make sure ptrtab always grows to be big enough for all types. */
824 if (ctf_grow_ptrtab (fp) < 0)
825 return CTF_ERR; /* errno is set for us. */
826
de07e349 827 if ((dtd = malloc (sizeof (ctf_dtdef_t))) == NULL)
47d546f4
NA
828 return (ctf_set_errno (fp, EAGAIN));
829
676c3ecb 830 type = ++fp->ctf_typemax;
47d546f4
NA
831 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
832
833 memset (dtd, 0, sizeof (ctf_dtdef_t));
676c3ecb 834 dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
835 dtd->dtd_type = type;
836
676c3ecb
NA
837 if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
838 {
de07e349 839 free (dtd);
676c3ecb
NA
840 return (ctf_set_errno (fp, EAGAIN));
841 }
842
fe4c2d55 843 if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
24865428 844 {
de07e349 845 free (dtd);
24865428
NA
846 return CTF_ERR; /* errno is set for us. */
847 }
47d546f4
NA
848 fp->ctf_flags |= LCTF_DIRTY;
849
850 *rp = dtd;
851 return type;
852}
853
854/* When encoding integer sizes, we want to convert a byte count in the range
855 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
856 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
857static size_t
858clp2 (size_t x)
859{
860 x--;
861
862 x |= (x >> 1);
863 x |= (x >> 2);
864 x |= (x >> 4);
865 x |= (x >> 8);
866 x |= (x >> 16);
867
868 return (x + 1);
869}
870
871static ctf_id_t
872ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
873 const char *name, const ctf_encoding_t *ep, uint32_t kind)
874{
875 ctf_dtdef_t *dtd;
876 ctf_id_t type;
877
878 if (ep == NULL)
879 return (ctf_set_errno (fp, EINVAL));
880
676c3ecb 881 if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
47d546f4
NA
882 return CTF_ERR; /* errno is set for us. */
883
884 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
76fad999
TT
885 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
886 / CHAR_BIT);
47d546f4
NA
887 dtd->dtd_u.dtu_enc = *ep;
888
889 return type;
890}
891
892static ctf_id_t
893ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
894{
895 ctf_dtdef_t *dtd;
896 ctf_id_t type;
897 ctf_file_t *tmp = fp;
676c3ecb 898 int child = fp->ctf_flags & LCTF_CHILD;
47d546f4 899
a0486bac 900 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
901 return (ctf_set_errno (fp, EINVAL));
902
2361f1c8 903 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
47d546f4
NA
904 return CTF_ERR; /* errno is set for us. */
905
676c3ecb 906 if ((type = ctf_add_generic (fp, flag, NULL, kind, &dtd)) == CTF_ERR)
47d546f4
NA
907 return CTF_ERR; /* errno is set for us. */
908
909 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
910 dtd->dtd_data.ctt_type = (uint32_t) ref;
911
676c3ecb
NA
912 if (kind != CTF_K_POINTER)
913 return type;
914
915 /* If we are adding a pointer, update the ptrtab, both the directly pointed-to
916 type and (if an anonymous typedef node is being pointed at) the type that
917 points at too. Note that ctf_typemax is at this point one higher than we
918 want to check against, because it's just been incremented for the addition
919 of this type. */
920
921 uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
922 uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
923
924 if (LCTF_TYPE_ISCHILD (fp, ref) == child
925 && ref_idx < fp->ctf_typemax)
926 {
927 fp->ctf_ptrtab[ref_idx] = type_idx;
928
929 ctf_id_t refref_idx = LCTF_TYPE_TO_INDEX (fp, dtd->dtd_data.ctt_type);
930
931 if (tmp == fp
932 && (LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) == CTF_K_TYPEDEF)
933 && strcmp (ctf_strptr (fp, dtd->dtd_data.ctt_name), "") == 0
934 && refref_idx < fp->ctf_typemax)
935 fp->ctf_ptrtab[refref_idx] = type_idx;
936 }
937
47d546f4
NA
938 return type;
939}
940
941ctf_id_t
942ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
943 const ctf_encoding_t *ep)
944{
945 ctf_dtdef_t *dtd;
946 ctf_id_t type;
947 int kind;
948 const ctf_type_t *tp;
949 ctf_file_t *tmp = fp;
950
951 if (ep == NULL)
952 return (ctf_set_errno (fp, EINVAL));
953
954 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
955 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
956
a0486bac 957 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
958 return (ctf_set_errno (fp, EINVAL));
959
2361f1c8 960 if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
47d546f4
NA
961 return CTF_ERR; /* errno is set for us. */
962
963 kind = ctf_type_kind_unsliced (tmp, ref);
964 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
2361f1c8
NA
965 (kind != CTF_K_ENUM)
966 && (ref != 0))
47d546f4
NA
967 return (ctf_set_errno (fp, ECTF_NOTINTFP));
968
676c3ecb 969 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE, &dtd)) == CTF_ERR)
47d546f4
NA
970 return CTF_ERR; /* errno is set for us. */
971
972 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
76fad999
TT
973 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
974 / CHAR_BIT);
9943fa3a 975 dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref;
47d546f4
NA
976 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
977 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
978
979 return type;
980}
981
982ctf_id_t
983ctf_add_integer (ctf_file_t *fp, uint32_t flag,
984 const char *name, const ctf_encoding_t *ep)
985{
986 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
987}
988
989ctf_id_t
990ctf_add_float (ctf_file_t *fp, uint32_t flag,
991 const char *name, const ctf_encoding_t *ep)
992{
993 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
994}
995
996ctf_id_t
997ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
998{
999 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
1000}
1001
1002ctf_id_t
1003ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
1004{
1005 ctf_dtdef_t *dtd;
1006 ctf_id_t type;
1007 ctf_file_t *tmp = fp;
1008
1009 if (arp == NULL)
1010 return (ctf_set_errno (fp, EINVAL));
1011
2361f1c8
NA
1012 if (arp->ctr_contents != 0
1013 && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
47d546f4
NA
1014 return CTF_ERR; /* errno is set for us. */
1015
1016 tmp = fp;
1017 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
1018 return CTF_ERR; /* errno is set for us. */
1019
676c3ecb 1020 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY, &dtd)) == CTF_ERR)
47d546f4
NA
1021 return CTF_ERR; /* errno is set for us. */
1022
1023 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
1024 dtd->dtd_data.ctt_size = 0;
1025 dtd->dtd_u.dtu_arr = *arp;
1026
1027 return type;
1028}
1029
1030int
1031ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
1032{
1033 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1034
1035 if (!(fp->ctf_flags & LCTF_RDWR))
1036 return (ctf_set_errno (fp, ECTF_RDONLY));
1037
1038 if (dtd == NULL
1039 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
1040 return (ctf_set_errno (fp, ECTF_BADID));
1041
1042 fp->ctf_flags |= LCTF_DIRTY;
1043 dtd->dtd_u.dtu_arr = *arp;
1044
1045 return 0;
1046}
1047
1048ctf_id_t
1049ctf_add_function (ctf_file_t *fp, uint32_t flag,
1050 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
1051{
1052 ctf_dtdef_t *dtd;
1053 ctf_id_t type;
1054 uint32_t vlen;
afd78bd6 1055 uint32_t *vdat = NULL;
47d546f4
NA
1056 ctf_file_t *tmp = fp;
1057 size_t i;
1058
1059 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
1060 || (ctc->ctc_argc != 0 && argv == NULL))
1061 return (ctf_set_errno (fp, EINVAL));
1062
1063 vlen = ctc->ctc_argc;
1064 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1065 vlen++; /* Add trailing zero to indicate varargs (see below). */
1066
2361f1c8
NA
1067 if (ctc->ctc_return != 0
1068 && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
47d546f4
NA
1069 return CTF_ERR; /* errno is set for us. */
1070
47d546f4
NA
1071 if (vlen > CTF_MAX_VLEN)
1072 return (ctf_set_errno (fp, EOVERFLOW));
1073
de07e349 1074 if (vlen != 0 && (vdat = malloc (sizeof (ctf_id_t) * vlen)) == NULL)
47d546f4
NA
1075 return (ctf_set_errno (fp, EAGAIN));
1076
afd78bd6
NA
1077 for (i = 0; i < ctc->ctc_argc; i++)
1078 {
1079 tmp = fp;
1080 if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
1081 {
1082 free (vdat);
1083 return CTF_ERR; /* errno is set for us. */
1084 }
1085 vdat[i] = (uint32_t) argv[i];
1086 }
1087
676c3ecb
NA
1088 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
1089 &dtd)) == CTF_ERR)
47d546f4 1090 {
de07e349 1091 free (vdat);
47d546f4
NA
1092 return CTF_ERR; /* errno is set for us. */
1093 }
1094
1095 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
1096 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
1097
47d546f4
NA
1098 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1099 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
1100 dtd->dtd_u.dtu_argv = vdat;
1101
1102 return type;
1103}
1104
1105ctf_id_t
1106ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1107 size_t size)
1108{
47d546f4
NA
1109 ctf_dtdef_t *dtd;
1110 ctf_id_t type = 0;
1111
fe4c2d55 1112 /* Promote root-visible forwards to structs. */
47d546f4 1113 if (name != NULL)
676c3ecb 1114 type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
47d546f4
NA
1115
1116 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1117 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1118 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
1119 &dtd)) == CTF_ERR)
47d546f4
NA
1120 return CTF_ERR; /* errno is set for us. */
1121
1122 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1123
1124 if (size > CTF_MAX_SIZE)
1125 {
1126 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1127 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1128 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1129 }
1130 else
1131 dtd->dtd_data.ctt_size = (uint32_t) size;
1132
1133 return type;
1134}
1135
1136ctf_id_t
1137ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1138{
1139 return (ctf_add_struct_sized (fp, flag, name, 0));
1140}
1141
1142ctf_id_t
1143ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1144 size_t size)
1145{
47d546f4
NA
1146 ctf_dtdef_t *dtd;
1147 ctf_id_t type = 0;
1148
fe4c2d55 1149 /* Promote root-visible forwards to unions. */
47d546f4 1150 if (name != NULL)
676c3ecb 1151 type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
47d546f4
NA
1152
1153 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1154 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1155 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
1156 &dtd)) == CTF_ERR)
47d546f4
NA
1157 return CTF_ERR; /* errno is set for us */
1158
1159 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1160
1161 if (size > CTF_MAX_SIZE)
1162 {
1163 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1164 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1165 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1166 }
1167 else
1168 dtd->dtd_data.ctt_size = (uint32_t) size;
1169
1170 return type;
1171}
1172
1173ctf_id_t
1174ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1175{
1176 return (ctf_add_union_sized (fp, flag, name, 0));
1177}
1178
1179ctf_id_t
1180ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1181{
47d546f4
NA
1182 ctf_dtdef_t *dtd;
1183 ctf_id_t type = 0;
1184
fe4c2d55 1185 /* Promote root-visible forwards to enums. */
47d546f4 1186 if (name != NULL)
676c3ecb 1187 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1188
1189 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1190 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1191 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
1192 &dtd)) == CTF_ERR)
47d546f4
NA
1193 return CTF_ERR; /* errno is set for us. */
1194
1195 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1196 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1197
1198 return type;
1199}
1200
1201ctf_id_t
1202ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1203 const ctf_encoding_t *ep)
1204{
47d546f4
NA
1205 ctf_id_t type = 0;
1206
1207 /* First, create the enum if need be, using most of the same machinery as
1208 ctf_add_enum(), to ensure that we do not allow things past that are not
1209 enums or forwards to them. (This includes other slices: you cannot slice a
1210 slice, which would be a useless thing to do anyway.) */
1211
1212 if (name != NULL)
676c3ecb 1213 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1214
1215 if (type != 0)
1216 {
1217 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1218 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1219 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1220 }
1221 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1222 return CTF_ERR; /* errno is set for us. */
1223
1224 /* Now attach a suitable slice to it. */
1225
1226 return ctf_add_slice (fp, flag, type, ep);
1227}
1228
1229ctf_id_t
1230ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1231 uint32_t kind)
1232{
47d546f4
NA
1233 ctf_dtdef_t *dtd;
1234 ctf_id_t type = 0;
1235
676c3ecb
NA
1236 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1237 return (ctf_set_errno (fp, ECTF_NOTSUE));
47d546f4
NA
1238
1239 /* If the type is already defined or exists as a forward tag, just
1240 return the ctf_id_t of the existing definition. */
1241
1242 if (name != NULL)
676c3ecb 1243 type = ctf_lookup_by_rawname (fp, kind, name);
47d546f4 1244
6bbf9da8
NA
1245 if (type)
1246 return type;
1247
8ffcdf18 1248 if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
47d546f4
NA
1249 return CTF_ERR; /* errno is set for us. */
1250
1251 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1252 dtd->dtd_data.ctt_type = kind;
1253
1254 return type;
1255}
1256
1257ctf_id_t
1258ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1259 ctf_id_t ref)
1260{
1261 ctf_dtdef_t *dtd;
1262 ctf_id_t type;
1263 ctf_file_t *tmp = fp;
1264
a0486bac 1265 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1266 return (ctf_set_errno (fp, EINVAL));
1267
2361f1c8 1268 if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
47d546f4
NA
1269 return CTF_ERR; /* errno is set for us. */
1270
676c3ecb
NA
1271 if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF,
1272 &dtd)) == CTF_ERR)
47d546f4
NA
1273 return CTF_ERR; /* errno is set for us. */
1274
1275 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1276 dtd->dtd_data.ctt_type = (uint32_t) ref;
1277
1278 return type;
1279}
1280
1281ctf_id_t
1282ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1283{
1284 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1285}
1286
1287ctf_id_t
1288ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1289{
1290 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1291}
1292
1293ctf_id_t
1294ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1295{
1296 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1297}
1298
1299int
1300ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1301 int value)
1302{
1303 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1304 ctf_dmdef_t *dmd;
1305
1306 uint32_t kind, vlen, root;
1307 char *s;
1308
1309 if (name == NULL)
1310 return (ctf_set_errno (fp, EINVAL));
1311
1312 if (!(fp->ctf_flags & LCTF_RDWR))
1313 return (ctf_set_errno (fp, ECTF_RDONLY));
1314
1315 if (dtd == NULL)
1316 return (ctf_set_errno (fp, ECTF_BADID));
1317
1318 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1319 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1320 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1321
1322 if (kind != CTF_K_ENUM)
1323 return (ctf_set_errno (fp, ECTF_NOTENUM));
1324
1325 if (vlen == CTF_MAX_VLEN)
1326 return (ctf_set_errno (fp, ECTF_DTFULL));
1327
1328 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1329 dmd != NULL; dmd = ctf_list_next (dmd))
1330 {
1331 if (strcmp (dmd->dmd_name, name) == 0)
1332 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1333 }
1334
de07e349 1335 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
1336 return (ctf_set_errno (fp, EAGAIN));
1337
de07e349 1338 if ((s = strdup (name)) == NULL)
47d546f4 1339 {
de07e349 1340 free (dmd);
47d546f4
NA
1341 return (ctf_set_errno (fp, EAGAIN));
1342 }
1343
1344 dmd->dmd_name = s;
1345 dmd->dmd_type = CTF_ERR;
1346 dmd->dmd_offset = 0;
1347 dmd->dmd_value = value;
1348
1349 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1350 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1351
47d546f4
NA
1352 fp->ctf_flags |= LCTF_DIRTY;
1353
1354 return 0;
1355}
1356
1357int
1358ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1359 ctf_id_t type, unsigned long bit_offset)
1360{
1361 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1362 ctf_dmdef_t *dmd;
1363
1364 ssize_t msize, malign, ssize;
1365 uint32_t kind, vlen, root;
1366 char *s = NULL;
1367
1368 if (!(fp->ctf_flags & LCTF_RDWR))
1369 return (ctf_set_errno (fp, ECTF_RDONLY));
1370
1371 if (dtd == NULL)
1372 return (ctf_set_errno (fp, ECTF_BADID));
1373
ab769488
NA
1374 if (name != NULL && name[0] == '\0')
1375 name = NULL;
1376
47d546f4
NA
1377 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1378 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1379 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1380
1381 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1382 return (ctf_set_errno (fp, ECTF_NOTSOU));
1383
1384 if (vlen == CTF_MAX_VLEN)
1385 return (ctf_set_errno (fp, ECTF_DTFULL));
1386
1387 if (name != NULL)
1388 {
1389 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1390 dmd != NULL; dmd = ctf_list_next (dmd))
1391 {
1392 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1393 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1394 }
1395 }
1396
a0486bac
JM
1397 if ((msize = ctf_type_size (fp, type)) < 0 ||
1398 (malign = ctf_type_align (fp, type)) < 0)
2361f1c8
NA
1399 {
1400 /* The unimplemented type, and any type that resolves to it, has no size
1401 and no alignment: it can correspond to any number of compiler-inserted
1402 types. */
1403
1404 if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
1405 {
1406 msize = 0;
1407 malign = 0;
1408 ctf_set_errno (fp, 0);
1409 }
1410 else
1411 return -1; /* errno is set for us. */
1412 }
47d546f4 1413
de07e349 1414 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
1415 return (ctf_set_errno (fp, EAGAIN));
1416
de07e349 1417 if (name != NULL && (s = strdup (name)) == NULL)
47d546f4 1418 {
de07e349 1419 free (dmd);
47d546f4
NA
1420 return (ctf_set_errno (fp, EAGAIN));
1421 }
1422
1423 dmd->dmd_name = s;
1424 dmd->dmd_type = type;
1425 dmd->dmd_value = -1;
1426
1427 if (kind == CTF_K_STRUCT && vlen != 0)
1428 {
1429 if (bit_offset == (unsigned long) - 1)
1430 {
1431 /* Natural alignment. */
1432
1433 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1434 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1435 size_t off = lmd->dmd_offset;
1436
1437 ctf_encoding_t linfo;
1438 ssize_t lsize;
1439
2361f1c8
NA
1440 /* Propagate any error from ctf_type_resolve. If the last member was
1441 of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
1442 cannot insert right after such a member without explicit offset
1443 specification, because its alignment and size is not known. */
1444 if (ltype == CTF_ERR)
1445 {
1446 free (dmd);
1447 return -1; /* errno is set for us. */
1448 }
1449
a0486bac 1450 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
47d546f4 1451 off += linfo.cte_bits;
a0486bac 1452 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
76fad999 1453 off += lsize * CHAR_BIT;
47d546f4
NA
1454
1455 /* Round up the offset of the end of the last member to
1456 the next byte boundary, convert 'off' to bytes, and
1457 then round it up again to the next multiple of the
1458 alignment required by the new member. Finally,
1459 convert back to bits and store the result in
1460 dmd_offset. Technically we could do more efficient
1461 packing if the new member is a bit-field, but we're
1462 the "compiler" and ANSI says we can do as we choose. */
1463
76fad999 1464 off = roundup (off, CHAR_BIT) / CHAR_BIT;
47d546f4 1465 off = roundup (off, MAX (malign, 1));
76fad999 1466 dmd->dmd_offset = off * CHAR_BIT;
47d546f4
NA
1467 ssize = off + msize;
1468 }
1469 else
1470 {
1471 /* Specified offset in bits. */
1472
1473 dmd->dmd_offset = bit_offset;
1474 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
76fad999 1475 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
47d546f4
NA
1476 }
1477 }
1478 else
1479 {
1480 dmd->dmd_offset = 0;
1481 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1482 ssize = MAX (ssize, msize);
1483 }
1484
a0486bac 1485 if ((size_t) ssize > CTF_MAX_SIZE)
47d546f4
NA
1486 {
1487 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1488 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1489 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1490 }
1491 else
1492 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1493
1494 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1495 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1496
47d546f4
NA
1497 fp->ctf_flags |= LCTF_DIRTY;
1498 return 0;
1499}
1500
1501int
1502ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1503 ctf_id_t type, unsigned long bit_offset,
1504 const ctf_encoding_t encoding)
1505{
1506 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1507 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1508 int otype = type;
1509
1510 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1511 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1512
1513 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
a0486bac 1514 return -1; /* errno is set for us. */
47d546f4
NA
1515
1516 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1517}
1518
1519int
1520ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1521 ctf_id_t type)
1522{
1523 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1524}
1525
1526int
1527ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1528{
1529 ctf_dvdef_t *dvd;
1530 ctf_file_t *tmp = fp;
1531
1532 if (!(fp->ctf_flags & LCTF_RDWR))
1533 return (ctf_set_errno (fp, ECTF_RDONLY));
1534
1535 if (ctf_dvd_lookup (fp, name) != NULL)
1536 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1537
1538 if (ctf_lookup_by_id (&tmp, ref) == NULL)
a0486bac 1539 return -1; /* errno is set for us. */
47d546f4 1540
791915db
NA
1541 /* Make sure this type is representable. */
1542 if ((ctf_type_resolve (fp, ref) == CTF_ERR)
1543 && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
1544 return -1;
1545
de07e349 1546 if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
47d546f4
NA
1547 return (ctf_set_errno (fp, EAGAIN));
1548
de07e349 1549 if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
47d546f4 1550 {
de07e349 1551 free (dvd);
47d546f4
NA
1552 return (ctf_set_errno (fp, EAGAIN));
1553 }
1554 dvd->dvd_type = ref;
1555 dvd->dvd_snapshots = fp->ctf_snapshots;
1556
24865428
NA
1557 if (ctf_dvd_insert (fp, dvd) < 0)
1558 {
de07e349
NA
1559 free (dvd->dvd_name);
1560 free (dvd);
24865428
NA
1561 return -1; /* errno is set for us. */
1562 }
47d546f4 1563
47d546f4
NA
1564 fp->ctf_flags |= LCTF_DIRTY;
1565 return 0;
1566}
1567
c499eb68
NA
1568static int
1569enumcmp (const char *name, int value, void *arg)
1570{
1571 ctf_bundle_t *ctb = arg;
1572 int bvalue;
1573
a0486bac 1574 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
c499eb68 1575 {
99dc3ebd
NA
1576 ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1577 ctf_errmsg (ctf_errno (ctb->ctb_file)));
c499eb68
NA
1578 return 1;
1579 }
1580 if (value != bvalue)
1581 {
1582 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1583 value, bvalue);
1584 return 1;
1585 }
1586 return 0;
1587}
1588
1589static int
1590enumadd (const char *name, int value, void *arg)
1591{
1592 ctf_bundle_t *ctb = arg;
1593
1594 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
a0486bac 1595 name, value) < 0);
c499eb68
NA
1596}
1597
1598static int
1599membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1600 void *arg)
1601{
1602 ctf_bundle_t *ctb = arg;
1603 ctf_membinfo_t ctm;
1604
f47ca311
NA
1605 /* Don't check nameless members (e.g. anonymous structs/unions) against each
1606 other. */
1607 if (name[0] == 0)
1608 return 0;
1609
a0486bac 1610 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
c499eb68 1611 {
99dc3ebd
NA
1612 ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1613 ctf_errmsg (ctf_errno (ctb->ctb_file)));
c499eb68
NA
1614 return 1;
1615 }
1616 if (ctm.ctm_offset != offset)
1617 {
1618 ctf_dprintf ("Conflict due to member %s offset change: "
1619 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1620 return 1;
1621 }
1622 return 0;
1623}
1624
1625static int
1626membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1627{
1628 ctf_bundle_t *ctb = arg;
1629 ctf_dmdef_t *dmd;
1630 char *s = NULL;
1631
de07e349 1632 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
c499eb68
NA
1633 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1634
de07e349 1635 if (name != NULL && (s = strdup (name)) == NULL)
c499eb68 1636 {
de07e349 1637 free (dmd);
c499eb68
NA
1638 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1639 }
1640
1641 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1642 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1643 dmd->dmd_name = s;
1644 dmd->dmd_type = type;
1645 dmd->dmd_offset = offset;
1646 dmd->dmd_value = -1;
1647
1648 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1649
c499eb68
NA
1650 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1651 return 0;
1652}
1653
1654/* The ctf_add_type routine is used to copy a type from a source CTF container
1655 to a dynamic destination container. This routine operates recursively by
1656 following the source type's links and embedded member types. If the
1657 destination container already contains a named type which has the same
1658 attributes, then we succeed and return this type but no changes occur. */
99dc3ebd
NA
1659static ctf_id_t
1660ctf_add_type_internal (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type,
1661 ctf_file_t *proc_tracking_fp)
c499eb68
NA
1662{
1663 ctf_id_t dst_type = CTF_ERR;
1664 uint32_t dst_kind = CTF_K_UNKNOWN;
99dc3ebd 1665 ctf_file_t *tmp_fp = dst_fp;
c499eb68
NA
1666 ctf_id_t tmp;
1667
1668 const char *name;
5de9eada 1669 uint32_t kind, forward_kind, flag, vlen;
c499eb68
NA
1670
1671 const ctf_type_t *src_tp, *dst_tp;
1672 ctf_bundle_t src, dst;
1673 ctf_encoding_t src_en, dst_en;
1674 ctf_arinfo_t src_ar, dst_ar;
1675
c499eb68 1676 ctf_funcinfo_t ctc;
c499eb68 1677
886453cb 1678 ctf_id_t orig_src_type = src_type;
c499eb68
NA
1679
1680 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1681 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1682
1683 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1684 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1685
791915db
NA
1686 if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
1687 && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
1688 return (ctf_set_errno (dst_fp, ECTF_NONREPRESENTABLE));
1689
c499eb68
NA
1690 name = ctf_strptr (src_fp, src_tp->ctt_name);
1691 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1692 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1693 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1694
99dc3ebd
NA
1695 /* If this is a type we are currently in the middle of adding, hand it
1696 straight back. (This lets us handle self-referential structures without
1697 considering forwards and empty structures the same as their completed
1698 forms.) */
1699
1700 tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1701
1702 if (tmp != 0)
1703 {
1704 if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1705 (void *) (uintptr_t) src_type))
1706 return tmp;
1707
1708 /* If this type has already been added from this container, and is the same
1709 kind and (if a struct or union) has the same number of members, hand it
1710 straight back. */
1711
d04a47ac 1712 if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
99dc3ebd 1713 {
d04a47ac
NA
1714 if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1715 || kind == CTF_K_ENUM)
1716 {
1717 if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1718 if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1719 return tmp;
1720 }
1721 else
1722 return tmp;
99dc3ebd
NA
1723 }
1724 }
1725
5de9eada
NA
1726 forward_kind = kind;
1727 if (kind == CTF_K_FORWARD)
1728 forward_kind = src_tp->ctt_type;
1729
c499eb68
NA
1730 /* If the source type has a name and is a root type (visible at the
1731 top-level scope), lookup the name in the destination container and
1732 verify that it is of the same kind before we do anything else. */
1733
1734 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
676c3ecb 1735 && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
c499eb68
NA
1736 {
1737 dst_type = tmp;
1738 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1739 }
1740
1741 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1742 unless dst_type is a forward declaration and src_type is a struct,
5de9eada 1743 union, or enum (i.e. the definition of the previous forward decl).
c499eb68 1744
5de9eada
NA
1745 We also allow addition in the opposite order (addition of a forward when a
1746 struct, union, or enum already exists), which is a NOP and returns the
1747 already-present struct, union, or enum. */
1748
1749 if (dst_type != CTF_ERR && dst_kind != kind)
c499eb68 1750 {
5de9eada
NA
1751 if (kind == CTF_K_FORWARD
1752 && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1753 || dst_kind == CTF_K_UNION))
1754 {
1755 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1756 return dst_type;
1757 }
1758
1759 if (dst_kind != CTF_K_FORWARD
1760 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1761 && kind != CTF_K_UNION))
1762 {
1763 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1764 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1765 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1766 }
c499eb68
NA
1767 }
1768
1769 /* We take special action for an integer, float, or slice since it is
1770 described not only by its name but also its encoding. For integers,
1771 bit-fields exploit this degeneracy. */
1772
1773 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1774 {
1775 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1776 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1777
1778 if (dst_type != CTF_ERR)
1779 {
1780 ctf_file_t *fp = dst_fp;
1781
1782 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1783 return CTF_ERR;
1784
99dc3ebd
NA
1785 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1786 return CTF_ERR; /* errno set for us. */
1787
c499eb68
NA
1788 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1789 {
1790 /* The type that we found in the hash is also root-visible. If
1791 the two types match then use the existing one; otherwise,
1792 declare a conflict. Note: slices are not certain to match
1793 even if there is no conflict: we must check the contained type
1794 too. */
1795
c499eb68
NA
1796 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1797 {
1798 if (kind != CTF_K_SLICE)
886453cb
NA
1799 {
1800 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1801 return dst_type;
1802 }
c499eb68
NA
1803 }
1804 else
1805 {
1806 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1807 }
1808 }
1809 else
1810 {
99dc3ebd
NA
1811 /* We found a non-root-visible type in the hash. If its encoding
1812 is the same, we can reuse it, unless it is a slice. */
c499eb68 1813
99dc3ebd 1814 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
c499eb68
NA
1815 {
1816 if (kind != CTF_K_SLICE)
886453cb 1817 {
99dc3ebd
NA
1818 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1819 return dst_type;
886453cb 1820 }
c499eb68 1821 }
c499eb68
NA
1822 }
1823 }
1824 }
1825
1826 src.ctb_file = src_fp;
1827 src.ctb_type = src_type;
1828 src.ctb_dtd = NULL;
1829
1830 dst.ctb_file = dst_fp;
1831 dst.ctb_type = dst_type;
1832 dst.ctb_dtd = NULL;
1833
99dc3ebd
NA
1834 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
1835 a new type with the same properties as src_type to dst_fp. If dst_type is
1836 not CTF_ERR, then we verify that dst_type has the same attributes as
1837 src_type. We recurse for embedded references. Before we start, we note
1838 that we are processing this type, to prevent infinite recursion: we do not
1839 re-process any type that appears in this list. The list is emptied
1840 wholesale at the end of processing everything in this recursive stack. */
1841
1842 if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1843 (void *) (uintptr_t) src_type, (void *) 1) < 0)
1844 return ctf_set_errno (dst_fp, ENOMEM);
1845
c499eb68
NA
1846 switch (kind)
1847 {
1848 case CTF_K_INTEGER:
1849 /* If we found a match we will have either returned it or declared a
1850 conflict. */
1851 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1852 break;
1853
1854 case CTF_K_FLOAT:
1855 /* If we found a match we will have either returned it or declared a
1856 conflict. */
1857 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1858 break;
1859
1860 case CTF_K_SLICE:
1861 /* We have checked for conflicting encodings: now try to add the
1862 contained type. */
1863 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
1864 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1865 proc_tracking_fp);
c499eb68
NA
1866
1867 if (src_type == CTF_ERR)
1868 return CTF_ERR; /* errno is set for us. */
1869
1870 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1871 break;
1872
1873 case CTF_K_POINTER:
1874 case CTF_K_VOLATILE:
1875 case CTF_K_CONST:
1876 case CTF_K_RESTRICT:
1877 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
1878 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1879 proc_tracking_fp);
c499eb68
NA
1880
1881 if (src_type == CTF_ERR)
1882 return CTF_ERR; /* errno is set for us. */
1883
1884 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1885 break;
1886
1887 case CTF_K_ARRAY:
a0486bac 1888 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
c499eb68
NA
1889 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1890
1891 src_ar.ctr_contents =
99dc3ebd
NA
1892 ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1893 proc_tracking_fp);
1894 src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1895 src_ar.ctr_index,
1896 proc_tracking_fp);
c499eb68
NA
1897 src_ar.ctr_nelems = src_ar.ctr_nelems;
1898
1899 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1900 return CTF_ERR; /* errno is set for us. */
1901
1902 if (dst_type != CTF_ERR)
1903 {
1904 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1905 return CTF_ERR; /* errno is set for us. */
1906
1907 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1908 {
1909 ctf_dprintf ("Conflict for type %s against ID %lx: "
1910 "array info differs, old %lx/%lx/%x; "
1911 "new: %lx/%lx/%x\n", name, dst_type,
1912 src_ar.ctr_contents, src_ar.ctr_index,
1913 src_ar.ctr_nelems, dst_ar.ctr_contents,
1914 dst_ar.ctr_index, dst_ar.ctr_nelems);
1915 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1916 }
1917 }
1918 else
1919 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1920 break;
1921
1922 case CTF_K_FUNCTION:
99dc3ebd
NA
1923 ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1924 src_tp->ctt_type,
1925 proc_tracking_fp);
c499eb68
NA
1926 ctc.ctc_argc = 0;
1927 ctc.ctc_flags = 0;
1928
1929 if (ctc.ctc_return == CTF_ERR)
1930 return CTF_ERR; /* errno is set for us. */
1931
1932 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1933 break;
1934
1935 case CTF_K_STRUCT:
1936 case CTF_K_UNION:
1937 {
1938 ctf_dmdef_t *dmd;
1939 int errs = 0;
a0486bac
JM
1940 size_t size;
1941 ssize_t ssize;
99dc3ebd 1942 ctf_dtdef_t *dtd;
c499eb68
NA
1943
1944 /* Technically to match a struct or union we need to check both
1945 ways (src members vs. dst, dst members vs. src) but we make
1946 this more optimal by only checking src vs. dst and comparing
1947 the total size of the structure (which we must do anyway)
1948 which covers the possibility of dst members not in src.
1949 This optimization can be defeated for unions, but is so
1950 pathological as to render it irrelevant for our purposes. */
1951
99dc3ebd
NA
1952 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1953 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
1954 {
1955 if (ctf_type_size (src_fp, src_type) !=
1956 ctf_type_size (dst_fp, dst_type))
1957 {
1958 ctf_dprintf ("Conflict for type %s against ID %lx: "
62d8e3b7
NA
1959 "union size differs, old %li, new %li\n",
1960 name, dst_type,
1961 (long) ctf_type_size (src_fp, src_type),
1962 (long) ctf_type_size (dst_fp, dst_type));
c499eb68
NA
1963 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1964 }
1965
1966 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1967 {
1968 ctf_dprintf ("Conflict for type %s against ID %lx: "
1969 "members differ, see above\n", name, dst_type);
1970 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1971 }
1972
1973 break;
1974 }
1975
1976 /* Unlike the other cases, copying structs and unions is done
1977 manually so as to avoid repeated lookups in ctf_add_member
1978 and to ensure the exact same member offsets as in src_type. */
1979
676c3ecb 1980 dst_type = ctf_add_generic (dst_fp, flag, name, kind, &dtd);
c499eb68
NA
1981 if (dst_type == CTF_ERR)
1982 return CTF_ERR; /* errno is set for us. */
1983
1984 dst.ctb_type = dst_type;
1985 dst.ctb_dtd = dtd;
1986
99dc3ebd
NA
1987 /* Pre-emptively add this struct to the type mapping so that
1988 structures that refer to themselves work. */
1989 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1990
c499eb68
NA
1991 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1992 errs++; /* Increment errs and fail at bottom of case. */
1993
a0486bac
JM
1994 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1995 return CTF_ERR; /* errno is set for us. */
1996
1997 size = (size_t) ssize;
1998 if (size > CTF_MAX_SIZE)
c499eb68
NA
1999 {
2000 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2001 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
2002 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
2003 }
2004 else
2005 dtd->dtd_data.ctt_size = (uint32_t) size;
2006
2007 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
2008
2009 /* Make a final pass through the members changing each dmd_type (a
2010 src_fp type) to an equivalent type in dst_fp. We pass through all
791915db
NA
2011 members, leaving any that fail set to CTF_ERR, unless they fail
2012 because they are marking a member of type not representable in this
2013 version of CTF, in which case we just want to silently omit them:
2014 no consumer can do anything with them anyway. */
c499eb68
NA
2015 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
2016 dmd != NULL; dmd = ctf_list_next (dmd))
2017 {
99dc3ebd
NA
2018 ctf_file_t *dst = dst_fp;
2019 ctf_id_t memb_type;
2020
2021 memb_type = ctf_type_mapping (src_fp, dmd->dmd_type, &dst);
2022 if (memb_type == 0)
791915db 2023 {
99dc3ebd
NA
2024 if ((dmd->dmd_type =
2025 ctf_add_type_internal (dst_fp, src_fp, dmd->dmd_type,
2026 proc_tracking_fp)) == CTF_ERR)
2027 {
2028 if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
2029 errs++;
2030 }
791915db 2031 }
99dc3ebd
NA
2032 else
2033 dmd->dmd_type = memb_type;
c499eb68
NA
2034 }
2035
2036 if (errs)
2037 return CTF_ERR; /* errno is set for us. */
2038 break;
2039 }
2040
2041 case CTF_K_ENUM:
99dc3ebd
NA
2042 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
2043 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
2044 {
2045 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
2046 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
2047 {
2048 ctf_dprintf ("Conflict for enum %s against ID %lx: "
2049 "members differ, see above\n", name, dst_type);
2050 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2051 }
2052 }
2053 else
2054 {
2055 dst_type = ctf_add_enum (dst_fp, flag, name);
2056 if ((dst.ctb_type = dst_type) == CTF_ERR
2057 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
2058 return CTF_ERR; /* errno is set for us */
2059 }
2060 break;
2061
2062 case CTF_K_FORWARD:
2063 if (dst_type == CTF_ERR)
5de9eada 2064 dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
c499eb68
NA
2065 break;
2066
2067 case CTF_K_TYPEDEF:
2068 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
2069 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2070 proc_tracking_fp);
c499eb68
NA
2071
2072 if (src_type == CTF_ERR)
2073 return CTF_ERR; /* errno is set for us. */
2074
2075 /* If dst_type is not CTF_ERR at this point, we should check if
2076 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
2077 ECTF_CONFLICT. However, this causes problems with bitness typedefs
2078 that vary based on things like if 32-bit then pid_t is int otherwise
2079 long. We therefore omit this check and assume that if the identically
2080 named typedef already exists in dst_fp, it is correct or
2081 equivalent. */
2082
2083 if (dst_type == CTF_ERR)
c499eb68 2084 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
99dc3ebd 2085
c499eb68
NA
2086 break;
2087
2088 default:
2089 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
2090 }
2091
886453cb
NA
2092 if (dst_type != CTF_ERR)
2093 ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
c499eb68
NA
2094 return dst_type;
2095}
2096
99dc3ebd
NA
2097ctf_id_t
2098ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
2099{
2100 ctf_id_t id;
2101
2102 if (!src_fp->ctf_add_processing)
2103 src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
2104 ctf_hash_eq_integer,
2105 NULL, NULL);
2106
2107 /* We store the hash on the source, because it contains only source type IDs:
2108 but callers will invariably expect errors to appear on the dest. */
2109 if (!src_fp->ctf_add_processing)
2110 return (ctf_set_errno (dst_fp, ENOMEM));
2111
2112 id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
2113 ctf_dynhash_empty (src_fp->ctf_add_processing);
2114
2115 return id;
2116}
2117
fd55eae8 2118/* Write the compressed CTF data stream to the specified gzFile descriptor. */
47d546f4
NA
2119int
2120ctf_gzwrite (ctf_file_t *fp, gzFile fd)
2121{
fd55eae8
NA
2122 const unsigned char *buf;
2123 ssize_t resid;
47d546f4
NA
2124 ssize_t len;
2125
fd55eae8
NA
2126 resid = sizeof (ctf_header_t);
2127 buf = (unsigned char *) fp->ctf_header;
2128 while (resid != 0)
2129 {
2130 if ((len = gzwrite (fd, buf, resid)) <= 0)
2131 return (ctf_set_errno (fp, errno));
2132 resid -= len;
2133 buf += len;
2134 }
2135
2136 resid = fp->ctf_size;
2137 buf = fp->ctf_buf;
47d546f4
NA
2138 while (resid != 0)
2139 {
2140 if ((len = gzwrite (fd, buf, resid)) <= 0)
2141 return (ctf_set_errno (fp, errno));
2142 resid -= len;
2143 buf += len;
2144 }
2145
2146 return 0;
2147}
2148
2149/* Compress the specified CTF data stream and write it to the specified file
2150 descriptor. */
2151int
2152ctf_compress_write (ctf_file_t *fp, int fd)
2153{
2154 unsigned char *buf;
2155 unsigned char *bp;
2156 ctf_header_t h;
2157 ctf_header_t *hp = &h;
2158 ssize_t header_len = sizeof (ctf_header_t);
2159 ssize_t compress_len;
47d546f4
NA
2160 ssize_t len;
2161 int rc;
2162 int err = 0;
2163
676c3ecb
NA
2164 if (ctf_serialize (fp) < 0)
2165 return -1; /* errno is set for us. */
2166
fd55eae8 2167 memcpy (hp, fp->ctf_header, header_len);
47d546f4 2168 hp->cth_flags |= CTF_F_COMPRESS;
676c3ecb 2169 compress_len = compressBound (fp->ctf_size);
47d546f4 2170
de07e349 2171 if ((buf = malloc (compress_len)) == NULL)
47d546f4
NA
2172 return (ctf_set_errno (fp, ECTF_ZALLOC));
2173
65365aa8 2174 if ((rc = compress (buf, (uLongf *) &compress_len,
fd55eae8 2175 fp->ctf_buf, fp->ctf_size)) != Z_OK)
47d546f4
NA
2176 {
2177 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2178 err = ctf_set_errno (fp, ECTF_COMPRESS);
2179 goto ret;
2180 }
2181
2182 while (header_len > 0)
2183 {
2184 if ((len = write (fd, hp, header_len)) < 0)
2185 {
2186 err = ctf_set_errno (fp, errno);
2187 goto ret;
2188 }
2189 header_len -= len;
2190 hp += len;
2191 }
2192
2193 bp = buf;
2194 while (compress_len > 0)
2195 {
2196 if ((len = write (fd, bp, compress_len)) < 0)
2197 {
2198 err = ctf_set_errno (fp, errno);
2199 goto ret;
2200 }
2201 compress_len -= len;
2202 bp += len;
2203 }
2204
2205ret:
de07e349 2206 free (buf);
47d546f4
NA
2207 return err;
2208}
2209
5537f9b9
NA
2210/* Optionally compress the specified CTF data stream and return it as a new
2211 dynamically-allocated string. */
2212unsigned char *
2213ctf_write_mem (ctf_file_t *fp, size_t *size, size_t threshold)
2214{
2215 unsigned char *buf;
2216 unsigned char *bp;
2217 ctf_header_t *hp;
2218 ssize_t header_len = sizeof (ctf_header_t);
2219 ssize_t compress_len;
5537f9b9
NA
2220 int rc;
2221
676c3ecb
NA
2222 if (ctf_serialize (fp) < 0)
2223 return NULL; /* errno is set for us. */
2224
2225 compress_len = compressBound (fp->ctf_size);
5537f9b9 2226 if (fp->ctf_size < threshold)
676c3ecb
NA
2227 compress_len = fp->ctf_size;
2228 if ((buf = malloc (compress_len
5537f9b9
NA
2229 + sizeof (struct ctf_header))) == NULL)
2230 {
2231 ctf_set_errno (fp, ENOMEM);
2232 return NULL;
2233 }
2234
2235 hp = (ctf_header_t *) buf;
2236 memcpy (hp, fp->ctf_header, header_len);
2237 bp = buf + sizeof (struct ctf_header);
2238 *size = sizeof (struct ctf_header);
2239
5537f9b9
NA
2240 if (fp->ctf_size < threshold)
2241 {
2242 hp->cth_flags &= ~CTF_F_COMPRESS;
2243 memcpy (bp, fp->ctf_buf, fp->ctf_size);
2244 *size += fp->ctf_size;
2245 }
2246 else
2247 {
2248 hp->cth_flags |= CTF_F_COMPRESS;
2249 if ((rc = compress (bp, (uLongf *) &compress_len,
2250 fp->ctf_buf, fp->ctf_size)) != Z_OK)
2251 {
2252 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2253 ctf_set_errno (fp, ECTF_COMPRESS);
de07e349 2254 free (buf);
5537f9b9
NA
2255 return NULL;
2256 }
2257 *size += compress_len;
2258 }
2259 return buf;
2260}
2261
fd55eae8 2262/* Write the uncompressed CTF data stream to the specified file descriptor. */
47d546f4
NA
2263int
2264ctf_write (ctf_file_t *fp, int fd)
2265{
fd55eae8
NA
2266 const unsigned char *buf;
2267 ssize_t resid;
47d546f4
NA
2268 ssize_t len;
2269
676c3ecb
NA
2270 if (ctf_serialize (fp) < 0)
2271 return -1; /* errno is set for us. */
2272
fd55eae8
NA
2273 resid = sizeof (ctf_header_t);
2274 buf = (unsigned char *) fp->ctf_header;
2275 while (resid != 0)
2276 {
2277 if ((len = write (fd, buf, resid)) <= 0)
2278 return (ctf_set_errno (fp, errno));
2279 resid -= len;
2280 buf += len;
2281 }
2282
2283 resid = fp->ctf_size;
2284 buf = fp->ctf_buf;
47d546f4
NA
2285 while (resid != 0)
2286 {
fd55eae8 2287 if ((len = write (fd, buf, resid)) <= 0)
47d546f4
NA
2288 return (ctf_set_errno (fp, errno));
2289 resid -= len;
2290 buf += len;
2291 }
2292
2293 return 0;
2294}