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