libctf: handle errors on dynhash insertion better
[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
24865428 529int
47d546f4
NA
530ctf_dtd_insert (ctf_file_t *fp, ctf_dtdef_t *dtd)
531{
24865428
NA
532 if (ctf_dynhash_insert (fp->ctf_dthash, (void *) dtd->dtd_type, dtd) < 0)
533 return -1;
534
47d546f4
NA
535 if (dtd->dtd_name)
536 {
537 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
24865428
NA
538 if (ctf_dynhash_insert (fp->ctf_dtbyname,
539 ctf_prefixed_name (kind, dtd->dtd_name),
540 dtd) < 0)
541 return -1;
47d546f4 542 }
24865428
NA
543 ctf_list_append (&fp->ctf_dtdefs, dtd);
544 return 0;
47d546f4
NA
545}
546
547void
548ctf_dtd_delete (ctf_file_t *fp, ctf_dtdef_t *dtd)
549{
550 ctf_dmdef_t *dmd, *nmd;
551 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
552
553 ctf_dynhash_remove (fp->ctf_dthash, (void *) dtd->dtd_type);
554
555 switch (kind)
556 {
557 case CTF_K_STRUCT:
558 case CTF_K_UNION:
559 case CTF_K_ENUM:
560 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
561 dmd != NULL; dmd = nmd)
562 {
563 if (dmd->dmd_name != NULL)
564 {
565 fp->ctf_dtvstrlen -= strlen (dmd->dmd_name) + 1;
566 ctf_free (dmd->dmd_name);
567 }
568 nmd = ctf_list_next (dmd);
569 ctf_free (dmd);
570 }
571 break;
572 case CTF_K_FUNCTION:
573 ctf_free (dtd->dtd_u.dtu_argv);
574 break;
575 }
576
577 if (dtd->dtd_name)
578 {
579 char *name;
580
581 name = ctf_prefixed_name (kind, dtd->dtd_name);
582 ctf_dynhash_remove (fp->ctf_dtbyname, name);
583 free (name);
584
585 fp->ctf_dtvstrlen -= strlen (dtd->dtd_name) + 1;
586 ctf_free (dtd->dtd_name);
587 }
588
589 ctf_list_delete (&fp->ctf_dtdefs, dtd);
590 ctf_free (dtd);
591}
592
593ctf_dtdef_t *
594ctf_dtd_lookup (const ctf_file_t *fp, ctf_id_t type)
595{
596 return (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dthash, (void *) type);
597}
598
599static ctf_id_t
600ctf_dtd_lookup_type_by_name (ctf_file_t *fp, int kind, const char *name)
601{
602 ctf_dtdef_t *dtd;
603 char *decorated = ctf_prefixed_name (kind, name);
604
605 dtd = (ctf_dtdef_t *) ctf_dynhash_lookup (fp->ctf_dtbyname, decorated);
606 free (decorated);
607
608 if (dtd)
609 return dtd->dtd_type;
610
611 return 0;
612}
613
614ctf_dtdef_t *
615ctf_dynamic_type (const ctf_file_t *fp, ctf_id_t id)
616{
617 ctf_id_t idx;
618
619 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
620 fp = fp->ctf_parent;
621
622 idx = LCTF_TYPE_TO_INDEX(fp, id);
623
624 if (((unsigned long) idx > fp->ctf_typemax) &&
625 ((unsigned long) idx < fp->ctf_dtnextid))
626 return ctf_dtd_lookup (fp, id);
627 return NULL;
628}
629
24865428 630int
47d546f4
NA
631ctf_dvd_insert (ctf_file_t *fp, ctf_dvdef_t *dvd)
632{
24865428
NA
633 if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
634 return -1;
47d546f4 635 ctf_list_append (&fp->ctf_dvdefs, dvd);
24865428 636 return 0;
47d546f4
NA
637}
638
639void
640ctf_dvd_delete (ctf_file_t *fp, ctf_dvdef_t *dvd)
641{
642 ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
643
644 fp->ctf_dtvstrlen -= strlen (dvd->dvd_name) + 1;
645 ctf_free (dvd->dvd_name);
646
647 ctf_list_delete (&fp->ctf_dvdefs, dvd);
648 ctf_free (dvd);
649}
650
651ctf_dvdef_t *
652ctf_dvd_lookup (const ctf_file_t *fp, const char *name)
653{
654 return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
655}
656
657/* Discard all of the dynamic type definitions and variable definitions that
658 have been added to the container since the last call to ctf_update(). We
659 locate such types by scanning the dtd list and deleting elements that have
660 type IDs greater than ctf_dtoldid, which is set by ctf_update(), above, and
661 by scanning the variable list and deleting elements that have update IDs
662 equal to the current value of the last-update snapshot count (indicating that
663 they were added after the most recent call to ctf_update()). */
664int
665ctf_discard (ctf_file_t *fp)
666{
667 ctf_snapshot_id_t last_update =
668 { fp->ctf_dtoldid,
669 fp->ctf_snapshot_lu + 1 };
670
671 /* Update required? */
672 if (!(fp->ctf_flags & LCTF_DIRTY))
673 return 0;
674
675 return (ctf_rollback (fp, last_update));
676}
677
678ctf_snapshot_id_t
679ctf_snapshot (ctf_file_t *fp)
680{
681 ctf_snapshot_id_t snapid;
682 snapid.dtd_id = fp->ctf_dtnextid - 1;
683 snapid.snapshot_id = fp->ctf_snapshots++;
684 return snapid;
685}
686
687/* Like ctf_discard(), only discards everything after a particular ID. */
688int
689ctf_rollback (ctf_file_t *fp, ctf_snapshot_id_t id)
690{
691 ctf_dtdef_t *dtd, *ntd;
692 ctf_dvdef_t *dvd, *nvd;
693
694 if (!(fp->ctf_flags & LCTF_RDWR))
695 return (ctf_set_errno (fp, ECTF_RDONLY));
696
697 if (fp->ctf_dtoldid > id.dtd_id)
698 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
699
700 if (fp->ctf_snapshot_lu >= id.snapshot_id)
701 return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
702
703 for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
704 {
705 ntd = ctf_list_next (dtd);
706
707 if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
708 continue;
709
710 ctf_dtd_delete (fp, dtd);
711 }
712
713 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
714 {
715 nvd = ctf_list_next (dvd);
716
717 if (dvd->dvd_snapshots <= id.snapshot_id)
718 continue;
719
720 ctf_dvd_delete (fp, dvd);
721 }
722
723 fp->ctf_dtnextid = id.dtd_id + 1;
724 fp->ctf_snapshots = id.snapshot_id;
725
726 if (fp->ctf_snapshots == fp->ctf_snapshot_lu)
727 fp->ctf_flags &= ~LCTF_DIRTY;
728
729 return 0;
730}
731
732static ctf_id_t
733ctf_add_generic (ctf_file_t *fp, uint32_t flag, const char *name,
734 ctf_dtdef_t **rp)
735{
736 ctf_dtdef_t *dtd;
737 ctf_id_t type;
738 char *s = NULL;
739
740 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
741 return (ctf_set_errno (fp, EINVAL));
742
743 if (!(fp->ctf_flags & LCTF_RDWR))
744 return (ctf_set_errno (fp, ECTF_RDONLY));
745
746 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
747 return (ctf_set_errno (fp, ECTF_FULL));
748
749 if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_dtnextid, 1) == CTF_MAX_PTYPE)
750 return (ctf_set_errno (fp, ECTF_FULL));
751
752 if ((dtd = ctf_alloc (sizeof (ctf_dtdef_t))) == NULL)
753 return (ctf_set_errno (fp, EAGAIN));
754
755 if (name != NULL && (s = ctf_strdup (name)) == NULL)
756 {
757 ctf_free (dtd);
758 return (ctf_set_errno (fp, EAGAIN));
759 }
760
761 type = fp->ctf_dtnextid++;
762 type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
763
764 memset (dtd, 0, sizeof (ctf_dtdef_t));
765 dtd->dtd_name = s;
766 dtd->dtd_type = type;
767
768 if (s != NULL)
769 fp->ctf_dtvstrlen += strlen (s) + 1;
770
24865428
NA
771 if (ctf_dtd_insert (fp, dtd) < 0)
772 {
773 ctf_free (dtd);
774 return CTF_ERR; /* errno is set for us. */
775 }
47d546f4
NA
776 fp->ctf_flags |= LCTF_DIRTY;
777
778 *rp = dtd;
779 return type;
780}
781
782/* When encoding integer sizes, we want to convert a byte count in the range
783 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
784 is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */
785static size_t
786clp2 (size_t x)
787{
788 x--;
789
790 x |= (x >> 1);
791 x |= (x >> 2);
792 x |= (x >> 4);
793 x |= (x >> 8);
794 x |= (x >> 16);
795
796 return (x + 1);
797}
798
799static ctf_id_t
800ctf_add_encoded (ctf_file_t *fp, uint32_t flag,
801 const char *name, const ctf_encoding_t *ep, uint32_t kind)
802{
803 ctf_dtdef_t *dtd;
804 ctf_id_t type;
805
806 if (ep == NULL)
807 return (ctf_set_errno (fp, EINVAL));
808
809 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
810 return CTF_ERR; /* errno is set for us. */
811
812 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
76fad999
TT
813 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
814 / CHAR_BIT);
47d546f4
NA
815 dtd->dtd_u.dtu_enc = *ep;
816
817 return type;
818}
819
820static ctf_id_t
821ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
822{
823 ctf_dtdef_t *dtd;
824 ctf_id_t type;
825 ctf_file_t *tmp = fp;
826
a0486bac 827 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
828 return (ctf_set_errno (fp, EINVAL));
829
830 if (ctf_lookup_by_id (&tmp, ref) == NULL)
831 return CTF_ERR; /* errno is set for us. */
832
833 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
834 return CTF_ERR; /* errno is set for us. */
835
836 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
837 dtd->dtd_data.ctt_type = (uint32_t) ref;
838
839 return type;
840}
841
842ctf_id_t
843ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
844 const ctf_encoding_t *ep)
845{
846 ctf_dtdef_t *dtd;
847 ctf_id_t type;
848 int kind;
849 const ctf_type_t *tp;
850 ctf_file_t *tmp = fp;
851
852 if (ep == NULL)
853 return (ctf_set_errno (fp, EINVAL));
854
855 if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
856 return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW));
857
a0486bac 858 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
859 return (ctf_set_errno (fp, EINVAL));
860
861 if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)
862 return CTF_ERR; /* errno is set for us. */
863
864 kind = ctf_type_kind_unsliced (tmp, ref);
865 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
866 (kind != CTF_K_ENUM))
867 return (ctf_set_errno (fp, ECTF_NOTINTFP));
868
869 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
870 return CTF_ERR; /* errno is set for us. */
871
872 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
76fad999
TT
873 dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
874 / CHAR_BIT);
47d546f4
NA
875 dtd->dtd_u.dtu_slice.cts_type = ref;
876 dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
877 dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
878
879 return type;
880}
881
882ctf_id_t
883ctf_add_integer (ctf_file_t *fp, uint32_t flag,
884 const char *name, const ctf_encoding_t *ep)
885{
886 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
887}
888
889ctf_id_t
890ctf_add_float (ctf_file_t *fp, uint32_t flag,
891 const char *name, const ctf_encoding_t *ep)
892{
893 return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
894}
895
896ctf_id_t
897ctf_add_pointer (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
898{
899 return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
900}
901
902ctf_id_t
903ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
904{
905 ctf_dtdef_t *dtd;
906 ctf_id_t type;
907 ctf_file_t *tmp = fp;
908
909 if (arp == NULL)
910 return (ctf_set_errno (fp, EINVAL));
911
912 if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
913 return CTF_ERR; /* errno is set for us. */
914
915 tmp = fp;
916 if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
917 return CTF_ERR; /* errno is set for us. */
918
919 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
920 return CTF_ERR; /* errno is set for us. */
921
922 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
923 dtd->dtd_data.ctt_size = 0;
924 dtd->dtd_u.dtu_arr = *arp;
925
926 return type;
927}
928
929int
930ctf_set_array (ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
931{
932 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
933
934 if (!(fp->ctf_flags & LCTF_RDWR))
935 return (ctf_set_errno (fp, ECTF_RDONLY));
936
937 if (dtd == NULL
938 || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
939 return (ctf_set_errno (fp, ECTF_BADID));
940
941 fp->ctf_flags |= LCTF_DIRTY;
942 dtd->dtd_u.dtu_arr = *arp;
943
944 return 0;
945}
946
947ctf_id_t
948ctf_add_function (ctf_file_t *fp, uint32_t flag,
949 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
950{
951 ctf_dtdef_t *dtd;
952 ctf_id_t type;
953 uint32_t vlen;
954 ctf_id_t *vdat = NULL;
955 ctf_file_t *tmp = fp;
956 size_t i;
957
958 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
959 || (ctc->ctc_argc != 0 && argv == NULL))
960 return (ctf_set_errno (fp, EINVAL));
961
962 vlen = ctc->ctc_argc;
963 if (ctc->ctc_flags & CTF_FUNC_VARARG)
964 vlen++; /* Add trailing zero to indicate varargs (see below). */
965
966 if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
967 return CTF_ERR; /* errno is set for us. */
968
969 for (i = 0; i < ctc->ctc_argc; i++)
970 {
971 tmp = fp;
972 if (ctf_lookup_by_id (&tmp, argv[i]) == NULL)
973 return CTF_ERR; /* errno is set for us. */
974 }
975
976 if (vlen > CTF_MAX_VLEN)
977 return (ctf_set_errno (fp, EOVERFLOW));
978
979 if (vlen != 0 && (vdat = ctf_alloc (sizeof (ctf_id_t) * vlen)) == NULL)
980 return (ctf_set_errno (fp, EAGAIN));
981
982 if ((type = ctf_add_generic (fp, flag, NULL, &dtd)) == CTF_ERR)
983 {
984 ctf_free (vdat);
985 return CTF_ERR; /* errno is set for us. */
986 }
987
988 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
989 dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
990
991 memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
992 if (ctc->ctc_flags & CTF_FUNC_VARARG)
993 vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
994 dtd->dtd_u.dtu_argv = vdat;
995
996 return type;
997}
998
999ctf_id_t
1000ctf_add_struct_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1001 size_t size)
1002{
1003 ctf_hash_t *hp = fp->ctf_structs;
1004 ctf_dtdef_t *dtd;
1005 ctf_id_t type = 0;
1006
1007 /* Promote forwards to structs. */
1008
1009 if (name != NULL)
1010 {
1011 type = ctf_hash_lookup_type (hp, fp, name);
1012 if (type == 0)
1013 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_STRUCT, name);
1014 }
1015
1016 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1017 dtd = ctf_dtd_lookup (fp, type);
1018 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1019 return CTF_ERR; /* errno is set for us. */
1020
1021 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
1022
1023 if (size > CTF_MAX_SIZE)
1024 {
1025 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1026 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1027 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1028 }
1029 else
1030 dtd->dtd_data.ctt_size = (uint32_t) size;
1031
1032 return type;
1033}
1034
1035ctf_id_t
1036ctf_add_struct (ctf_file_t *fp, uint32_t flag, const char *name)
1037{
1038 return (ctf_add_struct_sized (fp, flag, name, 0));
1039}
1040
1041ctf_id_t
1042ctf_add_union_sized (ctf_file_t *fp, uint32_t flag, const char *name,
1043 size_t size)
1044{
1045 ctf_hash_t *hp = fp->ctf_unions;
1046 ctf_dtdef_t *dtd;
1047 ctf_id_t type = 0;
1048
1049 /* Promote forwards to unions. */
1050 if (name != NULL)
1051 {
1052 type = ctf_hash_lookup_type (hp, fp, name);
1053 if (type == 0)
1054 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_UNION, name);
1055 }
1056
1057 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1058 dtd = ctf_dtd_lookup (fp, type);
1059 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1060 return CTF_ERR; /* errno is set for us */
1061
1062 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
1063
1064 if (size > CTF_MAX_SIZE)
1065 {
1066 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1067 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1068 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1069 }
1070 else
1071 dtd->dtd_data.ctt_size = (uint32_t) size;
1072
1073 return type;
1074}
1075
1076ctf_id_t
1077ctf_add_union (ctf_file_t *fp, uint32_t flag, const char *name)
1078{
1079 return (ctf_add_union_sized (fp, flag, name, 0));
1080}
1081
1082ctf_id_t
1083ctf_add_enum (ctf_file_t *fp, uint32_t flag, const char *name)
1084{
1085 ctf_hash_t *hp = fp->ctf_enums;
1086 ctf_dtdef_t *dtd;
1087 ctf_id_t type = 0;
1088
1089 /* Promote forwards to enums. */
1090 if (name != NULL)
1091 {
1092 type = ctf_hash_lookup_type (hp, fp, name);
1093 if (type == 0)
1094 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1095 }
1096
1097 if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
1098 dtd = ctf_dtd_lookup (fp, type);
1099 else if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1100 return CTF_ERR; /* errno is set for us. */
1101
1102 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
1103 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1104
1105 return type;
1106}
1107
1108ctf_id_t
1109ctf_add_enum_encoded (ctf_file_t *fp, uint32_t flag, const char *name,
1110 const ctf_encoding_t *ep)
1111{
1112 ctf_hash_t *hp = fp->ctf_enums;
1113 ctf_id_t type = 0;
1114
1115 /* First, create the enum if need be, using most of the same machinery as
1116 ctf_add_enum(), to ensure that we do not allow things past that are not
1117 enums or forwards to them. (This includes other slices: you cannot slice a
1118 slice, which would be a useless thing to do anyway.) */
1119
1120 if (name != NULL)
1121 {
1122 type = ctf_hash_lookup_type (hp, fp, name);
1123 if (type == 0)
1124 type = ctf_dtd_lookup_type_by_name (fp, CTF_K_ENUM, name);
1125 }
1126
1127 if (type != 0)
1128 {
1129 if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
1130 (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
1131 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1132 }
1133 else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
1134 return CTF_ERR; /* errno is set for us. */
1135
1136 /* Now attach a suitable slice to it. */
1137
1138 return ctf_add_slice (fp, flag, type, ep);
1139}
1140
1141ctf_id_t
1142ctf_add_forward (ctf_file_t *fp, uint32_t flag, const char *name,
1143 uint32_t kind)
1144{
1145 ctf_hash_t *hp;
1146 ctf_dtdef_t *dtd;
1147 ctf_id_t type = 0;
1148
1149 switch (kind)
1150 {
1151 case CTF_K_STRUCT:
1152 hp = fp->ctf_structs;
1153 break;
1154 case CTF_K_UNION:
1155 hp = fp->ctf_unions;
1156 break;
1157 case CTF_K_ENUM:
1158 hp = fp->ctf_enums;
1159 break;
1160 default:
1161 return (ctf_set_errno (fp, ECTF_NOTSUE));
1162 }
1163
1164 /* If the type is already defined or exists as a forward tag, just
1165 return the ctf_id_t of the existing definition. */
1166
1167 if (name != NULL)
1168 {
1169 if (((type = ctf_hash_lookup_type (hp, fp, name)) != 0)
1170 || (type = ctf_dtd_lookup_type_by_name (fp, kind, name)) != 0)
1171 return type;
1172 }
1173
1174 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1175 return CTF_ERR; /* errno is set for us. */
1176
1177 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
1178 dtd->dtd_data.ctt_type = kind;
1179
1180 return type;
1181}
1182
1183ctf_id_t
1184ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name,
1185 ctf_id_t ref)
1186{
1187 ctf_dtdef_t *dtd;
1188 ctf_id_t type;
1189 ctf_file_t *tmp = fp;
1190
a0486bac 1191 if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
47d546f4
NA
1192 return (ctf_set_errno (fp, EINVAL));
1193
1194 if (ctf_lookup_by_id (&tmp, ref) == NULL)
1195 return CTF_ERR; /* errno is set for us. */
1196
1197 if ((type = ctf_add_generic (fp, flag, name, &dtd)) == CTF_ERR)
1198 return CTF_ERR; /* errno is set for us. */
1199
1200 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1201 dtd->dtd_data.ctt_type = (uint32_t) ref;
1202
1203 return type;
1204}
1205
1206ctf_id_t
1207ctf_add_volatile (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1208{
1209 return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1210}
1211
1212ctf_id_t
1213ctf_add_const (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1214{
1215 return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1216}
1217
1218ctf_id_t
1219ctf_add_restrict (ctf_file_t *fp, uint32_t flag, ctf_id_t ref)
1220{
1221 return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1222}
1223
1224int
1225ctf_add_enumerator (ctf_file_t *fp, ctf_id_t enid, const char *name,
1226 int value)
1227{
1228 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, enid);
1229 ctf_dmdef_t *dmd;
1230
1231 uint32_t kind, vlen, root;
1232 char *s;
1233
1234 if (name == NULL)
1235 return (ctf_set_errno (fp, EINVAL));
1236
1237 if (!(fp->ctf_flags & LCTF_RDWR))
1238 return (ctf_set_errno (fp, ECTF_RDONLY));
1239
1240 if (dtd == NULL)
1241 return (ctf_set_errno (fp, ECTF_BADID));
1242
1243 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1244 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1245 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1246
1247 if (kind != CTF_K_ENUM)
1248 return (ctf_set_errno (fp, ECTF_NOTENUM));
1249
1250 if (vlen == CTF_MAX_VLEN)
1251 return (ctf_set_errno (fp, ECTF_DTFULL));
1252
1253 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1254 dmd != NULL; dmd = ctf_list_next (dmd))
1255 {
1256 if (strcmp (dmd->dmd_name, name) == 0)
1257 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1258 }
1259
1260 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1261 return (ctf_set_errno (fp, EAGAIN));
1262
1263 if ((s = ctf_strdup (name)) == NULL)
1264 {
1265 ctf_free (dmd);
1266 return (ctf_set_errno (fp, EAGAIN));
1267 }
1268
1269 dmd->dmd_name = s;
1270 dmd->dmd_type = CTF_ERR;
1271 dmd->dmd_offset = 0;
1272 dmd->dmd_value = value;
1273
1274 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1275 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1276
1277 fp->ctf_dtvstrlen += strlen (s) + 1;
1278 fp->ctf_flags |= LCTF_DIRTY;
1279
1280 return 0;
1281}
1282
1283int
1284ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name,
1285 ctf_id_t type, unsigned long bit_offset)
1286{
1287 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1288 ctf_dmdef_t *dmd;
1289
1290 ssize_t msize, malign, ssize;
1291 uint32_t kind, vlen, root;
1292 char *s = NULL;
1293
1294 if (!(fp->ctf_flags & LCTF_RDWR))
1295 return (ctf_set_errno (fp, ECTF_RDONLY));
1296
1297 if (dtd == NULL)
1298 return (ctf_set_errno (fp, ECTF_BADID));
1299
1300 kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1301 root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1302 vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1303
1304 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1305 return (ctf_set_errno (fp, ECTF_NOTSOU));
1306
1307 if (vlen == CTF_MAX_VLEN)
1308 return (ctf_set_errno (fp, ECTF_DTFULL));
1309
1310 if (name != NULL)
1311 {
1312 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1313 dmd != NULL; dmd = ctf_list_next (dmd))
1314 {
1315 if (dmd->dmd_name != NULL && strcmp (dmd->dmd_name, name) == 0)
1316 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1317 }
1318 }
1319
a0486bac
JM
1320 if ((msize = ctf_type_size (fp, type)) < 0 ||
1321 (malign = ctf_type_align (fp, type)) < 0)
1322 return -1; /* errno is set for us. */
47d546f4
NA
1323
1324 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1325 return (ctf_set_errno (fp, EAGAIN));
1326
1327 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1328 {
1329 ctf_free (dmd);
1330 return (ctf_set_errno (fp, EAGAIN));
1331 }
1332
1333 dmd->dmd_name = s;
1334 dmd->dmd_type = type;
1335 dmd->dmd_value = -1;
1336
1337 if (kind == CTF_K_STRUCT && vlen != 0)
1338 {
1339 if (bit_offset == (unsigned long) - 1)
1340 {
1341 /* Natural alignment. */
1342
1343 ctf_dmdef_t *lmd = ctf_list_prev (&dtd->dtd_u.dtu_members);
1344 ctf_id_t ltype = ctf_type_resolve (fp, lmd->dmd_type);
1345 size_t off = lmd->dmd_offset;
1346
1347 ctf_encoding_t linfo;
1348 ssize_t lsize;
1349
a0486bac 1350 if (ctf_type_encoding (fp, ltype, &linfo) == 0)
47d546f4 1351 off += linfo.cte_bits;
a0486bac 1352 else if ((lsize = ctf_type_size (fp, ltype)) > 0)
76fad999 1353 off += lsize * CHAR_BIT;
47d546f4
NA
1354
1355 /* Round up the offset of the end of the last member to
1356 the next byte boundary, convert 'off' to bytes, and
1357 then round it up again to the next multiple of the
1358 alignment required by the new member. Finally,
1359 convert back to bits and store the result in
1360 dmd_offset. Technically we could do more efficient
1361 packing if the new member is a bit-field, but we're
1362 the "compiler" and ANSI says we can do as we choose. */
1363
76fad999 1364 off = roundup (off, CHAR_BIT) / CHAR_BIT;
47d546f4 1365 off = roundup (off, MAX (malign, 1));
76fad999 1366 dmd->dmd_offset = off * CHAR_BIT;
47d546f4
NA
1367 ssize = off + msize;
1368 }
1369 else
1370 {
1371 /* Specified offset in bits. */
1372
1373 dmd->dmd_offset = bit_offset;
1374 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
76fad999 1375 ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
47d546f4
NA
1376 }
1377 }
1378 else
1379 {
1380 dmd->dmd_offset = 0;
1381 ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1382 ssize = MAX (ssize, msize);
1383 }
1384
a0486bac 1385 if ((size_t) ssize > CTF_MAX_SIZE)
47d546f4
NA
1386 {
1387 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1388 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1389 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1390 }
1391 else
1392 dtd->dtd_data.ctt_size = (uint32_t) ssize;
1393
1394 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1395 ctf_list_append (&dtd->dtd_u.dtu_members, dmd);
1396
1397 if (s != NULL)
1398 fp->ctf_dtvstrlen += strlen (s) + 1;
1399
1400 fp->ctf_flags |= LCTF_DIRTY;
1401 return 0;
1402}
1403
1404int
1405ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name,
1406 ctf_id_t type, unsigned long bit_offset,
1407 const ctf_encoding_t encoding)
1408{
1409 ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1410 int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1411 int otype = type;
1412
1413 if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1414 return (ctf_set_errno (fp, ECTF_NOTINTFP));
1415
1416 if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
a0486bac 1417 return -1; /* errno is set for us. */
47d546f4
NA
1418
1419 return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1420}
1421
1422int
1423ctf_add_member (ctf_file_t *fp, ctf_id_t souid, const char *name,
1424 ctf_id_t type)
1425{
1426 return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1427}
1428
1429int
1430ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref)
1431{
1432 ctf_dvdef_t *dvd;
1433 ctf_file_t *tmp = fp;
1434
1435 if (!(fp->ctf_flags & LCTF_RDWR))
1436 return (ctf_set_errno (fp, ECTF_RDONLY));
1437
1438 if (ctf_dvd_lookup (fp, name) != NULL)
1439 return (ctf_set_errno (fp, ECTF_DUPLICATE));
1440
1441 if (ctf_lookup_by_id (&tmp, ref) == NULL)
a0486bac 1442 return -1; /* errno is set for us. */
47d546f4
NA
1443
1444 if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL)
1445 return (ctf_set_errno (fp, EAGAIN));
1446
1447 if (name != NULL && (dvd->dvd_name = ctf_strdup (name)) == NULL)
1448 {
1449 ctf_free (dvd);
1450 return (ctf_set_errno (fp, EAGAIN));
1451 }
1452 dvd->dvd_type = ref;
1453 dvd->dvd_snapshots = fp->ctf_snapshots;
1454
24865428
NA
1455 if (ctf_dvd_insert (fp, dvd) < 0)
1456 {
1457 ctf_free (dvd);
1458 return -1; /* errno is set for us. */
1459 }
47d546f4
NA
1460
1461 fp->ctf_dtvstrlen += strlen (name) + 1;
1462 fp->ctf_flags |= LCTF_DIRTY;
1463 return 0;
1464}
1465
c499eb68
NA
1466static int
1467enumcmp (const char *name, int value, void *arg)
1468{
1469 ctf_bundle_t *ctb = arg;
1470 int bvalue;
1471
a0486bac 1472 if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0)
c499eb68
NA
1473 {
1474 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1475 return 1;
1476 }
1477 if (value != bvalue)
1478 {
1479 ctf_dprintf ("Conflict due to value change: %i versus %i\n",
1480 value, bvalue);
1481 return 1;
1482 }
1483 return 0;
1484}
1485
1486static int
1487enumadd (const char *name, int value, void *arg)
1488{
1489 ctf_bundle_t *ctb = arg;
1490
1491 return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type,
a0486bac 1492 name, value) < 0);
c499eb68
NA
1493}
1494
1495static int
1496membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1497 void *arg)
1498{
1499 ctf_bundle_t *ctb = arg;
1500 ctf_membinfo_t ctm;
1501
a0486bac 1502 if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0)
c499eb68
NA
1503 {
1504 ctf_dprintf ("Conflict due to member %s iteration error.\n", name);
1505 return 1;
1506 }
1507 if (ctm.ctm_offset != offset)
1508 {
1509 ctf_dprintf ("Conflict due to member %s offset change: "
1510 "%lx versus %lx\n", name, ctm.ctm_offset, offset);
1511 return 1;
1512 }
1513 return 0;
1514}
1515
1516static int
1517membadd (const char *name, ctf_id_t type, unsigned long offset, void *arg)
1518{
1519 ctf_bundle_t *ctb = arg;
1520 ctf_dmdef_t *dmd;
1521 char *s = NULL;
1522
1523 if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL)
1524 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1525
1526 if (name != NULL && (s = ctf_strdup (name)) == NULL)
1527 {
1528 ctf_free (dmd);
1529 return (ctf_set_errno (ctb->ctb_file, EAGAIN));
1530 }
1531
1532 /* For now, dmd_type is copied as the src_fp's type; it is reset to an
1533 equivalent dst_fp type by a final loop in ctf_add_type(), below. */
1534 dmd->dmd_name = s;
1535 dmd->dmd_type = type;
1536 dmd->dmd_offset = offset;
1537 dmd->dmd_value = -1;
1538
1539 ctf_list_append (&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1540
1541 if (s != NULL)
1542 ctb->ctb_file->ctf_dtvstrlen += strlen (s) + 1;
1543
1544 ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1545 return 0;
1546}
1547
1548/* The ctf_add_type routine is used to copy a type from a source CTF container
1549 to a dynamic destination container. This routine operates recursively by
1550 following the source type's links and embedded member types. If the
1551 destination container already contains a named type which has the same
1552 attributes, then we succeed and return this type but no changes occur. */
1553ctf_id_t
1554ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1555{
1556 ctf_id_t dst_type = CTF_ERR;
1557 uint32_t dst_kind = CTF_K_UNKNOWN;
1558 ctf_id_t tmp;
1559
1560 const char *name;
1561 uint32_t kind, flag, vlen;
1562
1563 const ctf_type_t *src_tp, *dst_tp;
1564 ctf_bundle_t src, dst;
1565 ctf_encoding_t src_en, dst_en;
1566 ctf_arinfo_t src_ar, dst_ar;
1567
1568 ctf_dtdef_t *dtd;
1569 ctf_funcinfo_t ctc;
c499eb68
NA
1570
1571 ctf_hash_t *hp;
1572
1573 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1574 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
1575
1576 if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1577 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1578
1579 name = ctf_strptr (src_fp, src_tp->ctt_name);
1580 kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1581 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1582 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1583
1584 switch (kind)
1585 {
1586 case CTF_K_STRUCT:
1587 hp = dst_fp->ctf_structs;
1588 break;
1589 case CTF_K_UNION:
1590 hp = dst_fp->ctf_unions;
1591 break;
1592 case CTF_K_ENUM:
1593 hp = dst_fp->ctf_enums;
1594 break;
1595 default:
1596 hp = dst_fp->ctf_names;
1597 break;
1598 }
1599
1600 /* If the source type has a name and is a root type (visible at the
1601 top-level scope), lookup the name in the destination container and
1602 verify that it is of the same kind before we do anything else. */
1603
1604 if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1605 && (tmp = ctf_hash_lookup_type (hp, dst_fp, name)) != 0)
1606 {
1607 dst_type = tmp;
1608 dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1609 }
1610
1611 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1612 unless dst_type is a forward declaration and src_type is a struct,
1613 union, or enum (i.e. the definition of the previous forward decl). */
1614
1615 if (dst_type != CTF_ERR && dst_kind != kind
1616 && (dst_kind != CTF_K_FORWARD
1617 || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1618 && kind != CTF_K_UNION)))
1619 {
1620 ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1621 "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1622 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1623 }
1624
1625 /* We take special action for an integer, float, or slice since it is
1626 described not only by its name but also its encoding. For integers,
1627 bit-fields exploit this degeneracy. */
1628
1629 if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1630 {
1631 if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1632 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1633
1634 if (dst_type != CTF_ERR)
1635 {
1636 ctf_file_t *fp = dst_fp;
1637
1638 if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1639 return CTF_ERR;
1640
1641 if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1642 {
1643 /* The type that we found in the hash is also root-visible. If
1644 the two types match then use the existing one; otherwise,
1645 declare a conflict. Note: slices are not certain to match
1646 even if there is no conflict: we must check the contained type
1647 too. */
1648
1649 if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1650 return CTF_ERR; /* errno set for us. */
1651
1652 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1653 {
1654 if (kind != CTF_K_SLICE)
1655 return dst_type;
1656 }
1657 else
1658 {
1659 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1660 }
1661 }
1662 else
1663 {
1664 /* We found a non-root-visible type in the hash. We reset
1665 dst_type to ensure that we continue to look for a possible
1666 conflict in the pending list. */
1667
1668 dst_type = CTF_ERR;
1669 }
1670 }
1671 }
1672
1673 /* If the non-empty name was not found in the appropriate hash, search
1674 the list of pending dynamic definitions that are not yet committed.
1675 If a matching name and kind are found, assume this is the type that
1676 we are looking for. This is necessary to permit ctf_add_type() to
1677 operate recursively on entities such as a struct that contains a
1678 pointer member that refers to the same struct type. */
1679
1680 if (dst_type == CTF_ERR && name[0] != '\0')
1681 {
1682 for (dtd = ctf_list_prev (&dst_fp->ctf_dtdefs); dtd != NULL
1683 && LCTF_TYPE_TO_INDEX (src_fp, dtd->dtd_type) > dst_fp->ctf_dtoldid;
1684 dtd = ctf_list_prev (dtd))
1685 {
1686 if (LCTF_INFO_KIND (src_fp, dtd->dtd_data.ctt_info) == kind
1687 && dtd->dtd_name != NULL && strcmp (dtd->dtd_name, name) == 0)
1688 {
1689 int sroot; /* Is the src root-visible? */
1690 int droot; /* Is the dst root-visible? */
1691 int match; /* Do the encodings match? */
1692
1693 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1694 return dtd->dtd_type;
1695
1696 sroot = (flag & CTF_ADD_ROOT);
1697 droot = (LCTF_INFO_ISROOT (dst_fp,
1698 dtd->dtd_data.
1699 ctt_info) & CTF_ADD_ROOT);
1700
1701 match = (memcmp (&src_en, &dtd->dtd_u.dtu_enc,
1702 sizeof (ctf_encoding_t)) == 0);
1703
1704 /* If the types share the same encoding then return the id of the
1705 first unless one type is root-visible and the other is not; in
1706 that case the new type must get a new id if a match is never
1707 found. Note: slices are not certain to match even if there is
1708 no conflict: we must check the contained type too. */
1709
1710 if (match && sroot == droot)
1711 {
1712 if (kind != CTF_K_SLICE)
1713 return dtd->dtd_type;
1714 }
1715 else if (!match && sroot && droot)
1716 {
1717 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1718 }
1719 }
1720 }
1721 }
1722
1723 src.ctb_file = src_fp;
1724 src.ctb_type = src_type;
1725 src.ctb_dtd = NULL;
1726
1727 dst.ctb_file = dst_fp;
1728 dst.ctb_type = dst_type;
1729 dst.ctb_dtd = NULL;
1730
1731 /* Now perform kind-specific processing. If dst_type is CTF_ERR, then
1732 we add a new type with the same properties as src_type to dst_fp.
1733 If dst_type is not CTF_ERR, then we verify that dst_type has the
1734 same attributes as src_type. We recurse for embedded references. */
1735 switch (kind)
1736 {
1737 case CTF_K_INTEGER:
1738 /* If we found a match we will have either returned it or declared a
1739 conflict. */
1740 dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1741 break;
1742
1743 case CTF_K_FLOAT:
1744 /* If we found a match we will have either returned it or declared a
1745 conflict. */
1746 dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1747 break;
1748
1749 case CTF_K_SLICE:
1750 /* We have checked for conflicting encodings: now try to add the
1751 contained type. */
1752 src_type = ctf_type_reference (src_fp, src_type);
1753 dst_type = ctf_add_type (dst_fp, src_fp, src_type);
1754
1755 if (src_type == CTF_ERR)
1756 return CTF_ERR; /* errno is set for us. */
1757
1758 dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1759 break;
1760
1761 case CTF_K_POINTER:
1762 case CTF_K_VOLATILE:
1763 case CTF_K_CONST:
1764 case CTF_K_RESTRICT:
1765 src_type = ctf_type_reference (src_fp, src_type);
1766 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1767
1768 if (src_type == CTF_ERR)
1769 return CTF_ERR; /* errno is set for us. */
1770
1771 dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1772 break;
1773
1774 case CTF_K_ARRAY:
a0486bac 1775 if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
c499eb68
NA
1776 return (ctf_set_errno (dst_fp, ctf_errno (src_fp)));
1777
1778 src_ar.ctr_contents =
1779 ctf_add_type (dst_fp, src_fp, src_ar.ctr_contents);
1780 src_ar.ctr_index = ctf_add_type (dst_fp, src_fp, src_ar.ctr_index);
1781 src_ar.ctr_nelems = src_ar.ctr_nelems;
1782
1783 if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1784 return CTF_ERR; /* errno is set for us. */
1785
1786 if (dst_type != CTF_ERR)
1787 {
1788 if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1789 return CTF_ERR; /* errno is set for us. */
1790
1791 if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1792 {
1793 ctf_dprintf ("Conflict for type %s against ID %lx: "
1794 "array info differs, old %lx/%lx/%x; "
1795 "new: %lx/%lx/%x\n", name, dst_type,
1796 src_ar.ctr_contents, src_ar.ctr_index,
1797 src_ar.ctr_nelems, dst_ar.ctr_contents,
1798 dst_ar.ctr_index, dst_ar.ctr_nelems);
1799 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1800 }
1801 }
1802 else
1803 dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1804 break;
1805
1806 case CTF_K_FUNCTION:
1807 ctc.ctc_return = ctf_add_type (dst_fp, src_fp, src_tp->ctt_type);
1808 ctc.ctc_argc = 0;
1809 ctc.ctc_flags = 0;
1810
1811 if (ctc.ctc_return == CTF_ERR)
1812 return CTF_ERR; /* errno is set for us. */
1813
1814 dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1815 break;
1816
1817 case CTF_K_STRUCT:
1818 case CTF_K_UNION:
1819 {
1820 ctf_dmdef_t *dmd;
1821 int errs = 0;
a0486bac
JM
1822 size_t size;
1823 ssize_t ssize;
c499eb68
NA
1824
1825 /* Technically to match a struct or union we need to check both
1826 ways (src members vs. dst, dst members vs. src) but we make
1827 this more optimal by only checking src vs. dst and comparing
1828 the total size of the structure (which we must do anyway)
1829 which covers the possibility of dst members not in src.
1830 This optimization can be defeated for unions, but is so
1831 pathological as to render it irrelevant for our purposes. */
1832
1833 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1834 {
1835 if (ctf_type_size (src_fp, src_type) !=
1836 ctf_type_size (dst_fp, dst_type))
1837 {
1838 ctf_dprintf ("Conflict for type %s against ID %lx: "
62d8e3b7
NA
1839 "union size differs, old %li, new %li\n",
1840 name, dst_type,
1841 (long) ctf_type_size (src_fp, src_type),
1842 (long) ctf_type_size (dst_fp, dst_type));
c499eb68
NA
1843 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1844 }
1845
1846 if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1847 {
1848 ctf_dprintf ("Conflict for type %s against ID %lx: "
1849 "members differ, see above\n", name, dst_type);
1850 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1851 }
1852
1853 break;
1854 }
1855
1856 /* Unlike the other cases, copying structs and unions is done
1857 manually so as to avoid repeated lookups in ctf_add_member
1858 and to ensure the exact same member offsets as in src_type. */
1859
1860 dst_type = ctf_add_generic (dst_fp, flag, name, &dtd);
1861 if (dst_type == CTF_ERR)
1862 return CTF_ERR; /* errno is set for us. */
1863
1864 dst.ctb_type = dst_type;
1865 dst.ctb_dtd = dtd;
1866
1867 if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0)
1868 errs++; /* Increment errs and fail at bottom of case. */
1869
a0486bac
JM
1870 if ((ssize = ctf_type_size (src_fp, src_type)) < 0)
1871 return CTF_ERR; /* errno is set for us. */
1872
1873 size = (size_t) ssize;
1874 if (size > CTF_MAX_SIZE)
c499eb68
NA
1875 {
1876 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1877 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
1878 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
1879 }
1880 else
1881 dtd->dtd_data.ctt_size = (uint32_t) size;
1882
1883 dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, vlen);
1884
1885 /* Make a final pass through the members changing each dmd_type (a
1886 src_fp type) to an equivalent type in dst_fp. We pass through all
1887 members, leaving any that fail set to CTF_ERR. */
1888 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1889 dmd != NULL; dmd = ctf_list_next (dmd))
1890 {
1891 if ((dmd->dmd_type = ctf_add_type (dst_fp, src_fp,
1892 dmd->dmd_type)) == CTF_ERR)
1893 errs++;
1894 }
1895
1896 if (errs)
1897 return CTF_ERR; /* errno is set for us. */
1898 break;
1899 }
1900
1901 case CTF_K_ENUM:
1902 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD)
1903 {
1904 if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
1905 || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
1906 {
1907 ctf_dprintf ("Conflict for enum %s against ID %lx: "
1908 "members differ, see above\n", name, dst_type);
1909 return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1910 }
1911 }
1912 else
1913 {
1914 dst_type = ctf_add_enum (dst_fp, flag, name);
1915 if ((dst.ctb_type = dst_type) == CTF_ERR
1916 || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
1917 return CTF_ERR; /* errno is set for us */
1918 }
1919 break;
1920
1921 case CTF_K_FORWARD:
1922 if (dst_type == CTF_ERR)
1923 {
1924 dst_type = ctf_add_forward (dst_fp, flag,
1925 name, CTF_K_STRUCT); /* Assume STRUCT. */
1926 }
1927 break;
1928
1929 case CTF_K_TYPEDEF:
1930 src_type = ctf_type_reference (src_fp, src_type);
1931 src_type = ctf_add_type (dst_fp, src_fp, src_type);
1932
1933 if (src_type == CTF_ERR)
1934 return CTF_ERR; /* errno is set for us. */
1935
1936 /* If dst_type is not CTF_ERR at this point, we should check if
1937 ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
1938 ECTF_CONFLICT. However, this causes problems with bitness typedefs
1939 that vary based on things like if 32-bit then pid_t is int otherwise
1940 long. We therefore omit this check and assume that if the identically
1941 named typedef already exists in dst_fp, it is correct or
1942 equivalent. */
1943
1944 if (dst_type == CTF_ERR)
1945 {
1946 dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
1947 }
1948 break;
1949
1950 default:
1951 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
1952 }
1953
1954 return dst_type;
1955}
1956
47d546f4
NA
1957/* Write the compressed CTF data stream to the specified gzFile descriptor.
1958 This is useful for saving the results of dynamic CTF containers. */
1959int
1960ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1961{
1962 const unsigned char *buf = fp->ctf_base;
1963 ssize_t resid = fp->ctf_size;
1964 ssize_t len;
1965
1966 while (resid != 0)
1967 {
1968 if ((len = gzwrite (fd, buf, resid)) <= 0)
1969 return (ctf_set_errno (fp, errno));
1970 resid -= len;
1971 buf += len;
1972 }
1973
1974 return 0;
1975}
1976
1977/* Compress the specified CTF data stream and write it to the specified file
1978 descriptor. */
1979int
1980ctf_compress_write (ctf_file_t *fp, int fd)
1981{
1982 unsigned char *buf;
1983 unsigned char *bp;
1984 ctf_header_t h;
1985 ctf_header_t *hp = &h;
1986 ssize_t header_len = sizeof (ctf_header_t);
1987 ssize_t compress_len;
1988 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1989 ssize_t len;
1990 int rc;
1991 int err = 0;
1992
1993 memcpy (hp, fp->ctf_base, header_len);
1994 hp->cth_flags |= CTF_F_COMPRESS;
1995
1996 if ((buf = ctf_data_alloc (max_compress_len)) == NULL)
1997 return (ctf_set_errno (fp, ECTF_ZALLOC));
1998
1999 compress_len = max_compress_len;
2000 if ((rc = compress (buf, (uLongf *) & compress_len,
2001 fp->ctf_base + header_len,
2002 fp->ctf_size - header_len)) != Z_OK)
2003 {
2004 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2005 err = ctf_set_errno (fp, ECTF_COMPRESS);
2006 goto ret;
2007 }
2008
2009 while (header_len > 0)
2010 {
2011 if ((len = write (fd, hp, header_len)) < 0)
2012 {
2013 err = ctf_set_errno (fp, errno);
2014 goto ret;
2015 }
2016 header_len -= len;
2017 hp += len;
2018 }
2019
2020 bp = buf;
2021 while (compress_len > 0)
2022 {
2023 if ((len = write (fd, bp, compress_len)) < 0)
2024 {
2025 err = ctf_set_errno (fp, errno);
2026 goto ret;
2027 }
2028 compress_len -= len;
2029 bp += len;
2030 }
2031
2032ret:
2033 ctf_data_free (buf, max_compress_len);
2034 return err;
2035}
2036
2037/* Write the uncompressed CTF data stream to the specified file descriptor.
2038 This is useful for saving the results of dynamic CTF containers. */
2039int
2040ctf_write (ctf_file_t *fp, int fd)
2041{
2042 const unsigned char *buf = fp->ctf_base;
2043 ssize_t resid = fp->ctf_size;
2044 ssize_t len;
2045
2046 while (resid != 0)
2047 {
2048 if ((len = write (fd, buf, resid)) < 0)
2049 return (ctf_set_errno (fp, errno));
2050 resid -= len;
2051 buf += len;
2052 }
2053
2054 return 0;
2055}
This page took 0.102554 seconds and 4 git commands to generate.