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