libctf: create: non-root-visible types should not appear in name tables
[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
fe4c2d55 600ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd, int flag, 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
fe4c2d55 606 if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
676c3ecb 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 648 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
649 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
650 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
47d546f4 651 {
676c3ecb
NA
652 ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
653 name);
654 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
655 }
656
657 ctf_list_delete (&fp->ctf_dtdefs, dtd);
de07e349 658 free (dtd);
47d546f4
NA
659}
660
661ctf_dtdef_t *
662ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
663{
664 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
665}
666
47d546f4
NA
667ctf_dtdef_t *
668ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
669{
670 ctf_id_t idx;
671
676c3ecb
NA
672 if (!(fp->ctf_flags & LCTF_RDWR))
673 return NULL;
674
47d546f4
NA
675 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
676 fp = fp->ctf_parent;
677
678 idx = LCTF_TYPE_TO_INDEX(fp, id);
679
676c3ecb 680 if ((unsigned long) idx <= fp->ctf_typemax)
47d546f4
NA
681 return ctf_dtd_lookup (fp, id);
682 return NULL;
683}
684
24865428 685int
47d546f4
NA
686ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
687{
24865428
NA
688 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
689 return -1;
47d546f4 690 ctf_list_append (&fp->ctf_dvdefs, dvd);
24865428 691 return 0;
47d546f4
NA
692}
693
694void
695ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
696{
697 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
de07e349 698 free (dvd->dvd_name);
47d546f4
NA
699
700 ctf_list_delete (&fp->ctf_dvdefs, dvd);
de07e349 701 free (dvd);
47d546f4
NA
702}
703
704ctf_dvdef_t *
705ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
706{
707 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
708}
709
710/* Discard all of the dynamic type definitions and variable definitions that
711 have been added to the container since the last call to ctf_update(). We
712 locate such types by scanning the dtd list and deleting elements that have
713 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
714 by scanning the variable list and deleting elements that have update IDs
715 equal to the current value of the last-update snapshot count (indicating that
716 they were added after the most recent call to ctf_update()). */
717int
718ctf_discard (ctf_file_t *fp)
719{
720 ctf_snapshot_id_t last_update =
721 { fp->ctf_dtoldid,
722 fp->ctf_snapshot_lu + 1 };
723
724 /* Update required? */
725 if (!(fp->ctf_flags & LCTF_DIRTY))
726 return 0;
727
728 return (ctf_rollback (fp, last_update));
729}
730
731ctf_snapshot_id_t
732ctf_snapshot (ctf_file_t *fp)
733{
734 ctf_snapshot_id_t snapid;
676c3ecb 735 snapid.dtd_id = fp->ctf_typemax;
47d546f4
NA
736 snapid.snapshot_id = fp->ctf_snapshots++;
737 return snapid;
738}
739
740/* Like ctf_discard(), only discards everything after a particular ID. */
741int
742ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
743{
744 ctf_dtdef_t *dtd, *ntd;
745 ctf_dvdef_t *dvd, *nvd;
746
747 if (!(fp->ctf_flags & LCTF_RDWR))
748 return (ctf_set_errno (fp, ECTF_RDONLY));
749
47d546f4
NA
750 if (fp->ctf_snapshot_lu >= id.snapshot_id)
751 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
752
753 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
754 {
676c3ecb
NA
755 int kind;
756 const char *name;
757
47d546f4
NA
758 ntd = ctf_list_next (dtd);
759
760 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
761 continue;
762
676c3ecb
NA
763 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
764
765 if (dtd->dtd_data.ctt_name
fe4c2d55
NA
766 && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
767 && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
676c3ecb
NA
768 {
769 ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
770 name);
771 ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
772 }
773
774 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
47d546f4
NA
775 ctf_dtd_delete (fp, dtd);
776 }
777
778 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
779 {
780 nvd = ctf_list_next (dvd);
781
782 if (dvd->dvd_snapshots <= id.snapshot_id)
783 continue;
784
785 ctf_dvd_delete (fp, dvd);
786 }
787
676c3ecb 788 fp->ctf_typemax = id.dtd_id;
47d546f4
NA
789 fp->ctf_snapshots = id.snapshot_id;
790
791 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
792 fp->ctf_flags &= ~LCTF_DIRTY;
793
794 return 0;
795}
796
797static ctf_id_t
676c3ecb 798ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name, int kind,
47d546f4
NA
799 ctf_dtdef_t **rp)
800{
801 ctf_dtdef_t *dtd;
802 ctf_id_t type;
47d546f4
NA
803
804 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
805 return (ctf_set_errno (fp, EINVAL));
806
807 if (!(fp->ctf_flags & LCTF_RDWR))
808 return (ctf_set_errno (fp, ECTF_RDONLY));
809
676c3ecb 810 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
47d546f4
NA
811 return (ctf_set_errno (fp, ECTF_FULL));
812
676c3ecb 813 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
47d546f4
NA
814 return (ctf_set_errno (fp, ECTF_FULL));
815
676c3ecb
NA
816 /* Make sure ptrtab always grows to be big enough for all types. */
817 if (ctf_grow_ptrtab (fp) < 0)
818 return CTF_ERR; /* errno is set for us. */
819
de07e349 820 if ((dtd = malloc (sizeof (ctf_dtdef_t))) == NULL)
47d546f4
NA
821 return (ctf_set_errno (fp, EAGAIN));
822
676c3ecb 823 type = ++fp->ctf_typemax;
47d546f4
NA
824 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
825
826 memset (dtd, 0, sizeof (ctf_dtdef_t));
676c3ecb 827 dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
47d546f4
NA
828 dtd->dtd_type = type;
829
676c3ecb
NA
830 if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
831 {
de07e349 832 free (dtd);
676c3ecb
NA
833 return (ctf_set_errno (fp, EAGAIN));
834 }
835
fe4c2d55 836 if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
24865428 837 {
de07e349 838 free (dtd);
24865428
NA
839 return CTF_ERR; /* errno is set for us. */
840 }
47d546f4
NA
841 fp->ctf_flags |= LCTF_DIRTY;
842
843 *rp = dtd;
844 return type;
845}
846
847/* When encoding integer sizes, we want to convert a byte count in the range
848 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
849 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
850static size_t
851clp2 (size_t x)
852{
853 x--;
854
855 x |= (x >> 1);
856 x |= (x >> 2);
857 x |= (x >> 4);
858 x |= (x >> 8);
859 x |= (x >> 16);
860
861 return (x + 1);
862}
863
864static ctf_id_t
865ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
866 const char *name, const ctf_encoding_t *ep, uint32_t kind)
867{
868 ctf_dtdef_t *dtd;
869 ctf_id_t type;
870
871 if (ep == NULL)
872 return (ctf_set_errno (fp, EINVAL));
873
676c3ecb 874 if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
47d546f4
NA
875 return CTF_ERR; /* errno is set for us. */
876
877 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
76fad999
TT
878 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
879 / CHAR_BIT);
47d546f4
NA
880 dtd->dtd_u.dtu_enc = *ep;
881
882 return type;
883}
884
885static ctf_id_t
886ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
887{
888 ctf_dtdef_t *dtd;
889 ctf_id_t type;
890 ctf_file_t *tmp = fp;
676c3ecb 891 int child = fp->ctf_flags & LCTF_CHILD;
47d546f4 892
a0486bac 893 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
894 return (ctf_set_errno (fp, EINVAL));
895
896 if (ctf_lookup_by_id (&tmp, ref) == NULL)
897 return CTF_ERR; /* errno is set for us. */
898
676c3ecb 899 if ((type = ctf_add_generic (fp, flag, NULL, kind, &dtd)) == CTF_ERR)
47d546f4
NA
900 return CTF_ERR; /* errno is set for us. */
901
902 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
903 dtd->dtd_data.ctt_type = (uint32_t) ref;
904
676c3ecb
NA
905 if (kind != CTF_K_POINTER)
906 return type;
907
908 /* If we are adding a pointer, update the ptrtab, both the directly pointed-to
909 type and (if an anonymous typedef node is being pointed at) the type that
910 points at too. Note that ctf_typemax is at this point one higher than we
911 want to check against, because it's just been incremented for the addition
912 of this type. */
913
914 uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
915 uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
916
917 if (LCTF_TYPE_ISCHILD (fp, ref) == child
918 && ref_idx < fp->ctf_typemax)
919 {
920 fp->ctf_ptrtab[ref_idx] = type_idx;
921
922 ctf_id_t refref_idx = LCTF_TYPE_TO_INDEX (fp, dtd->dtd_data.ctt_type);
923
924 if (tmp == fp
925 && (LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) == CTF_K_TYPEDEF)
926 && strcmp (ctf_strptr (fp, dtd->dtd_data.ctt_name), "") == 0
927 && refref_idx < fp->ctf_typemax)
928 fp->ctf_ptrtab[refref_idx] = type_idx;
929 }
930
47d546f4
NA
931 return type;
932}
933
934ctf_id_t
935ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
936 const ctf_encoding_t *ep)
937{
938 ctf_dtdef_t *dtd;
939 ctf_id_t type;
940 int kind;
941 const ctf_type_t *tp;
942 ctf_file_t *tmp = fp;
943
944 if (ep == NULL)
945 return (ctf_set_errno (fp, EINVAL));
946
947 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
948 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
949
a0486bac 950 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
951 return (ctf_set_errno (fp, EINVAL));
952
953 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
954 return CTF_ERR; /* errno is set for us. */
955
956 kind = ctf_type_kind_unsliced (tmp, ref);
957 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
958 (kind != CTF_K_ENUM))
959 return (ctf_set_errno (fp, ECTF_NOTINTFP));
960
676c3ecb 961 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE, &dtd)) == CTF_ERR)
47d546f4
NA
962 return CTF_ERR; /* errno is set for us. */
963
964 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
76fad999
TT
965 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
966 / CHAR_BIT);
47d546f4
NA
967 dtd->dtd_u.dtu_slice.cts_type = ref;
968 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
969 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
970
971 return type;
972}
973
974ctf_id_t
975ctf_add_integer (ctf_file_t *fp, uint32_t flag,
976 const char *name, const ctf_encoding_t *ep)
977{
978 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
979}
980
981ctf_id_t
982ctf_add_float (ctf_file_t *fp, uint32_t flag,
983 const char *name, const ctf_encoding_t *ep)
984{
985 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
986}
987
988ctf_id_t
989ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
990{
991 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
992}
993
994ctf_id_t
995ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
996{
997 ctf_dtdef_t *dtd;
998 ctf_id_t type;
999 ctf_file_t *tmp = fp;
1000
1001 if (arp == NULL)
1002 return (ctf_set_errno (fp, EINVAL));
1003
1004 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
1005 return CTF_ERR; /* errno is set for us. */
1006
1007 tmp = fp;
1008 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
1009 return CTF_ERR; /* errno is set for us. */
1010
676c3ecb 1011 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY, &dtd)) == CTF_ERR)
47d546f4
NA
1012 return CTF_ERR; /* errno is set for us. */
1013
1014 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
1015 dtd->dtd_data.ctt_size = 0;
1016 dtd->dtd_u.dtu_arr = *arp;
1017
1018 return type;
1019}
1020
1021int
1022ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
1023{
1024 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1025
1026 if (!(fp->ctf_flags & LCTF_RDWR))
1027 return (ctf_set_errno (fp, ECTF_RDONLY));
1028
1029 if (dtd == NULL
1030 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
1031 return (ctf_set_errno (fp, ECTF_BADID));
1032
1033 fp->ctf_flags |= LCTF_DIRTY;
1034 dtd->dtd_u.dtu_arr = *arp;
1035
1036 return 0;
1037}
1038
1039ctf_id_t
1040ctf_add_function (ctf_file_t *fp, uint32_t flag,
1041 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
1042{
1043 ctf_dtdef_t *dtd;
1044 ctf_id_t type;
1045 uint32_t vlen;
1046 ctf_id_t *vdat = NULL;
1047 ctf_file_t *tmp = fp;
1048 size_t i;
1049
1050 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
1051 || (ctc->ctc_argc != 0 && argv == NULL))
1052 return (ctf_set_errno (fp, EINVAL));
1053
1054 vlen = ctc->ctc_argc;
1055 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1056 vlen++; /* Add trailing zero to indicate varargs (see below). */
1057
1058 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
1059 return CTF_ERR; /* errno is set for us. */
1060
1061 for (i = 0; i < ctc->ctc_argc; i++)
1062 {
1063 tmp = fp;
1064 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
1065 return CTF_ERR; /* errno is set for us. */
1066 }
1067
1068 if (vlen > CTF_MAX_VLEN)
1069 return (ctf_set_errno (fp, EOVERFLOW));
1070
de07e349 1071 if (vlen != 0 && (vdat = malloc (sizeof (ctf_id_t) * vlen)) == NULL)
47d546f4
NA
1072 return (ctf_set_errno (fp, EAGAIN));
1073
676c3ecb
NA
1074 if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
1075 &dtd)) == CTF_ERR)
47d546f4 1076 {
de07e349 1077 free (vdat);
47d546f4
NA
1078 return CTF_ERR; /* errno is set for us. */
1079 }
1080
1081 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
1082 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
1083
1084 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
1085 if (ctc->ctc_flags & CTF_FUNC_VARARG)
1086 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
1087 dtd->dtd_u.dtu_argv = vdat;
1088
1089 return type;
1090}
1091
1092ctf_id_t
1093ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1094 size_t size)
1095{
47d546f4
NA
1096 ctf_dtdef_t *dtd;
1097 ctf_id_t type = 0;
1098
fe4c2d55 1099 /* Promote root-visible forwards to structs. */
47d546f4 1100 if (name != NULL)
676c3ecb 1101 type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
47d546f4
NA
1102
1103 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1104 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1105 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
1106 &dtd)) == CTF_ERR)
47d546f4
NA
1107 return CTF_ERR; /* errno is set for us. */
1108
1109 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1110
1111 if (size > CTF_MAX_SIZE)
1112 {
1113 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1114 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1115 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1116 }
1117 else
1118 dtd->dtd_data.ctt_size = (uint32_t) size;
1119
1120 return type;
1121}
1122
1123ctf_id_t
1124ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1125{
1126 return (ctf_add_struct_sized (fp, flag, name, 0));
1127}
1128
1129ctf_id_t
1130ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1131 size_t size)
1132{
47d546f4
NA
1133 ctf_dtdef_t *dtd;
1134 ctf_id_t type = 0;
1135
fe4c2d55 1136 /* Promote root-visible forwards to unions. */
47d546f4 1137 if (name != NULL)
676c3ecb 1138 type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
47d546f4
NA
1139
1140 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1141 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1142 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
1143 &dtd)) == CTF_ERR)
47d546f4
NA
1144 return CTF_ERR; /* errno is set for us */
1145
1146 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1147
1148 if (size > CTF_MAX_SIZE)
1149 {
1150 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1151 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1152 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1153 }
1154 else
1155 dtd->dtd_data.ctt_size = (uint32_t) size;
1156
1157 return type;
1158}
1159
1160ctf_id_t
1161ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1162{
1163 return (ctf_add_union_sized (fp, flag, name, 0));
1164}
1165
1166ctf_id_t
1167ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1168{
47d546f4
NA
1169 ctf_dtdef_t *dtd;
1170 ctf_id_t type = 0;
1171
fe4c2d55 1172 /* Promote root-visible forwards to enums. */
47d546f4 1173 if (name != NULL)
676c3ecb 1174 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1175
1176 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1177 dtd = ctf_dtd_lookup (fp, type);
676c3ecb
NA
1178 else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
1179 &dtd)) == CTF_ERR)
47d546f4
NA
1180 return CTF_ERR; /* errno is set for us. */
1181
1182 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1183 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1184
1185 return type;
1186}
1187
1188ctf_id_t
1189ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1190 const ctf_encoding_t *ep)
1191{
47d546f4
NA
1192 ctf_id_t type = 0;
1193
1194 /* First, create the enum if need be, using most of the same machinery as
1195 ctf_add_enum(), to ensure that we do not allow things past that are not
1196 enums or forwards to them. (This includes other slices: you cannot slice a
1197 slice, which would be a useless thing to do anyway.) */
1198
1199 if (name != NULL)
676c3ecb 1200 type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
47d546f4
NA
1201
1202 if (type != 0)
1203 {
1204 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1205 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1206 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1207 }
1208 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1209 return CTF_ERR; /* errno is set for us. */
1210
1211 /* Now attach a suitable slice to it. */
1212
1213 return ctf_add_slice (fp, flag, type, ep);
1214}
1215
1216ctf_id_t
1217ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1218 uint32_t kind)
1219{
47d546f4
NA
1220 ctf_dtdef_t *dtd;
1221 ctf_id_t type = 0;
1222
676c3ecb
NA
1223 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1224 return (ctf_set_errno (fp, ECTF_NOTSUE));
47d546f4
NA
1225
1226 /* If the type is already defined or exists as a forward tag, just
1227 return the ctf_id_t of the existing definition. */
1228
1229 if (name != NULL)
676c3ecb 1230 type = ctf_lookup_by_rawname (fp, kind, name);
47d546f4 1231
676c3ecb 1232 if ((type = ctf_add_generic (fp, flag, name, CTF_K_FORWARD,&dtd)) == CTF_ERR)
47d546f4
NA
1233 return CTF_ERR; /* errno is set for us. */
1234
1235 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1236 dtd->dtd_data.ctt_type = kind;
1237
1238 return type;
1239}
1240
1241ctf_id_t
1242ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1243 ctf_id_t ref)
1244{
1245 ctf_dtdef_t *dtd;
1246 ctf_id_t type;
1247 ctf_file_t *tmp = fp;
1248
a0486bac 1249 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1250 return (ctf_set_errno (fp, EINVAL));
1251
1252 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1253 return CTF_ERR; /* errno is set for us. */
1254
676c3ecb
NA
1255 if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF,
1256 &dtd)) == CTF_ERR)
47d546f4
NA
1257 return CTF_ERR; /* errno is set for us. */
1258
1259 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1260 dtd->dtd_data.ctt_type = (uint32_t) ref;
1261
1262 return type;
1263}
1264
1265ctf_id_t
1266ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1267{
1268 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1269}
1270
1271ctf_id_t
1272ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1273{
1274 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1275}
1276
1277ctf_id_t
1278ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1279{
1280 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1281}
1282
1283int
1284ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1285 int value)
1286{
1287 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1288 ctf_dmdef_t *dmd;
1289
1290 uint32_t kind, vlen, root;
1291 char *s;
1292
1293 if (name == NULL)
1294 return (ctf_set_errno (fp, EINVAL));
1295
1296 if (!(fp->ctf_flags & LCTF_RDWR))
1297 return (ctf_set_errno (fp, ECTF_RDONLY));
1298
1299 if (dtd == NULL)
1300 return (ctf_set_errno (fp, ECTF_BADID));
1301
1302 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1303 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1304 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1305
1306 if (kind != CTF_K_ENUM)
1307 return (ctf_set_errno (fp, ECTF_NOTENUM));
1308
1309 if (vlen == CTF_MAX_VLEN)
1310 return (ctf_set_errno (fp, ECTF_DTFULL));
1311
1312 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1313 dmd != NULL; dmd = ctf_list_next (dmd))
1314 {
1315 if (strcmp (dmd->dmd_name, name) == 0)
1316 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1317 }
1318
de07e349 1319 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
1320 return (ctf_set_errno (fp, EAGAIN));
1321
de07e349 1322 if ((s = strdup (name)) == NULL)
47d546f4 1323 {
de07e349 1324 free (dmd);
47d546f4
NA
1325 return (ctf_set_errno (fp, EAGAIN));
1326 }
1327
1328 dmd->dmd_name = s;
1329 dmd->dmd_type = CTF_ERR;
1330 dmd->dmd_offset = 0;
1331 dmd->dmd_value = value;
1332
1333 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1334 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1335
47d546f4
NA
1336 fp->ctf_flags |= LCTF_DIRTY;
1337
1338 return 0;
1339}
1340
1341int
1342ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1343 ctf_id_t type, unsigned long bit_offset)
1344{
1345 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1346 ctf_dmdef_t *dmd;
1347
1348 ssize_t msize, malign, ssize;
1349 uint32_t kind, vlen, root;
1350 char *s = NULL;
1351
1352 if (!(fp->ctf_flags & LCTF_RDWR))
1353 return (ctf_set_errno (fp, ECTF_RDONLY));
1354
1355 if (dtd == NULL)
1356 return (ctf_set_errno (fp, ECTF_BADID));
1357
1358 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1359 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1360 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1361
1362 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1363 return (ctf_set_errno (fp, ECTF_NOTSOU));
1364
1365 if (vlen == CTF_MAX_VLEN)
1366 return (ctf_set_errno (fp, ECTF_DTFULL));
1367
1368 if (name != NULL)
1369 {
1370 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1371 dmd != NULL; dmd = ctf_list_next (dmd))
1372 {
1373 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1374 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1375 }
1376 }
1377
a0486bac
JM
1378 if ((msize = ctf_type_size (fp, type)) < 0 ||
1379 (malign = ctf_type_align (fp, type)) < 0)
1380 return -1; /* errno is set for us. */
47d546f4 1381
de07e349 1382 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
47d546f4
NA
1383 return (ctf_set_errno (fp, EAGAIN));
1384
de07e349 1385 if (name != NULL && (s = strdup (name)) == NULL)
47d546f4 1386 {
de07e349 1387 free (dmd);
47d546f4
NA
1388 return (ctf_set_errno (fp, EAGAIN));
1389 }
1390
1391 dmd->dmd_name = s;
1392 dmd->dmd_type = type;
1393 dmd->dmd_value = -1;
1394
1395 if (kind == CTF_K_STRUCT && vlen != 0)
1396 {
1397 if (bit_offset == (unsigned long) - 1)
1398 {
1399 /* Natural alignment. */
1400
1401 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1402 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1403 size_t off = lmd->dmd_offset;
1404
1405 ctf_encoding_t linfo;
1406 ssize_t lsize;
1407
a0486bac 1408 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
47d546f4 1409 off += linfo.cte_bits;
a0486bac 1410 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
76fad999 1411 off += lsize * CHAR_BIT;
47d546f4
NA
1412
1413 /* Round up the offset of the end of the last member to
1414 the next byte boundary, convert 'off' to bytes, and
1415 then round it up again to the next multiple of the
1416 alignment required by the new member. Finally,
1417 convert back to bits and store the result in
1418 dmd_offset. Technically we could do more efficient
1419 packing if the new member is a bit-field, but we're
1420 the "compiler" and ANSI says we can do as we choose. */
1421
76fad999 1422 off = roundup (off, CHAR_BIT) / CHAR_BIT;
47d546f4 1423 off = roundup (off, MAX (malign, 1));
76fad999 1424 dmd->dmd_offset = off * CHAR_BIT;
47d546f4
NA
1425 ssize = off + msize;
1426 }
1427 else
1428 {
1429 /* Specified offset in bits. */
1430
1431 dmd->dmd_offset = bit_offset;
1432 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
76fad999 1433 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
47d546f4
NA
1434 }
1435 }
1436 else
1437 {
1438 dmd->dmd_offset = 0;
1439 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1440 ssize = MAX (ssize, msize);
1441 }
1442
a0486bac 1443 if ((size_t) ssize > CTF_MAX_SIZE)
47d546f4
NA
1444 {
1445 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1446 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1447 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1448 }
1449 else
1450 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1451
1452 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1453 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1454
47d546f4
NA
1455 fp->ctf_flags |= LCTF_DIRTY;
1456 return 0;
1457}
1458
1459int
1460ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1461 ctf_id_t type, unsigned long bit_offset,
1462 const ctf_encoding_t encoding)
1463{
1464 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1465 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1466 int otype = type;
1467
1468 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1469 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1470
1471 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
a0486bac 1472 return -1; /* errno is set for us. */
47d546f4
NA
1473
1474 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1475}
1476
1477int
1478ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1479 ctf_id_t type)
1480{
1481 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1482}
1483
1484int
1485ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1486{
1487 ctf_dvdef_t *dvd;
1488 ctf_file_t *tmp = fp;
1489
1490 if (!(fp->ctf_flags & LCTF_RDWR))
1491 return (ctf_set_errno (fp, ECTF_RDONLY));
1492
1493 if (ctf_dvd_lookup (fp, name) != NULL)
1494 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1495
1496 if (ctf_lookup_by_id (&tmp, ref) == NULL)
a0486bac 1497 return -1; /* errno is set for us. */
47d546f4 1498
791915db
NA
1499 /* Make sure this type is representable. */
1500 if ((ctf_type_resolve (fp, ref) == CTF_ERR)
1501 && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
1502 return -1;
1503
de07e349 1504 if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
47d546f4
NA
1505 return (ctf_set_errno (fp, EAGAIN));
1506
de07e349 1507 if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
47d546f4 1508 {
de07e349 1509 free (dvd);
47d546f4
NA
1510 return (ctf_set_errno (fp, EAGAIN));
1511 }
1512 dvd->dvd_type = ref;
1513 dvd->dvd_snapshots = fp->ctf_snapshots;
1514
24865428
NA
1515 if (ctf_dvd_insert (fp, dvd) < 0)
1516 {
de07e349
NA
1517 free (dvd->dvd_name);
1518 free (dvd);
24865428
NA
1519 return -1; /* errno is set for us. */
1520 }
47d546f4 1521
47d546f4
NA
1522 fp->ctf_flags |= LCTF_DIRTY;
1523 return 0;
1524}
1525
c499eb68
NA
1526static int
1527enumcmp (const char *name, int value, void *arg)
1528{
1529 ctf_bundle_t *ctb = arg;
1530 int bvalue;
1531
a0486bac 1532 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
c499eb68 1533 {
99dc3ebd
NA
1534 ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1535 ctf_errmsg (ctf_errno (ctb->ctb_file)));
c499eb68
NA
1536 return 1;
1537 }
1538 if (value != bvalue)
1539 {
1540 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1541 value, bvalue);
1542 return 1;
1543 }
1544 return 0;
1545}
1546
1547static int
1548enumadd (const char *name, int value, void *arg)
1549{
1550 ctf_bundle_t *ctb = arg;
1551
1552 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
a0486bac 1553 name, value) < 0);
c499eb68
NA
1554}
1555
1556static int
1557membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1558 void *arg)
1559{
1560 ctf_bundle_t *ctb = arg;
1561 ctf_membinfo_t ctm;
1562
a0486bac 1563 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
c499eb68 1564 {
99dc3ebd
NA
1565 ctf_dprintf ("Conflict due to member %s iteration error: %s.\n", name,
1566 ctf_errmsg (ctf_errno (ctb->ctb_file)));
c499eb68
NA
1567 return 1;
1568 }
1569 if (ctm.ctm_offset != offset)
1570 {
1571 ctf_dprintf ("Conflict due to member %s offset change: "
1572 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1573 return 1;
1574 }
1575 return 0;
1576}
1577
1578static int
1579membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1580{
1581 ctf_bundle_t *ctb = arg;
1582 ctf_dmdef_t *dmd;
1583 char *s = NULL;
1584
de07e349 1585 if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL)
c499eb68
NA
1586 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1587
de07e349 1588 if (name != NULL && (s = strdup (name)) == NULL)
c499eb68 1589 {
de07e349 1590 free (dmd);
c499eb68
NA
1591 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1592 }
1593
1594 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1595 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1596 dmd->dmd_name = s;
1597 dmd->dmd_type = type;
1598 dmd->dmd_offset = offset;
1599 dmd->dmd_value = -1;
1600
1601 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1602
c499eb68
NA
1603 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1604 return 0;
1605}
1606
1607/* The ctf_add_type routine is used to copy a type from a source CTF container
1608 to a dynamic destination container. This routine operates recursively by
1609 following the source type's links and embedded member types. If the
1610 destination container already contains a named type which has the same
1611 attributes, then we succeed and return this type but no changes occur. */
99dc3ebd
NA
1612static ctf_id_t
1613ctf_add_type_internal (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type,
1614 ctf_file_t *proc_tracking_fp)
c499eb68
NA
1615{
1616 ctf_id_t dst_type = CTF_ERR;
1617 uint32_t dst_kind = CTF_K_UNKNOWN;
99dc3ebd 1618 ctf_file_t *tmp_fp = dst_fp;
c499eb68
NA
1619 ctf_id_t tmp;
1620
1621 const char *name;
5de9eada 1622 uint32_t kind, forward_kind, flag, vlen;
c499eb68
NA
1623
1624 const ctf_type_t *src_tp, *dst_tp;
1625 ctf_bundle_t src, dst;
1626 ctf_encoding_t src_en, dst_en;
1627 ctf_arinfo_t src_ar, dst_ar;
1628
c499eb68 1629 ctf_funcinfo_t ctc;
c499eb68 1630
886453cb 1631 ctf_id_t orig_src_type = src_type;
c499eb68
NA
1632
1633 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1634 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1635
1636 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1637 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1638
791915db
NA
1639 if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
1640 && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
1641 return (ctf_set_errno (dst_fp, ECTF_NONREPRESENTABLE));
1642
c499eb68
NA
1643 name = ctf_strptr (src_fp, src_tp->ctt_name);
1644 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1645 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1646 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1647
99dc3ebd
NA
1648 /* If this is a type we are currently in the middle of adding, hand it
1649 straight back. (This lets us handle self-referential structures without
1650 considering forwards and empty structures the same as their completed
1651 forms.) */
1652
1653 tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1654
1655 if (tmp != 0)
1656 {
1657 if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1658 (void *) (uintptr_t) src_type))
1659 return tmp;
1660
1661 /* If this type has already been added from this container, and is the same
1662 kind and (if a struct or union) has the same number of members, hand it
1663 straight back. */
1664
1665 if ((ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
1666 && (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1667 || kind == CTF_K_ENUM))
1668 {
1669 if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1670 if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1671 return tmp;
1672 }
1673 }
1674
5de9eada
NA
1675 forward_kind = kind;
1676 if (kind == CTF_K_FORWARD)
1677 forward_kind = src_tp->ctt_type;
1678
c499eb68
NA
1679 /* If the source type has a name and is a root type (visible at the
1680 top-level scope), lookup the name in the destination container and
1681 verify that it is of the same kind before we do anything else. */
1682
1683 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
676c3ecb 1684 && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
c499eb68
NA
1685 {
1686 dst_type = tmp;
1687 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1688 }
1689
1690 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1691 unless dst_type is a forward declaration and src_type is a struct,
5de9eada 1692 union, or enum (i.e. the definition of the previous forward decl).
c499eb68 1693
5de9eada
NA
1694 We also allow addition in the opposite order (addition of a forward when a
1695 struct, union, or enum already exists), which is a NOP and returns the
1696 already-present struct, union, or enum. */
1697
1698 if (dst_type != CTF_ERR && dst_kind != kind)
c499eb68 1699 {
5de9eada
NA
1700 if (kind == CTF_K_FORWARD
1701 && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1702 || dst_kind == CTF_K_UNION))
1703 {
1704 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1705 return dst_type;
1706 }
1707
1708 if (dst_kind != CTF_K_FORWARD
1709 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1710 && kind != CTF_K_UNION))
1711 {
1712 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1713 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1714 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1715 }
c499eb68
NA
1716 }
1717
1718 /* We take special action for an integer, float, or slice since it is
1719 described not only by its name but also its encoding. For integers,
1720 bit-fields exploit this degeneracy. */
1721
1722 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1723 {
1724 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1725 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1726
1727 if (dst_type != CTF_ERR)
1728 {
1729 ctf_file_t *fp = dst_fp;
1730
1731 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1732 return CTF_ERR;
1733
99dc3ebd
NA
1734 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1735 return CTF_ERR; /* errno set for us. */
1736
c499eb68
NA
1737 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1738 {
1739 /* The type that we found in the hash is also root-visible. If
1740 the two types match then use the existing one; otherwise,
1741 declare a conflict. Note: slices are not certain to match
1742 even if there is no conflict: we must check the contained type
1743 too. */
1744
c499eb68
NA
1745 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1746 {
1747 if (kind != CTF_K_SLICE)
886453cb
NA
1748 {
1749 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1750 return dst_type;
1751 }
c499eb68
NA
1752 }
1753 else
1754 {
1755 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1756 }
1757 }
1758 else
1759 {
99dc3ebd
NA
1760 /* We found a non-root-visible type in the hash. If its encoding
1761 is the same, we can reuse it, unless it is a slice. */
c499eb68 1762
99dc3ebd 1763 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
c499eb68
NA
1764 {
1765 if (kind != CTF_K_SLICE)
886453cb 1766 {
99dc3ebd
NA
1767 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1768 return dst_type;
886453cb 1769 }
c499eb68 1770 }
c499eb68
NA
1771 }
1772 }
1773 }
1774
1775 src.ctb_file = src_fp;
1776 src.ctb_type = src_type;
1777 src.ctb_dtd = NULL;
1778
1779 dst.ctb_file = dst_fp;
1780 dst.ctb_type = dst_type;
1781 dst.ctb_dtd = NULL;
1782
99dc3ebd
NA
1783 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then we add
1784 a new type with the same properties as src_type to dst_fp. If dst_type is
1785 not CTF_ERR, then we verify that dst_type has the same attributes as
1786 src_type. We recurse for embedded references. Before we start, we note
1787 that we are processing this type, to prevent infinite recursion: we do not
1788 re-process any type that appears in this list. The list is emptied
1789 wholesale at the end of processing everything in this recursive stack. */
1790
1791 if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1792 (void *) (uintptr_t) src_type, (void *) 1) < 0)
1793 return ctf_set_errno (dst_fp, ENOMEM);
1794
c499eb68
NA
1795 switch (kind)
1796 {
1797 case CTF_K_INTEGER:
1798 /* If we found a match we will have either returned it or declared a
1799 conflict. */
1800 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1801 break;
1802
1803 case CTF_K_FLOAT:
1804 /* If we found a match we will have either returned it or declared a
1805 conflict. */
1806 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1807 break;
1808
1809 case CTF_K_SLICE:
1810 /* We have checked for conflicting encodings: now try to add the
1811 contained type. */
1812 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
1813 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1814 proc_tracking_fp);
c499eb68
NA
1815
1816 if (src_type == CTF_ERR)
1817 return CTF_ERR; /* errno is set for us. */
1818
1819 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1820 break;
1821
1822 case CTF_K_POINTER:
1823 case CTF_K_VOLATILE:
1824 case CTF_K_CONST:
1825 case CTF_K_RESTRICT:
1826 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
1827 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1828 proc_tracking_fp);
c499eb68
NA
1829
1830 if (src_type == CTF_ERR)
1831 return CTF_ERR; /* errno is set for us. */
1832
1833 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1834 break;
1835
1836 case CTF_K_ARRAY:
a0486bac 1837 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
c499eb68
NA
1838 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1839
1840 src_ar.ctr_contents =
99dc3ebd
NA
1841 ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1842 proc_tracking_fp);
1843 src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1844 src_ar.ctr_index,
1845 proc_tracking_fp);
c499eb68
NA
1846 src_ar.ctr_nelems = src_ar.ctr_nelems;
1847
1848 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1849 return CTF_ERR; /* errno is set for us. */
1850
1851 if (dst_type != CTF_ERR)
1852 {
1853 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1854 return CTF_ERR; /* errno is set for us. */
1855
1856 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1857 {
1858 ctf_dprintf ("Conflict for type %s against ID %lx: "
1859 "array info differs, old %lx/%lx/%x; "
1860 "new: %lx/%lx/%x\n", name, dst_type,
1861 src_ar.ctr_contents, src_ar.ctr_index,
1862 src_ar.ctr_nelems, dst_ar.ctr_contents,
1863 dst_ar.ctr_index, dst_ar.ctr_nelems);
1864 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1865 }
1866 }
1867 else
1868 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1869 break;
1870
1871 case CTF_K_FUNCTION:
99dc3ebd
NA
1872 ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1873 src_tp->ctt_type,
1874 proc_tracking_fp);
c499eb68
NA
1875 ctc.ctc_argc = 0;
1876 ctc.ctc_flags = 0;
1877
1878 if (ctc.ctc_return == CTF_ERR)
1879 return CTF_ERR; /* errno is set for us. */
1880
1881 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1882 break;
1883
1884 case CTF_K_STRUCT:
1885 case CTF_K_UNION:
1886 {
1887 ctf_dmdef_t *dmd;
1888 int errs = 0;
a0486bac
JM
1889 size_t size;
1890 ssize_t ssize;
99dc3ebd 1891 ctf_dtdef_t *dtd;
c499eb68
NA
1892
1893 /* Technically to match a struct or union we need to check both
1894 ways (src members vs. dst, dst members vs. src) but we make
1895 this more optimal by only checking src vs. dst and comparing
1896 the total size of the structure (which we must do anyway)
1897 which covers the possibility of dst members not in src.
1898 This optimization can be defeated for unions, but is so
1899 pathological as to render it irrelevant for our purposes. */
1900
99dc3ebd
NA
1901 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1902 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
1903 {
1904 if (ctf_type_size (src_fp, src_type) !=
1905 ctf_type_size (dst_fp, dst_type))
1906 {
1907 ctf_dprintf ("Conflict for type %s against ID %lx: "
62d8e3b7
NA
1908 "union size differs, old %li, new %li\n",
1909 name, dst_type,
1910 (long) ctf_type_size (src_fp, src_type),
1911 (long) ctf_type_size (dst_fp, dst_type));
c499eb68
NA
1912 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1913 }
1914
1915 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1916 {
1917 ctf_dprintf ("Conflict for type %s against ID %lx: "
1918 "members differ, see above\n", name, dst_type);
1919 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1920 }
1921
1922 break;
1923 }
1924
1925 /* Unlike the other cases, copying structs and unions is done
1926 manually so as to avoid repeated lookups in ctf_add_member
1927 and to ensure the exact same member offsets as in src_type. */
1928
676c3ecb 1929 dst_type = ctf_add_generic (dst_fp, flag, name, kind, &dtd);
c499eb68
NA
1930 if (dst_type == CTF_ERR)
1931 return CTF_ERR; /* errno is set for us. */
1932
1933 dst.ctb_type = dst_type;
1934 dst.ctb_dtd = dtd;
1935
99dc3ebd
NA
1936 /* Pre-emptively add this struct to the type mapping so that
1937 structures that refer to themselves work. */
1938 ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1939
c499eb68
NA
1940 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1941 errs++; /* Increment errs and fail at bottom of case. */
1942
a0486bac
JM
1943 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1944 return CTF_ERR; /* errno is set for us. */
1945
1946 size = (size_t) ssize;
1947 if (size > CTF_MAX_SIZE)
c499eb68
NA
1948 {
1949 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1950 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1951 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1952 }
1953 else
1954 dtd->dtd_data.ctt_size = (uint32_t) size;
1955
1956 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1957
1958 /* Make a final pass through the members changing each dmd_type (a
1959 src_fp type) to an equivalent type in dst_fp. We pass through all
791915db
NA
1960 members, leaving any that fail set to CTF_ERR, unless they fail
1961 because they are marking a member of type not representable in this
1962 version of CTF, in which case we just want to silently omit them:
1963 no consumer can do anything with them anyway. */
c499eb68
NA
1964 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1965 dmd != NULL; dmd = ctf_list_next (dmd))
1966 {
99dc3ebd
NA
1967 ctf_file_t *dst = dst_fp;
1968 ctf_id_t memb_type;
1969
1970 memb_type = ctf_type_mapping (src_fp, dmd->dmd_type, &dst);
1971 if (memb_type == 0)
791915db 1972 {
99dc3ebd
NA
1973 if ((dmd->dmd_type =
1974 ctf_add_type_internal (dst_fp, src_fp, dmd->dmd_type,
1975 proc_tracking_fp)) == CTF_ERR)
1976 {
1977 if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1978 errs++;
1979 }
791915db 1980 }
99dc3ebd
NA
1981 else
1982 dmd->dmd_type = memb_type;
c499eb68
NA
1983 }
1984
1985 if (errs)
1986 return CTF_ERR; /* errno is set for us. */
1987 break;
1988 }
1989
1990 case CTF_K_ENUM:
99dc3ebd
NA
1991 if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1992 && dst_kind != CTF_K_FORWARD)
c499eb68
NA
1993 {
1994 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1995 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1996 {
1997 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1998 "members differ, see above\n", name, dst_type);
1999 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
2000 }
2001 }
2002 else
2003 {
2004 dst_type = ctf_add_enum (dst_fp, flag, name);
2005 if ((dst.ctb_type = dst_type) == CTF_ERR
2006 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
2007 return CTF_ERR; /* errno is set for us */
2008 }
2009 break;
2010
2011 case CTF_K_FORWARD:
2012 if (dst_type == CTF_ERR)
5de9eada 2013 dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
c499eb68
NA
2014 break;
2015
2016 case CTF_K_TYPEDEF:
2017 src_type = ctf_type_reference (src_fp, src_type);
99dc3ebd
NA
2018 src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2019 proc_tracking_fp);
c499eb68
NA
2020
2021 if (src_type == CTF_ERR)
2022 return CTF_ERR; /* errno is set for us. */
2023
2024 /* If dst_type is not CTF_ERR at this point, we should check if
2025 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
2026 ECTF_CONFLICT. However, this causes problems with bitness typedefs
2027 that vary based on things like if 32-bit then pid_t is int otherwise
2028 long. We therefore omit this check and assume that if the identically
2029 named typedef already exists in dst_fp, it is correct or
2030 equivalent. */
2031
2032 if (dst_type == CTF_ERR)
c499eb68 2033 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
99dc3ebd 2034
c499eb68
NA
2035 break;
2036
2037 default:
2038 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
2039 }
2040
886453cb
NA
2041 if (dst_type != CTF_ERR)
2042 ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
c499eb68
NA
2043 return dst_type;
2044}
2045
99dc3ebd
NA
2046ctf_id_t
2047ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
2048{
2049 ctf_id_t id;
2050
2051 if (!src_fp->ctf_add_processing)
2052 src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
2053 ctf_hash_eq_integer,
2054 NULL, NULL);
2055
2056 /* We store the hash on the source, because it contains only source type IDs:
2057 but callers will invariably expect errors to appear on the dest. */
2058 if (!src_fp->ctf_add_processing)
2059 return (ctf_set_errno (dst_fp, ENOMEM));
2060
2061 id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
2062 ctf_dynhash_empty (src_fp->ctf_add_processing);
2063
2064 return id;
2065}
2066
fd55eae8 2067/* Write the compressed CTF data stream to the specified gzFile descriptor. */
47d546f4
NA
2068int
2069ctf_gzwrite (ctf_file_t *fp, gzFile fd)
2070{
fd55eae8
NA
2071 const unsigned char *buf;
2072 ssize_t resid;
47d546f4
NA
2073 ssize_t len;
2074
fd55eae8
NA
2075 resid = sizeof (ctf_header_t);
2076 buf = (unsigned char *) fp->ctf_header;
2077 while (resid != 0)
2078 {
2079 if ((len = gzwrite (fd, buf, resid)) <= 0)
2080 return (ctf_set_errno (fp, errno));
2081 resid -= len;
2082 buf += len;
2083 }
2084
2085 resid = fp->ctf_size;
2086 buf = fp->ctf_buf;
47d546f4
NA
2087 while (resid != 0)
2088 {
2089 if ((len = gzwrite (fd, buf, resid)) <= 0)
2090 return (ctf_set_errno (fp, errno));
2091 resid -= len;
2092 buf += len;
2093 }
2094
2095 return 0;
2096}
2097
2098/* Compress the specified CTF data stream and write it to the specified file
2099 descriptor. */
2100int
2101ctf_compress_write (ctf_file_t *fp, int fd)
2102{
2103 unsigned char *buf;
2104 unsigned char *bp;
2105 ctf_header_t h;
2106 ctf_header_t *hp = &h;
2107 ssize_t header_len = sizeof (ctf_header_t);
2108 ssize_t compress_len;
47d546f4
NA
2109 ssize_t len;
2110 int rc;
2111 int err = 0;
2112
676c3ecb
NA
2113 if (ctf_serialize (fp) < 0)
2114 return -1; /* errno is set for us. */
2115
fd55eae8 2116 memcpy (hp, fp->ctf_header, header_len);
47d546f4 2117 hp->cth_flags |= CTF_F_COMPRESS;
676c3ecb 2118 compress_len = compressBound (fp->ctf_size);
47d546f4 2119
de07e349 2120 if ((buf = malloc (compress_len)) == NULL)
47d546f4
NA
2121 return (ctf_set_errno (fp, ECTF_ZALLOC));
2122
65365aa8 2123 if ((rc = compress (buf, (uLongf *) &compress_len,
fd55eae8 2124 fp->ctf_buf, fp->ctf_size)) != Z_OK)
47d546f4
NA
2125 {
2126 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2127 err = ctf_set_errno (fp, ECTF_COMPRESS);
2128 goto ret;
2129 }
2130
2131 while (header_len > 0)
2132 {
2133 if ((len = write (fd, hp, header_len)) < 0)
2134 {
2135 err = ctf_set_errno (fp, errno);
2136 goto ret;
2137 }
2138 header_len -= len;
2139 hp += len;
2140 }
2141
2142 bp = buf;
2143 while (compress_len > 0)
2144 {
2145 if ((len = write (fd, bp, compress_len)) < 0)
2146 {
2147 err = ctf_set_errno (fp, errno);
2148 goto ret;
2149 }
2150 compress_len -= len;
2151 bp += len;
2152 }
2153
2154ret:
de07e349 2155 free (buf);
47d546f4
NA
2156 return err;
2157}
2158
5537f9b9
NA
2159/* Optionally compress the specified CTF data stream and return it as a new
2160 dynamically-allocated string. */
2161unsigned char *
2162ctf_write_mem (ctf_file_t *fp, size_t *size, size_t threshold)
2163{
2164 unsigned char *buf;
2165 unsigned char *bp;
2166 ctf_header_t *hp;
2167 ssize_t header_len = sizeof (ctf_header_t);
2168 ssize_t compress_len;
5537f9b9
NA
2169 int rc;
2170
676c3ecb
NA
2171 if (ctf_serialize (fp) < 0)
2172 return NULL; /* errno is set for us. */
2173
2174 compress_len = compressBound (fp->ctf_size);
5537f9b9 2175 if (fp->ctf_size < threshold)
676c3ecb
NA
2176 compress_len = fp->ctf_size;
2177 if ((buf = malloc (compress_len
5537f9b9
NA
2178 + sizeof (struct ctf_header))) == NULL)
2179 {
2180 ctf_set_errno (fp, ENOMEM);
2181 return NULL;
2182 }
2183
2184 hp = (ctf_header_t *) buf;
2185 memcpy (hp, fp->ctf_header, header_len);
2186 bp = buf + sizeof (struct ctf_header);
2187 *size = sizeof (struct ctf_header);
2188
5537f9b9
NA
2189 if (fp->ctf_size < threshold)
2190 {
2191 hp->cth_flags &= ~CTF_F_COMPRESS;
2192 memcpy (bp, fp->ctf_buf, fp->ctf_size);
2193 *size += fp->ctf_size;
2194 }
2195 else
2196 {
2197 hp->cth_flags |= CTF_F_COMPRESS;
2198 if ((rc = compress (bp, (uLongf *) &compress_len,
2199 fp->ctf_buf, fp->ctf_size)) != Z_OK)
2200 {
2201 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2202 ctf_set_errno (fp, ECTF_COMPRESS);
de07e349 2203 free (buf);
5537f9b9
NA
2204 return NULL;
2205 }
2206 *size += compress_len;
2207 }
2208 return buf;
2209}
2210
fd55eae8 2211/* Write the uncompressed CTF data stream to the specified file descriptor. */
47d546f4
NA
2212int
2213ctf_write (ctf_file_t *fp, int fd)
2214{
fd55eae8
NA
2215 const unsigned char *buf;
2216 ssize_t resid;
47d546f4
NA
2217 ssize_t len;
2218
676c3ecb
NA
2219 if (ctf_serialize (fp) < 0)
2220 return -1; /* errno is set for us. */
2221
fd55eae8
NA
2222 resid = sizeof (ctf_header_t);
2223 buf = (unsigned char *) fp->ctf_header;
2224 while (resid != 0)
2225 {
2226 if ((len = write (fd, buf, resid)) <= 0)
2227 return (ctf_set_errno (fp, errno));
2228 resid -= len;
2229 buf += len;
2230 }
2231
2232 resid = fp->ctf_size;
2233 buf = fp->ctf_buf;
47d546f4
NA
2234 while (resid != 0)
2235 {
fd55eae8 2236 if ((len = write (fd, buf, resid)) <= 0)
47d546f4
NA
2237 return (ctf_set_errno (fp, errno));
2238 resid -= len;
2239 buf += len;
2240 }
2241
2242 return 0;
2243}
This page took 0.170945 seconds and 4 git commands to generate.