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