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