libctf: lookups by name and symbol
[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
1449/* Write the compressed CTF data stream to the specified gzFile descriptor.
1450 This is useful for saving the results of dynamic CTF containers. */
1451int
1452ctf_gzwrite (ctf_file_t *fp, gzFile fd)
1453{
1454 const unsigned char *buf = fp->ctf_base;
1455 ssize_t resid = fp->ctf_size;
1456 ssize_t len;
1457
1458 while (resid != 0)
1459 {
1460 if ((len = gzwrite (fd, buf, resid)) <= 0)
1461 return (ctf_set_errno (fp, errno));
1462 resid -= len;
1463 buf += len;
1464 }
1465
1466 return 0;
1467}
1468
1469/* Compress the specified CTF data stream and write it to the specified file
1470 descriptor. */
1471int
1472ctf_compress_write (ctf_file_t *fp, int fd)
1473{
1474 unsigned char *buf;
1475 unsigned char *bp;
1476 ctf_header_t h;
1477 ctf_header_t *hp = &h;
1478 ssize_t header_len = sizeof (ctf_header_t);
1479 ssize_t compress_len;
1480 size_t max_compress_len = compressBound (fp->ctf_size - header_len);
1481 ssize_t len;
1482 int rc;
1483 int err = 0;
1484
1485 memcpy (hp, fp->ctf_base, header_len);
1486 hp->cth_flags |= CTF_F_COMPRESS;
1487
1488 if ((buf = ctf_data_alloc (max_compress_len)) == NULL)
1489 return (ctf_set_errno (fp, ECTF_ZALLOC));
1490
1491 compress_len = max_compress_len;
1492 if ((rc = compress (buf, (uLongf *) & compress_len,
1493 fp->ctf_base + header_len,
1494 fp->ctf_size - header_len)) != Z_OK)
1495 {
1496 ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
1497 err = ctf_set_errno (fp, ECTF_COMPRESS);
1498 goto ret;
1499 }
1500
1501 while (header_len > 0)
1502 {
1503 if ((len = write (fd, hp, header_len)) < 0)
1504 {
1505 err = ctf_set_errno (fp, errno);
1506 goto ret;
1507 }
1508 header_len -= len;
1509 hp += len;
1510 }
1511
1512 bp = buf;
1513 while (compress_len > 0)
1514 {
1515 if ((len = write (fd, bp, compress_len)) < 0)
1516 {
1517 err = ctf_set_errno (fp, errno);
1518 goto ret;
1519 }
1520 compress_len -= len;
1521 bp += len;
1522 }
1523
1524ret:
1525 ctf_data_free (buf, max_compress_len);
1526 return err;
1527}
1528
1529/* Write the uncompressed CTF data stream to the specified file descriptor.
1530 This is useful for saving the results of dynamic CTF containers. */
1531int
1532ctf_write (ctf_file_t *fp, int fd)
1533{
1534 const unsigned char *buf = fp->ctf_base;
1535 ssize_t resid = fp->ctf_size;
1536 ssize_t len;
1537
1538 while (resid != 0)
1539 {
1540 if ((len = write (fd, buf, resid)) < 0)
1541 return (ctf_set_errno (fp, errno));
1542 resid -= len;
1543 buf += len;
1544 }
1545
1546 return 0;
1547}
This page took 0.077359 seconds and 4 git commands to generate.