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