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