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