Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/libctf/ctf-create.c
Line
Count
Source (jump to first uncovered line)
1
/* CTF dict creation.
2
   Copyright (C) 2019-2025 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 <string.h>
22
#include <unistd.h>
23
24
#ifndef EOVERFLOW
25
#define EOVERFLOW ERANGE
26
#endif
27
28
#ifndef roundup
29
0
#define roundup(x, y)  ((((x) + ((y) - 1)) / (y)) * (y))
30
#endif
31
32
/* The initial size of a dynamic type's vlen in members.  Arbitrary: the bigger
33
   this is, the less allocation needs to be done for small structure
34
   initialization, and the more memory is wasted for small structures during CTF
35
   construction.  No effect on generated CTF or ctf_open()ed CTF. */
36
0
#define INITIAL_VLEN 16
37
38
/* Make sure the ptrtab has enough space for at least one more type.
39
40
   We start with 4KiB of ptrtab, enough for a thousand types, then grow it 25%
41
   at a time.  */
42
43
static int
44
ctf_grow_ptrtab (ctf_dict_t *fp)
45
0
{
46
0
  size_t new_ptrtab_len = fp->ctf_ptrtab_len;
47
48
  /* We allocate one more ptrtab entry than we need, for the initial zero,
49
     plus one because the caller will probably allocate a new type.
50
51
     Equally, if the ptrtab is small -- perhaps due to ctf_open of a small
52
     dict -- boost it by quite a lot at first, so we don't need to keep
53
     realloc()ing.  */
54
55
0
  if (fp->ctf_ptrtab == NULL || fp->ctf_ptrtab_len < 1024)
56
0
    new_ptrtab_len = 1024;
57
0
  else if ((fp->ctf_typemax + 2) > fp->ctf_ptrtab_len)
58
0
    new_ptrtab_len = fp->ctf_ptrtab_len * 1.25;
59
60
0
  if (new_ptrtab_len != fp->ctf_ptrtab_len)
61
0
    {
62
0
      uint32_t *new_ptrtab;
63
64
0
      if ((new_ptrtab = realloc (fp->ctf_ptrtab,
65
0
         new_ptrtab_len * sizeof (uint32_t))) == NULL)
66
0
  return (ctf_set_errno (fp, ENOMEM));
67
68
0
      fp->ctf_ptrtab = new_ptrtab;
69
0
      memset (fp->ctf_ptrtab + fp->ctf_ptrtab_len, 0,
70
0
        (new_ptrtab_len - fp->ctf_ptrtab_len) * sizeof (uint32_t));
71
0
      fp->ctf_ptrtab_len = new_ptrtab_len;
72
0
    }
73
0
  return 0;
74
0
}
75
76
/* Make sure a vlen has enough space: expand it otherwise.  Unlike the ptrtab,
77
   which grows quite slowly, the vlen grows in big jumps because it is quite
78
   expensive to expand: the caller has to scan the old vlen for string refs
79
   first and remove them, then re-add them afterwards.  The initial size is
80
   more or less arbitrary.  */
81
static int
82
ctf_grow_vlen (ctf_dict_t *fp, ctf_dtdef_t *dtd, size_t vlen)
83
0
{
84
0
  unsigned char *old = dtd->dtd_vlen;
85
86
0
  if (dtd->dtd_vlen_alloc > vlen)
87
0
    return 0;
88
89
0
  if ((dtd->dtd_vlen = realloc (dtd->dtd_vlen,
90
0
        dtd->dtd_vlen_alloc * 2)) == NULL)
91
0
    {
92
0
      dtd->dtd_vlen = old;
93
0
      return (ctf_set_errno (fp, ENOMEM));
94
0
    }
95
0
  memset (dtd->dtd_vlen + dtd->dtd_vlen_alloc, 0, dtd->dtd_vlen_alloc);
96
0
  dtd->dtd_vlen_alloc *= 2;
97
0
  return 0;
98
0
}
99
100
/* To create an empty CTF dict, we just declare a zeroed header and call
101
   ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new dict r/w and
102
   initialize the dynamic members.  We start assigning type IDs at 1 because
103
   type ID 0 is used as a sentinel and a not-found indicator.  */
104
105
ctf_dict_t *
106
ctf_create (int *errp)
107
0
{
108
0
  static const ctf_header_t hdr = { .cth_preamble = { CTF_MAGIC, CTF_VERSION, 0 } };
109
110
0
  ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL;
111
0
  ctf_sect_t cts;
112
0
  ctf_dict_t *fp;
113
114
0
  libctf_init_debug();
115
116
0
  structs = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
117
0
        NULL, NULL);
118
0
  unions = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
119
0
             NULL, NULL);
120
0
  enums = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
121
0
            NULL, NULL);
122
0
  names = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
123
0
            NULL, NULL);
124
0
  if (!structs || !unions || !enums || !names)
125
0
    {
126
0
      ctf_set_open_errno (errp, EAGAIN);
127
0
      goto err;
128
0
    }
129
130
0
  cts.cts_name = _CTF_SECTION;
131
0
  cts.cts_data = &hdr;
132
0
  cts.cts_size = sizeof (hdr);
133
0
  cts.cts_entsize = 1;
134
135
0
  if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
136
0
    goto err;
137
138
  /* These hashes will have been initialized with a starting size of zero,
139
     which is surely wrong.  Use ones with slightly larger sizes.  */
140
0
  ctf_dynhash_destroy (fp->ctf_structs);
141
0
  ctf_dynhash_destroy (fp->ctf_unions);
142
0
  ctf_dynhash_destroy (fp->ctf_enums);
143
0
  ctf_dynhash_destroy (fp->ctf_names);
144
0
  fp->ctf_structs = structs;
145
0
  fp->ctf_unions = unions;
146
0
  fp->ctf_enums = enums;
147
0
  fp->ctf_names = names;
148
0
  fp->ctf_dtoldid = 0;
149
0
  fp->ctf_snapshot_lu = 0;
150
151
  /* Make sure the ptrtab starts out at a reasonable size.  */
152
153
0
  ctf_set_ctl_hashes (fp);
154
0
  if (ctf_grow_ptrtab (fp) < 0)
155
0
    {
156
0
      ctf_set_open_errno (errp, ctf_errno (fp));
157
0
      ctf_dict_close (fp);
158
0
      return NULL;
159
0
    }
160
161
0
  return fp;
162
163
0
 err:
164
0
  ctf_dynhash_destroy (structs);
165
0
  ctf_dynhash_destroy (unions);
166
0
  ctf_dynhash_destroy (enums);
167
0
  ctf_dynhash_destroy (names);
168
0
  return NULL;
169
0
}
170
171
/* Compatibility: just update the threshold for ctf_discard.  */
172
int
173
ctf_update (ctf_dict_t *fp)
174
0
{
175
0
  fp->ctf_dtoldid = fp->ctf_typemax;
176
0
  return 0;
177
0
}
178
179
ctf_dynhash_t *
180
ctf_name_table (ctf_dict_t *fp, int kind)
181
0
{
182
0
  switch (kind)
183
0
    {
184
0
    case CTF_K_STRUCT:
185
0
      return fp->ctf_structs;
186
0
    case CTF_K_UNION:
187
0
      return fp->ctf_unions;
188
0
    case CTF_K_ENUM:
189
0
      return fp->ctf_enums;
190
0
    default:
191
0
      return fp->ctf_names;
192
0
    }
193
0
}
194
195
int
196
ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
197
0
{
198
0
  const char *name;
199
0
  if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
200
0
        dtd) < 0)
201
0
    return ctf_set_errno (fp, ENOMEM);
202
203
0
  if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
204
0
      && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
205
0
    {
206
0
      if (ctf_dynhash_insert (ctf_name_table (fp, kind),
207
0
            (char *) name, (void *) (uintptr_t)
208
0
            dtd->dtd_type) < 0)
209
0
  {
210
0
    ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
211
0
            dtd->dtd_type);
212
0
    return ctf_set_errno (fp, ENOMEM);
213
0
  }
214
0
    }
215
0
  ctf_list_append (&fp->ctf_dtdefs, dtd);
216
0
  return 0;
217
0
}
218
219
void
220
ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
221
0
{
222
0
  int kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
223
0
  size_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
224
0
  int name_kind = kind;
225
0
  const char *name;
226
227
0
  ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
228
229
0
  switch (kind)
230
0
    {
231
0
    case CTF_K_STRUCT:
232
0
    case CTF_K_UNION:
233
0
      {
234
0
  ctf_lmember_t *memb = (ctf_lmember_t *) dtd->dtd_vlen;
235
0
  size_t i;
236
237
0
  for (i = 0; i < vlen; i++)
238
0
    ctf_str_remove_ref (fp, ctf_strraw (fp, memb[i].ctlm_name),
239
0
            &memb[i].ctlm_name);
240
0
      }
241
0
      break;
242
0
    case CTF_K_ENUM:
243
0
      {
244
0
  ctf_enum_t *en = (ctf_enum_t *) dtd->dtd_vlen;
245
0
  size_t i;
246
247
0
  for (i = 0; i < vlen; i++)
248
0
    ctf_str_remove_ref (fp, ctf_strraw (fp, en[i].cte_name),
249
0
            &en[i].cte_name);
250
0
      }
251
0
      break;
252
0
    case CTF_K_FORWARD:
253
0
      name_kind = dtd->dtd_data.ctt_type;
254
0
      break;
255
0
    }
256
0
  free (dtd->dtd_vlen);
257
0
  dtd->dtd_vlen_alloc = 0;
258
259
0
  if (dtd->dtd_data.ctt_name
260
0
      && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
261
0
    {
262
0
      if (LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
263
0
  ctf_dynhash_remove (ctf_name_table (fp, name_kind), name);
264
0
      ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
265
0
    }
266
267
0
  ctf_list_delete (&fp->ctf_dtdefs, dtd);
268
0
  free (dtd);
269
0
}
270
271
ctf_dtdef_t *
272
ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
273
0
{
274
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
275
0
    fp = fp->ctf_parent;
276
277
0
  return (ctf_dtdef_t *)
278
0
    ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
279
0
}
280
281
ctf_dtdef_t *
282
ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
283
0
{
284
0
  ctf_id_t idx;
285
286
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
287
0
    fp = fp->ctf_parent;
288
289
0
  idx = LCTF_TYPE_TO_INDEX(fp, id);
290
291
0
  if ((unsigned long) idx <= fp->ctf_typemax)
292
0
    return ctf_dtd_lookup (fp, id);
293
0
  return NULL;
294
0
}
295
296
static int
297
ctf_static_type (const ctf_dict_t *fp, ctf_id_t id)
298
0
{
299
0
  ctf_id_t idx;
300
301
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id))
302
0
    fp = fp->ctf_parent;
303
304
0
  idx = LCTF_TYPE_TO_INDEX(fp, id);
305
306
0
  return ((unsigned long) idx <= fp->ctf_stypes);
307
0
}
308
309
int
310
ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
311
0
{
312
0
  if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
313
0
    return ctf_set_errno (fp, ENOMEM);
314
0
  ctf_list_append (&fp->ctf_dvdefs, dvd);
315
0
  return 0;
316
0
}
317
318
void
319
ctf_dvd_delete (ctf_dict_t *fp, ctf_dvdef_t *dvd)
320
0
{
321
0
  ctf_dynhash_remove (fp->ctf_dvhash, dvd->dvd_name);
322
0
  free (dvd->dvd_name);
323
324
0
  ctf_list_delete (&fp->ctf_dvdefs, dvd);
325
0
  free (dvd);
326
0
}
327
328
ctf_dvdef_t *
329
ctf_dvd_lookup (const ctf_dict_t *fp, const char *name)
330
0
{
331
0
  return (ctf_dvdef_t *) ctf_dynhash_lookup (fp->ctf_dvhash, name);
332
0
}
333
334
/* Discard all of the dynamic type definitions and variable definitions that
335
   have been added to the dict since the last call to ctf_update().  We locate
336
   such types by scanning the dtd list and deleting elements that have type IDs
337
   greater than ctf_dtoldid, which is set by ctf_update(), above, and by
338
   scanning the variable list and deleting elements that have update IDs equal
339
   to the current value of the last-update snapshot count (indicating that they
340
   were added after the most recent call to ctf_update()).  */
341
int
342
ctf_discard (ctf_dict_t *fp)
343
0
{
344
0
  ctf_snapshot_id_t last_update =
345
0
    { fp->ctf_dtoldid,
346
0
      fp->ctf_snapshot_lu + 1 };
347
348
0
  return (ctf_rollback (fp, last_update));
349
0
}
350
351
ctf_snapshot_id_t
352
ctf_snapshot (ctf_dict_t *fp)
353
0
{
354
0
  ctf_snapshot_id_t snapid;
355
0
  snapid.dtd_id = fp->ctf_typemax;
356
0
  snapid.snapshot_id = fp->ctf_snapshots++;
357
0
  return snapid;
358
0
}
359
360
/* Like ctf_discard(), only discards everything after a particular ID.  */
361
int
362
ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
363
0
{
364
0
  ctf_dtdef_t *dtd, *ntd;
365
0
  ctf_dvdef_t *dvd, *nvd;
366
367
0
  if (id.snapshot_id < fp->ctf_stypes)
368
0
    return (ctf_set_errno (fp, ECTF_RDONLY));
369
370
0
  if (fp->ctf_snapshot_lu >= id.snapshot_id)
371
0
    return (ctf_set_errno (fp, ECTF_OVERROLLBACK));
372
373
0
  for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
374
0
    {
375
0
      int kind;
376
0
      const char *name;
377
378
0
      ntd = ctf_list_next (dtd);
379
380
0
      if (LCTF_TYPE_TO_INDEX (fp, dtd->dtd_type) <= id.dtd_id)
381
0
  continue;
382
383
0
      kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
384
0
      if (kind == CTF_K_FORWARD)
385
0
  kind = dtd->dtd_data.ctt_type;
386
387
0
      if (dtd->dtd_data.ctt_name
388
0
    && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
389
0
    && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
390
0
  {
391
0
    ctf_dynhash_remove (ctf_name_table (fp, kind), name);
392
0
    ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
393
0
  }
394
395
0
      ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
396
0
      ctf_dtd_delete (fp, dtd);
397
0
    }
398
399
0
  for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
400
0
    {
401
0
      nvd = ctf_list_next (dvd);
402
403
0
      if (dvd->dvd_snapshots <= id.snapshot_id)
404
0
  continue;
405
406
0
      ctf_dvd_delete (fp, dvd);
407
0
    }
408
409
0
  fp->ctf_typemax = id.dtd_id;
410
0
  fp->ctf_snapshots = id.snapshot_id;
411
412
0
  return 0;
413
0
}
414
415
/* Note: vlen is the amount of space *allocated* for the vlen.  It may well not
416
   be the amount of space used (yet): the space used is declared in per-kind
417
   fashion in the dtd_data's info word.  */
418
static ctf_id_t
419
ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
420
     size_t vlen, ctf_dtdef_t **rp)
421
0
{
422
0
  ctf_dtdef_t *dtd;
423
0
  ctf_id_t type;
424
425
0
  if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
426
0
    return (ctf_set_typed_errno (fp, EINVAL));
427
428
0
  if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) >= CTF_MAX_TYPE)
429
0
    return (ctf_set_typed_errno (fp, ECTF_FULL));
430
431
0
  if (LCTF_INDEX_TO_TYPE (fp, fp->ctf_typemax, 1) == (CTF_MAX_PTYPE - 1))
432
0
    return (ctf_set_typed_errno (fp, ECTF_FULL));
433
434
  /* Prohibit addition of a root-visible type that is already present
435
     in the non-dynamic portion. */
436
437
0
  if (flag == CTF_ADD_ROOT && name != NULL && name[0] != '\0')
438
0
    {
439
0
      ctf_id_t existing;
440
441
0
      if (((existing = ctf_dynhash_lookup_type (ctf_name_table (fp, kind),
442
0
            name)) > 0)
443
0
    && ctf_static_type (fp, existing))
444
0
  return (ctf_set_typed_errno (fp, ECTF_RDONLY));
445
0
    }
446
447
  /* Make sure ptrtab always grows to be big enough for all types.  */
448
0
  if (ctf_grow_ptrtab (fp) < 0)
449
0
      return CTF_ERR;       /* errno is set for us. */
450
451
0
  if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
452
0
    return (ctf_set_typed_errno (fp, EAGAIN));
453
454
0
  dtd->dtd_vlen_alloc = vlen;
455
0
  if (vlen > 0)
456
0
    {
457
0
      if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
458
0
  goto oom;
459
0
    }
460
0
  else
461
0
    dtd->dtd_vlen = NULL;
462
463
0
  type = ++fp->ctf_typemax;
464
0
  type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
465
466
0
  dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
467
0
  dtd->dtd_type = type;
468
469
0
  if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
470
0
    goto oom;
471
472
0
  if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
473
0
    goto err;         /* errno is set for us.  */
474
475
0
  *rp = dtd;
476
0
  return type;
477
478
0
 oom:
479
0
  ctf_set_errno (fp, EAGAIN);
480
0
 err:
481
0
  free (dtd->dtd_vlen);
482
0
  free (dtd);
483
0
  return CTF_ERR;
484
0
}
485
486
/* When encoding integer sizes, we want to convert a byte count in the range
487
   1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc).  The clp2() function
488
   is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.  */
489
static size_t
490
clp2 (size_t x)
491
0
{
492
0
  x--;
493
494
0
  x |= (x >> 1);
495
0
  x |= (x >> 2);
496
0
  x |= (x >> 4);
497
0
  x |= (x >> 8);
498
0
  x |= (x >> 16);
499
500
0
  return (x + 1);
501
0
}
502
503
ctf_id_t
504
ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
505
     const char *name, const ctf_encoding_t *ep, uint32_t kind)
506
0
{
507
0
  ctf_dtdef_t *dtd;
508
0
  ctf_id_t type;
509
0
  uint32_t encoding;
510
511
0
  if (ep == NULL)
512
0
    return (ctf_set_typed_errno (fp, EINVAL));
513
514
0
  if (name == NULL || name[0] == '\0')
515
0
    return (ctf_set_typed_errno (fp, ECTF_NONAME));
516
517
0
  if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
518
0
    return CTF_ERR;         /* errno is set for us.  */
519
520
0
  if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
521
0
             &dtd)) == CTF_ERR)
522
0
    return CTF_ERR;   /* errno is set for us.  */
523
524
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
525
0
  dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
526
0
         / CHAR_BIT);
527
0
  switch (kind)
528
0
    {
529
0
    case CTF_K_INTEGER:
530
0
      encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
531
0
      break;
532
0
    case CTF_K_FLOAT:
533
0
      encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
534
0
      break;
535
0
    default:
536
      /* ctf_assert is opaque with -fno-inline.  This dead code avoids
537
   a warning about "encoding" being used uninitialized.  */
538
0
      return CTF_ERR;
539
0
    }
540
0
  memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
541
542
0
  return type;
543
0
}
544
545
ctf_id_t
546
ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
547
0
{
548
0
  ctf_dtdef_t *dtd;
549
0
  ctf_id_t type;
550
0
  ctf_dict_t *tmp = fp;
551
0
  int child = fp->ctf_flags & LCTF_CHILD;
552
553
0
  if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
554
0
    return (ctf_set_typed_errno (fp, EINVAL));
555
556
0
  if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
557
0
    return CTF_ERR;   /* errno is set for us.  */
558
559
0
  if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
560
0
    return CTF_ERR;   /* errno is set for us.  */
561
562
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
563
0
  dtd->dtd_data.ctt_type = (uint32_t) ref;
564
565
0
  if (kind != CTF_K_POINTER)
566
0
    return type;
567
568
  /* If we are adding a pointer, update the ptrtab, pointing at this type from
569
     the type it points to.  Note that ctf_typemax is at this point one higher
570
     than we want to check against, because it's just been incremented for the
571
     addition of this type.  The pptrtab is lazily-updated as needed, so is not
572
     touched here.  */
573
574
0
  uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
575
0
  uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
576
577
0
  if (LCTF_TYPE_ISCHILD (fp, ref) == child
578
0
      && ref_idx < fp->ctf_typemax)
579
0
    fp->ctf_ptrtab[ref_idx] = type_idx;
580
581
0
  return type;
582
0
}
583
584
ctf_id_t
585
ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
586
         const ctf_encoding_t *ep)
587
0
{
588
0
  ctf_dtdef_t *dtd;
589
0
  ctf_slice_t slice;
590
0
  ctf_id_t resolved_ref = ref;
591
0
  ctf_id_t type;
592
0
  int kind;
593
0
  const ctf_type_t *tp;
594
0
  ctf_dict_t *tmp = fp;
595
596
0
  if (ep == NULL)
597
0
    return (ctf_set_typed_errno (fp, EINVAL));
598
599
0
  if ((ep->cte_bits > 255) || (ep->cte_offset > 255))
600
0
    return (ctf_set_typed_errno (fp, ECTF_SLICEOVERFLOW));
601
602
0
  if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
603
0
    return (ctf_set_typed_errno (fp, EINVAL));
604
605
0
  if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
606
0
    return CTF_ERR;   /* errno is set for us.  */
607
608
  /* Make sure we ultimately point to an integral type.  We also allow slices to
609
     point to the unimplemented type, for now, because the compiler can emit
610
     such slices, though they're not very much use.  */
611
612
0
  resolved_ref = ctf_type_resolve_unsliced (fp, ref);
613
0
  kind = ctf_type_kind_unsliced (fp, resolved_ref);
614
615
0
  if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
616
0
      (kind != CTF_K_ENUM)
617
0
      && (ref != 0))
618
0
    return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
619
620
0
  if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
621
0
             sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
622
0
    return CTF_ERR;   /* errno is set for us.  */
623
624
0
  memset (&slice, 0, sizeof (ctf_slice_t));
625
626
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
627
0
  dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
628
0
         / CHAR_BIT);
629
0
  slice.cts_type = (uint32_t) ref;
630
0
  slice.cts_bits = ep->cte_bits;
631
0
  slice.cts_offset = ep->cte_offset;
632
0
  memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
633
634
0
  return type;
635
0
}
636
637
ctf_id_t
638
ctf_add_integer (ctf_dict_t *fp, uint32_t flag,
639
     const char *name, const ctf_encoding_t *ep)
640
0
{
641
0
  return (ctf_add_encoded (fp, flag, name, ep, CTF_K_INTEGER));
642
0
}
643
644
ctf_id_t
645
ctf_add_float (ctf_dict_t *fp, uint32_t flag,
646
         const char *name, const ctf_encoding_t *ep)
647
0
{
648
0
  return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
649
0
}
650
651
ctf_id_t
652
ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
653
0
{
654
0
  return (ctf_add_reftype (fp, flag, ref, CTF_K_POINTER));
655
0
}
656
657
ctf_id_t
658
ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
659
0
{
660
0
  ctf_dtdef_t *dtd;
661
0
  ctf_array_t cta;
662
0
  ctf_id_t type;
663
0
  ctf_dict_t *tmp = fp;
664
665
0
  if (arp == NULL)
666
0
    return (ctf_set_typed_errno (fp, EINVAL));
667
668
0
  if (arp->ctr_contents != 0
669
0
      && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL)
670
0
    return CTF_ERR;   /* errno is set for us.  */
671
672
0
  tmp = fp;
673
0
  if (ctf_lookup_by_id (&tmp, arp->ctr_index) == NULL)
674
0
    return CTF_ERR;   /* errno is set for us.  */
675
676
0
  if (ctf_type_kind (fp, arp->ctr_index) == CTF_K_FORWARD)
677
0
    {
678
0
      ctf_err_warn (fp, 1, ECTF_INCOMPLETE,
679
0
        _("ctf_add_array: index type %lx is incomplete"),
680
0
        arp->ctr_contents);
681
0
      return (ctf_set_typed_errno (fp, ECTF_INCOMPLETE));
682
0
    }
683
684
0
  if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
685
0
             sizeof (ctf_array_t), &dtd)) == CTF_ERR)
686
0
    return CTF_ERR;   /* errno is set for us.  */
687
688
0
  memset (&cta, 0, sizeof (ctf_array_t));
689
690
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
691
0
  dtd->dtd_data.ctt_size = 0;
692
0
  cta.cta_contents = (uint32_t) arp->ctr_contents;
693
0
  cta.cta_index = (uint32_t) arp->ctr_index;
694
0
  cta.cta_nelems = arp->ctr_nelems;
695
0
  memcpy (dtd->dtd_vlen, &cta, sizeof (ctf_array_t));
696
697
0
  return type;
698
0
}
699
700
int
701
ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
702
0
{
703
0
  ctf_dict_t *ofp = fp;
704
0
  ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
705
0
  ctf_array_t *vlen;
706
707
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
708
0
    fp = fp->ctf_parent;
709
710
  /* You can only call ctf_set_array on a type you have added, not a
711
     type that was read in via ctf_open().  */
712
0
  if (type < fp->ctf_stypes)
713
0
    return (ctf_set_errno (ofp, ECTF_RDONLY));
714
715
0
  if (dtd == NULL
716
0
      || LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
717
0
    return (ctf_set_errno (ofp, ECTF_BADID));
718
719
0
  vlen = (ctf_array_t *) dtd->dtd_vlen;
720
0
  vlen->cta_contents = (uint32_t) arp->ctr_contents;
721
0
  vlen->cta_index = (uint32_t) arp->ctr_index;
722
0
  vlen->cta_nelems = arp->ctr_nelems;
723
724
0
  return 0;
725
0
}
726
727
ctf_id_t
728
ctf_add_function (ctf_dict_t *fp, uint32_t flag,
729
      const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
730
0
{
731
0
  ctf_dtdef_t *dtd;
732
0
  ctf_id_t type;
733
0
  uint32_t vlen;
734
0
  uint32_t *vdat;
735
0
  ctf_dict_t *tmp = fp;
736
0
  size_t initial_vlen;
737
0
  size_t i;
738
739
0
  if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
740
0
      || (ctc->ctc_argc != 0 && argv == NULL))
741
0
    return (ctf_set_typed_errno (fp, EINVAL));
742
743
0
  vlen = ctc->ctc_argc;
744
0
  if (ctc->ctc_flags & CTF_FUNC_VARARG)
745
0
    vlen++;        /* Add trailing zero to indicate varargs (see below).  */
746
747
0
  if (ctc->ctc_return != 0
748
0
      && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
749
0
    return CTF_ERR;       /* errno is set for us.  */
750
751
0
  if (vlen > CTF_MAX_VLEN)
752
0
    return (ctf_set_typed_errno (fp, EOVERFLOW));
753
754
  /* One word extra allocated for padding for 4-byte alignment if need be.
755
     Not reflected in vlen: we don't want to copy anything into it, and
756
     it's in addition to (e.g.) the trailing 0 indicating varargs.  */
757
758
0
  initial_vlen = (sizeof (uint32_t) * (vlen + (vlen & 1)));
759
0
  if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
760
0
             initial_vlen, &dtd)) == CTF_ERR)
761
0
    return CTF_ERR;       /* errno is set for us.  */
762
763
0
  vdat = (uint32_t *) dtd->dtd_vlen;
764
765
0
  for (i = 0; i < ctc->ctc_argc; i++)
766
0
    {
767
0
      tmp = fp;
768
0
      if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
769
0
  return CTF_ERR;       /* errno is set for us.  */
770
0
      vdat[i] = (uint32_t) argv[i];
771
0
    }
772
773
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
774
0
  dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
775
776
0
  if (ctc->ctc_flags & CTF_FUNC_VARARG)
777
0
    vdat[vlen - 1] = 0;      /* Add trailing zero to indicate varargs.  */
778
779
0
  return type;
780
0
}
781
782
ctf_id_t
783
ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
784
          size_t size)
785
0
{
786
0
  ctf_dtdef_t *dtd;
787
0
  ctf_id_t type = 0;
788
0
  size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
789
790
  /* Promote root-visible forwards to structs.  */
791
0
  if (name != NULL)
792
0
    type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name);
793
794
  /* Prohibit promotion if this type was ctf_open()ed.  */
795
0
  if (type > 0 && type < fp->ctf_stypes)
796
0
    return (ctf_set_errno (fp, ECTF_RDONLY));
797
798
0
  if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
799
0
    dtd = ctf_dtd_lookup (fp, type);
800
0
  else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
801
0
            initial_vlen, &dtd)) == CTF_ERR)
802
0
    return CTF_ERR;   /* errno is set for us.  */
803
804
  /* Forwards won't have any vlen yet.  */
805
0
  if (dtd->dtd_vlen_alloc == 0)
806
0
    {
807
0
      if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
808
0
  return (ctf_set_typed_errno (fp, ENOMEM));
809
0
      dtd->dtd_vlen_alloc = initial_vlen;
810
0
    }
811
812
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
813
0
  dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
814
0
  dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
815
0
  dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
816
817
0
  return type;
818
0
}
819
820
ctf_id_t
821
ctf_add_struct (ctf_dict_t *fp, uint32_t flag, const char *name)
822
0
{
823
0
  return (ctf_add_struct_sized (fp, flag, name, 0));
824
0
}
825
826
ctf_id_t
827
ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
828
         size_t size)
829
0
{
830
0
  ctf_dtdef_t *dtd;
831
0
  ctf_id_t type = 0;
832
0
  size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN;
833
834
  /* Promote root-visible forwards to unions.  */
835
0
  if (name != NULL)
836
0
    type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name);
837
838
  /* Prohibit promotion if this type was ctf_open()ed.  */
839
0
  if (type > 0 && type < fp->ctf_stypes)
840
0
    return (ctf_set_errno (fp, ECTF_RDONLY));
841
842
0
  if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
843
0
    dtd = ctf_dtd_lookup (fp, type);
844
0
  else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
845
0
            initial_vlen, &dtd)) == CTF_ERR)
846
0
    return CTF_ERR;   /* errno is set for us.  */
847
848
  /* Forwards won't have any vlen yet.  */
849
0
  if (dtd->dtd_vlen_alloc == 0)
850
0
    {
851
0
      if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
852
0
  return (ctf_set_typed_errno (fp, ENOMEM));
853
0
      dtd->dtd_vlen_alloc = initial_vlen;
854
0
    }
855
856
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
857
0
  dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
858
0
  dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
859
0
  dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
860
861
0
  return type;
862
0
}
863
864
ctf_id_t
865
ctf_add_union (ctf_dict_t *fp, uint32_t flag, const char *name)
866
0
{
867
0
  return (ctf_add_union_sized (fp, flag, name, 0));
868
0
}
869
870
ctf_id_t
871
ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
872
0
{
873
0
  ctf_dtdef_t *dtd;
874
0
  ctf_id_t type = 0;
875
0
  size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN;
876
877
  /* Promote root-visible forwards to enums.  */
878
0
  if (name != NULL)
879
0
    type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
880
881
  /* Prohibit promotion if this type was ctf_open()ed.  */
882
0
  if (type > 0 && type < fp->ctf_stypes)
883
0
    return (ctf_set_errno (fp, ECTF_RDONLY));
884
885
0
  if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
886
0
    dtd = ctf_dtd_lookup (fp, type);
887
0
  else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
888
0
            initial_vlen, &dtd)) == CTF_ERR)
889
0
    return CTF_ERR;   /* errno is set for us.  */
890
891
  /* Forwards won't have any vlen yet.  */
892
0
  if (dtd->dtd_vlen_alloc == 0)
893
0
    {
894
0
      if ((dtd->dtd_vlen = calloc (1, initial_vlen)) == NULL)
895
0
  return (ctf_set_typed_errno (fp, ENOMEM));
896
0
      dtd->dtd_vlen_alloc = initial_vlen;
897
0
    }
898
899
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
900
0
  dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
901
902
0
  return type;
903
0
}
904
905
ctf_id_t
906
ctf_add_enum_encoded (ctf_dict_t *fp, uint32_t flag, const char *name,
907
          const ctf_encoding_t *ep)
908
0
{
909
0
  ctf_id_t type = 0;
910
911
  /* First, create the enum if need be, using most of the same machinery as
912
     ctf_add_enum(), to ensure that we do not allow things past that are not
913
     enums or forwards to them.  (This includes other slices: you cannot slice a
914
     slice, which would be a useless thing to do anyway.)  */
915
916
0
  if (name != NULL)
917
0
    type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
918
919
0
  if (type != 0)
920
0
    {
921
0
      if ((ctf_type_kind (fp, type) != CTF_K_FORWARD) &&
922
0
    (ctf_type_kind_unsliced (fp, type) != CTF_K_ENUM))
923
0
  return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
924
0
    }
925
0
  else if ((type = ctf_add_enum (fp, flag, name)) == CTF_ERR)
926
0
    return CTF_ERR;   /* errno is set for us.  */
927
928
  /* Now attach a suitable slice to it.  */
929
930
0
  return ctf_add_slice (fp, flag, type, ep);
931
0
}
932
933
ctf_id_t
934
ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
935
     uint32_t kind)
936
0
{
937
0
  ctf_dtdef_t *dtd;
938
0
  ctf_id_t type = 0;
939
940
0
  if (!ctf_forwardable_kind (kind))
941
0
    return (ctf_set_typed_errno (fp, ECTF_NOTSUE));
942
943
0
  if (name == NULL || name[0] == '\0')
944
0
    return (ctf_set_typed_errno (fp, ECTF_NONAME));
945
946
  /* If the type is already defined or exists as a forward tag, just return
947
     the ctf_id_t of the existing definition.  Since this changes nothing,
948
     it's safe to do even on the read-only portion of the dict.  */
949
950
0
  type = ctf_lookup_by_rawname (fp, kind, name);
951
952
0
  if (type)
953
0
    return type;
954
955
0
  if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
956
0
    return CTF_ERR;   /* errno is set for us.  */
957
958
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
959
0
  dtd->dtd_data.ctt_type = kind;
960
961
0
  return type;
962
0
}
963
964
ctf_id_t
965
ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name)
966
0
{
967
0
  ctf_dtdef_t *dtd;
968
0
  ctf_id_t type = 0;
969
970
  /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN)
971
     or just return it.  */
972
973
0
  if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT
974
0
      && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name)))
975
0
    {
976
0
      if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN)
977
0
  return type;
978
0
      else
979
0
  {
980
0
    ctf_err_warn (fp, 1, ECTF_CONFLICT,
981
0
      _("ctf_add_unknown: cannot add unknown type "
982
0
        "named %s: type of this name already defined"),
983
0
      name ? name : _("(unnamed type)"));
984
0
    return (ctf_set_typed_errno (fp, ECTF_CONFLICT));
985
0
  }
986
0
    }
987
988
0
  if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR)
989
0
    return CTF_ERR;   /* errno is set for us.  */
990
991
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0);
992
0
  dtd->dtd_data.ctt_type = 0;
993
994
0
  return type;
995
0
}
996
997
ctf_id_t
998
ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
999
     ctf_id_t ref)
1000
0
{
1001
0
  ctf_dtdef_t *dtd;
1002
0
  ctf_id_t type;
1003
0
  ctf_dict_t *tmp = fp;
1004
1005
0
  if (ref == CTF_ERR || ref > CTF_MAX_TYPE)
1006
0
    return (ctf_set_typed_errno (fp, EINVAL));
1007
1008
0
  if (name == NULL || name[0] == '\0')
1009
0
    return (ctf_set_typed_errno (fp, ECTF_NONAME));
1010
1011
0
  if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
1012
0
    return CTF_ERR;   /* errno is set for us.  */
1013
1014
0
  if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
1015
0
             &dtd)) == CTF_ERR)
1016
0
    return CTF_ERR;   /* errno is set for us.  */
1017
1018
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
1019
0
  dtd->dtd_data.ctt_type = (uint32_t) ref;
1020
1021
0
  return type;
1022
0
}
1023
1024
ctf_id_t
1025
ctf_add_volatile (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1026
0
{
1027
0
  return (ctf_add_reftype (fp, flag, ref, CTF_K_VOLATILE));
1028
0
}
1029
1030
ctf_id_t
1031
ctf_add_const (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1032
0
{
1033
0
  return (ctf_add_reftype (fp, flag, ref, CTF_K_CONST));
1034
0
}
1035
1036
ctf_id_t
1037
ctf_add_restrict (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
1038
0
{
1039
0
  return (ctf_add_reftype (fp, flag, ref, CTF_K_RESTRICT));
1040
0
}
1041
1042
int
1043
ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
1044
        int value)
1045
0
{
1046
0
  ctf_dict_t *ofp = fp;
1047
0
  ctf_dtdef_t *dtd;
1048
0
  unsigned char *old_vlen;
1049
0
  ctf_enum_t *en;
1050
1051
0
  uint32_t kind, vlen, root;
1052
1053
0
  if (name == NULL)
1054
0
    return (ctf_set_errno (fp, EINVAL));
1055
1056
0
  if ((enid = ctf_type_resolve_unsliced (fp, enid)) == CTF_ERR)
1057
0
      return -1;       /* errno is set for us.  */
1058
1059
0
  dtd = ctf_dtd_lookup (fp, enid);
1060
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, enid))
1061
0
    fp = fp->ctf_parent;
1062
1063
0
  if (enid < fp->ctf_stypes)
1064
0
    return (ctf_set_errno (ofp, ECTF_RDONLY));
1065
1066
0
  if (dtd == NULL)
1067
0
    return (ctf_set_errno (ofp, ECTF_BADID));
1068
1069
0
  kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1070
0
  root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1071
0
  vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1072
1073
  /* Enumeration constant names are only added, and only checked for duplicates,
1074
     if the enum they are part of is a root-visible type.  */
1075
1076
0
  if (root == CTF_ADD_ROOT && ctf_dynhash_lookup (fp->ctf_names, name))
1077
0
    {
1078
0
      if (fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS)
1079
0
  return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1080
1081
0
      if (ctf_track_enumerator (fp, enid, name) < 0)
1082
0
  return (ctf_set_errno (ofp, ctf_errno (fp)));
1083
0
    }
1084
1085
0
  if (kind != CTF_K_ENUM)
1086
0
    return (ctf_set_errno (ofp, ECTF_NOTENUM));
1087
1088
0
  if (vlen == CTF_MAX_VLEN)
1089
0
    return (ctf_set_errno (ofp, ECTF_DTFULL));
1090
1091
0
  old_vlen = dtd->dtd_vlen;
1092
1093
0
  if (ctf_grow_vlen (fp, dtd, sizeof (ctf_enum_t) * (vlen + 1)) < 0)
1094
0
    return -1;         /* errno is set for us.  */
1095
1096
0
  en = (ctf_enum_t *) dtd->dtd_vlen;
1097
1098
  /* Remove refs in the old vlen region and reapply them.  */
1099
1100
0
  ctf_str_move_refs (fp, old_vlen, sizeof (ctf_enum_t) * vlen, dtd->dtd_vlen);
1101
1102
  /* Check for constant duplication within any given enum: only needed for
1103
     non-root-visible types, since the duplicate detection above does the job
1104
     for root-visible types just fine.  */
1105
1106
0
  if (root == CTF_ADD_NONROOT && (fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS))
1107
0
    {
1108
0
      size_t i;
1109
1110
0
      for (i = 0; i < vlen; i++)
1111
0
  if (strcmp (ctf_strptr (fp, en[i].cte_name), name) == 0)
1112
0
    return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1113
0
    }
1114
1115
0
  en[vlen].cte_name = ctf_str_add_movable_ref (fp, name, &en[vlen].cte_name);
1116
0
  en[vlen].cte_value = value;
1117
1118
0
  if (en[vlen].cte_name == 0 && name != NULL && name[0] != '\0')
1119
0
    return (ctf_set_errno (ofp, ctf_errno (fp)));
1120
1121
  /* Put the newly-added enumerator name into the name table if this type is
1122
     root-visible.  */
1123
1124
0
  if (root == CTF_ADD_ROOT)
1125
0
    {
1126
0
      if (ctf_dynhash_insert (fp->ctf_names,
1127
0
            (char *) ctf_strptr (fp, en[vlen].cte_name),
1128
0
            (void *) (uintptr_t) enid) < 0)
1129
0
  return ctf_set_errno (fp, ENOMEM);
1130
0
    }
1131
1132
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1133
1134
0
  return 0;
1135
0
}
1136
1137
int
1138
ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1139
           ctf_id_t type, unsigned long bit_offset)
1140
0
{
1141
0
  ctf_dict_t *ofp = fp;
1142
0
  ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, souid);
1143
1144
0
  ssize_t msize, malign, ssize;
1145
0
  uint32_t kind, vlen, root;
1146
0
  size_t i;
1147
0
  int is_incomplete = 0;
1148
0
  unsigned char *old_vlen;
1149
0
  ctf_lmember_t *memb;
1150
1151
0
  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, souid))
1152
0
    {
1153
      /* Adding a child type to a parent, even via the child, is prohibited.
1154
   Otherwise, climb to the parent and do all work there.  */
1155
1156
0
      if (LCTF_TYPE_ISCHILD (fp, type))
1157
0
  return (ctf_set_errno (ofp, ECTF_BADID));
1158
1159
0
      fp = fp->ctf_parent;
1160
0
    }
1161
1162
0
  if (souid < fp->ctf_stypes)
1163
0
    return (ctf_set_errno (ofp, ECTF_RDONLY));
1164
1165
0
  if (dtd == NULL)
1166
0
    return (ctf_set_errno (ofp, ECTF_BADID));
1167
1168
0
  if (name != NULL && name[0] == '\0')
1169
0
    name = NULL;
1170
1171
0
  kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1172
0
  root = LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info);
1173
0
  vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
1174
1175
0
  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1176
0
    return (ctf_set_errno (ofp, ECTF_NOTSOU));
1177
1178
0
  if (vlen == CTF_MAX_VLEN)
1179
0
    return (ctf_set_errno (ofp, ECTF_DTFULL));
1180
1181
0
  old_vlen = dtd->dtd_vlen;
1182
0
  if (ctf_grow_vlen (fp, dtd, sizeof (ctf_lmember_t) * (vlen + 1)) < 0)
1183
0
    return (ctf_set_errno (ofp, ctf_errno (fp)));
1184
0
  memb = (ctf_lmember_t *) dtd->dtd_vlen;
1185
1186
  /* Remove pending refs in the old vlen region and reapply them.  */
1187
1188
0
  ctf_str_move_refs (fp, old_vlen, sizeof (ctf_lmember_t) * vlen, dtd->dtd_vlen);
1189
1190
0
  if (name != NULL)
1191
0
    {
1192
0
      for (i = 0; i < vlen; i++)
1193
0
  if (strcmp (ctf_strptr (fp, memb[i].ctlm_name), name) == 0)
1194
0
    return (ctf_set_errno (ofp, ECTF_DUPLICATE));
1195
0
    }
1196
1197
0
  if ((msize = ctf_type_size (fp, type)) < 0 ||
1198
0
      (malign = ctf_type_align (fp, type)) < 0)
1199
0
    {
1200
      /* The unimplemented type, and any type that resolves to it, has no size
1201
   and no alignment: it can correspond to any number of compiler-inserted
1202
   types.  We allow incomplete types through since they are routinely
1203
   added to the ends of structures, and can even be added elsewhere in
1204
   structures by the deduplicator.  They are assumed to be zero-size with
1205
   no alignment: this is often wrong, but problems can be avoided in this
1206
   case by explicitly specifying the size of the structure via the _sized
1207
   functions.  The deduplicator always does this.  */
1208
1209
0
      msize = 0;
1210
0
      malign = 0;
1211
0
      if (ctf_errno (fp) == ECTF_NONREPRESENTABLE)
1212
0
  ctf_set_errno (fp, 0);
1213
0
      else if (ctf_errno (fp) == ECTF_INCOMPLETE)
1214
0
  is_incomplete = 1;
1215
0
      else
1216
0
  return -1;   /* errno is set for us.  */
1217
0
    }
1218
1219
0
  memb[vlen].ctlm_name = ctf_str_add_movable_ref (fp, name, &memb[vlen].ctlm_name);
1220
0
  memb[vlen].ctlm_type = type;
1221
0
  if (memb[vlen].ctlm_name == 0 && name != NULL && name[0] != '\0')
1222
0
    return -1;     /* errno is set for us.  */
1223
1224
0
  if (kind == CTF_K_STRUCT && vlen != 0)
1225
0
    {
1226
0
      if (bit_offset == (unsigned long) - 1)
1227
0
  {
1228
    /* Natural alignment.  */
1229
1230
0
    ctf_id_t ltype = ctf_type_resolve (fp, memb[vlen - 1].ctlm_type);
1231
0
    size_t off = CTF_LMEM_OFFSET(&memb[vlen - 1]);
1232
1233
0
    ctf_encoding_t linfo;
1234
0
    ssize_t lsize;
1235
1236
    /* Propagate any error from ctf_type_resolve.  If the last member was
1237
       of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we
1238
       cannot insert right after such a member without explicit offset
1239
       specification, because its alignment and size is not known.  */
1240
0
    if (ltype == CTF_ERR)
1241
0
      return -1; /* errno is set for us.  */
1242
1243
0
    if (is_incomplete)
1244
0
      {
1245
0
        ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
1246
0
          _("ctf_add_member_offset: cannot add member %s of "
1247
0
            "incomplete type %lx to struct %lx without "
1248
0
            "specifying explicit offset\n"),
1249
0
          name ? name : _("(unnamed member)"), type, souid);
1250
0
        return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1251
0
      }
1252
1253
0
    if (ctf_type_encoding (fp, ltype, &linfo) == 0)
1254
0
      off += linfo.cte_bits;
1255
0
    else if ((lsize = ctf_type_size (fp, ltype)) > 0)
1256
0
      off += lsize * CHAR_BIT;
1257
0
    else if (lsize == -1 && ctf_errno (fp) == ECTF_INCOMPLETE)
1258
0
      {
1259
0
        const char *lname = ctf_strraw (fp, memb[vlen - 1].ctlm_name);
1260
1261
0
        ctf_err_warn (ofp, 1, ECTF_INCOMPLETE,
1262
0
          _("ctf_add_member_offset: cannot add member %s of "
1263
0
            "type %lx to struct %lx without specifying "
1264
0
            "explicit offset after member %s of type %lx, "
1265
0
            "which is an incomplete type\n"),
1266
0
          name ? name : _("(unnamed member)"), type, souid,
1267
0
          lname ? lname : _("(unnamed member)"), ltype);
1268
0
        return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1269
0
      }
1270
1271
    /* Round up the offset of the end of the last member to
1272
       the next byte boundary, convert 'off' to bytes, and
1273
       then round it up again to the next multiple of the
1274
       alignment required by the new member.  Finally,
1275
       convert back to bits and store the result in
1276
       dmd_offset.  Technically we could do more efficient
1277
       packing if the new member is a bit-field, but we're
1278
       the "compiler" and ANSI says we can do as we choose.  */
1279
1280
0
    off = roundup (off, CHAR_BIT) / CHAR_BIT;
1281
0
    off = roundup (off, MAX (malign, 1));
1282
0
    memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (off * CHAR_BIT);
1283
0
    memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (off * CHAR_BIT);
1284
0
    ssize = off + msize;
1285
0
  }
1286
0
      else
1287
0
  {
1288
    /* Specified offset in bits.  */
1289
1290
0
    memb[vlen].ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (bit_offset);
1291
0
    memb[vlen].ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (bit_offset);
1292
0
    ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1293
0
    ssize = MAX (ssize, ((signed) bit_offset / CHAR_BIT) + msize);
1294
0
  }
1295
0
    }
1296
0
  else
1297
0
    {
1298
0
      memb[vlen].ctlm_offsethi = 0;
1299
0
      memb[vlen].ctlm_offsetlo = 0;
1300
0
      ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL);
1301
0
      ssize = MAX (ssize, msize);
1302
0
    }
1303
1304
0
  dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1305
0
  dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize);
1306
0
  dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (ssize);
1307
0
  dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, root, vlen + 1);
1308
1309
0
  return 0;
1310
0
}
1311
1312
int
1313
ctf_add_member_encoded (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1314
      ctf_id_t type, unsigned long bit_offset,
1315
      const ctf_encoding_t encoding)
1316
0
{
1317
0
  ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
1318
0
  int kind;
1319
0
  int otype = type;
1320
1321
0
  if (dtd == NULL)
1322
0
    return (ctf_set_errno (fp, ECTF_BADID));
1323
1324
0
  kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
1325
1326
0
  if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && (kind != CTF_K_ENUM))
1327
0
    return (ctf_set_errno (fp, ECTF_NOTINTFP));
1328
1329
0
  if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR)
1330
0
    return -1;     /* errno is set for us.  */
1331
1332
0
  return ctf_add_member_offset (fp, souid, name, type, bit_offset);
1333
0
}
1334
1335
int
1336
ctf_add_member (ctf_dict_t *fp, ctf_id_t souid, const char *name,
1337
    ctf_id_t type)
1338
0
{
1339
0
  return ctf_add_member_offset (fp, souid, name, type, (unsigned long) - 1);
1340
0
}
1341
1342
/* Add a variable regardless of whether or not it is already present.
1343
1344
   Internal use only.  */
1345
int
1346
ctf_add_variable_forced (ctf_dict_t *fp, const char *name, ctf_id_t ref)
1347
0
{
1348
0
  ctf_dvdef_t *dvd;
1349
0
  ctf_dict_t *tmp = fp;
1350
1351
0
  if (ctf_lookup_by_id (&tmp, ref) == NULL)
1352
0
    return -1;     /* errno is set for us.  */
1353
1354
  /* Make sure this type is representable.  */
1355
0
  if ((ctf_type_resolve (fp, ref) == CTF_ERR)
1356
0
      && (ctf_errno (fp) == ECTF_NONREPRESENTABLE))
1357
0
    return -1;
1358
1359
0
  if ((dvd = malloc (sizeof (ctf_dvdef_t))) == NULL)
1360
0
    return (ctf_set_errno (fp, EAGAIN));
1361
1362
0
  if (name != NULL && (dvd->dvd_name = strdup (name)) == NULL)
1363
0
    {
1364
0
      free (dvd);
1365
0
      return (ctf_set_errno (fp, EAGAIN));
1366
0
    }
1367
0
  dvd->dvd_type = ref;
1368
0
  dvd->dvd_snapshots = fp->ctf_snapshots;
1369
1370
0
  if (ctf_dvd_insert (fp, dvd) < 0)
1371
0
    {
1372
0
      free (dvd->dvd_name);
1373
0
      free (dvd);
1374
0
      return -1;      /* errno is set for us.  */
1375
0
    }
1376
1377
0
  return 0;
1378
0
}
1379
1380
int
1381
ctf_add_variable (ctf_dict_t *fp, const char *name, ctf_id_t ref)
1382
0
{
1383
0
  if (ctf_lookup_variable_here (fp, name) != CTF_ERR)
1384
0
    return (ctf_set_errno (fp, ECTF_DUPLICATE));
1385
1386
0
  if (ctf_errno (fp) != ECTF_NOTYPEDAT)
1387
0
    return -1;       /* errno is set for us.  */
1388
1389
0
  return ctf_add_variable_forced (fp, name, ref);
1390
0
}
1391
1392
/* Add a function or object symbol regardless of whether or not it is already
1393
   present (already existing symbols are silently overwritten).
1394
1395
   Internal use only.  */
1396
int
1397
ctf_add_funcobjt_sym_forced (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
1398
0
{
1399
0
  ctf_dict_t *tmp = fp;
1400
0
  char *dupname;
1401
0
  ctf_dynhash_t *h = is_function ? fp->ctf_funchash : fp->ctf_objthash;
1402
1403
0
  if (ctf_lookup_by_id (&tmp, id) == NULL)
1404
0
    return -1;       /* errno is set for us.  */
1405
1406
0
  if (is_function && ctf_type_kind (fp, id) != CTF_K_FUNCTION)
1407
0
    return (ctf_set_errno (fp, ECTF_NOTFUNC));
1408
1409
0
  if ((dupname = strdup (name)) == NULL)
1410
0
    return (ctf_set_errno (fp, ENOMEM));
1411
1412
0
  if (ctf_dynhash_insert (h, dupname, (void *) (uintptr_t) id) < 0)
1413
0
    {
1414
0
      free (dupname);
1415
0
      return (ctf_set_errno (fp, ENOMEM));
1416
0
    }
1417
0
  return 0;
1418
0
}
1419
1420
int
1421
ctf_add_funcobjt_sym (ctf_dict_t *fp, int is_function, const char *name, ctf_id_t id)
1422
0
{
1423
0
  if (ctf_lookup_by_sym_or_name (fp, 0, name, 0, is_function) != CTF_ERR)
1424
0
    return (ctf_set_errno (fp, ECTF_DUPLICATE));
1425
1426
0
  return ctf_add_funcobjt_sym_forced (fp, is_function, name, id);
1427
0
}
1428
1429
int
1430
ctf_add_objt_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1431
0
{
1432
0
  return (ctf_add_funcobjt_sym (fp, 0, name, id));
1433
0
}
1434
1435
int
1436
ctf_add_func_sym (ctf_dict_t *fp, const char *name, ctf_id_t id)
1437
0
{
1438
0
  return (ctf_add_funcobjt_sym (fp, 1, name, id));
1439
0
}
1440
1441
/* Add an enumeration constant observed in a given enum type as an identifier.
1442
   They appear as names that cite the enum type.
1443
1444
   Constants that appear in more than one enum, or which are already the names
1445
   of types, appear in ctf_conflicting_enums as well.
1446
1447
   This is done for all enumeration types at open time, and for newly-added ones
1448
   as well: if the strict-enum flag is turned on, this table must be kept up to
1449
   date with enums added in the interim.  */
1450
1451
int
1452
ctf_track_enumerator (ctf_dict_t *fp, ctf_id_t type, const char *cte_name)
1453
0
{
1454
0
  int err;
1455
1456
0
  if (ctf_dynhash_lookup_type (fp->ctf_names, cte_name) == 0)
1457
0
    {
1458
0
      uint32_t name = ctf_str_add (fp, cte_name);
1459
1460
0
      if (name == 0)
1461
0
  return -1;       /* errno is set for us.  */
1462
1463
0
      err = ctf_dynhash_insert_type (fp, fp->ctf_names, type, name);
1464
0
    }
1465
0
  else
1466
0
    {
1467
0
      err = ctf_dynset_insert (fp->ctf_conflicting_enums, (void *)
1468
0
             cte_name);
1469
0
      if (err != 0)
1470
0
  ctf_set_errno (fp, err * -1);
1471
0
    }
1472
0
  if (err != 0)
1473
0
    return -1;         /* errno is set for us.  */
1474
0
  return 0;
1475
0
}
1476
1477
typedef struct ctf_bundle
1478
{
1479
  ctf_dict_t *ctb_dict;   /* CTF dict handle.  */
1480
  ctf_id_t ctb_type;    /* CTF type identifier.  */
1481
  ctf_dtdef_t *ctb_dtd;   /* CTF dynamic type definition (if any).  */
1482
} ctf_bundle_t;
1483
1484
static int
1485
enumcmp (const char *name, int value, void *arg)
1486
0
{
1487
0
  ctf_bundle_t *ctb = arg;
1488
0
  int bvalue;
1489
1490
0
  if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
1491
0
    {
1492
0
      ctf_err_warn (ctb->ctb_dict, 0, 0,
1493
0
        _("conflict due to enum %s iteration error"), name);
1494
0
      return 1;
1495
0
    }
1496
0
  if (value != bvalue)
1497
0
    {
1498
0
      ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1499
0
        _("conflict due to enum value change: %i versus %i"),
1500
0
        value, bvalue);
1501
0
      return 1;
1502
0
    }
1503
0
  return 0;
1504
0
}
1505
1506
static int
1507
enumadd (const char *name, int value, void *arg)
1508
0
{
1509
0
  ctf_bundle_t *ctb = arg;
1510
1511
0
  return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
1512
0
            name, value) < 0);
1513
0
}
1514
1515
static int
1516
membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset,
1517
   void *arg)
1518
0
{
1519
0
  ctf_bundle_t *ctb = arg;
1520
0
  ctf_membinfo_t ctm;
1521
1522
  /* Don't check nameless members (e.g. anonymous structs/unions) against each
1523
     other.  */
1524
0
  if (name[0] == 0)
1525
0
    return 0;
1526
1527
0
  if (ctf_member_info (ctb->ctb_dict, ctb->ctb_type, name, &ctm) < 0)
1528
0
    {
1529
0
      ctf_err_warn (ctb->ctb_dict, 0, 0,
1530
0
        _("conflict due to struct member %s iteration error"),
1531
0
        name);
1532
0
      return 1;
1533
0
    }
1534
0
  if (ctm.ctm_offset != offset)
1535
0
    {
1536
0
      ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
1537
0
        _("conflict due to struct member %s offset change: "
1538
0
          "%lx versus %lx"),
1539
0
        name, ctm.ctm_offset, offset);
1540
0
      return 1;
1541
0
    }
1542
0
  return 0;
1543
0
}
1544
1545
/* Record the correspondence between a source and ctf_add_type()-added
1546
   destination type: both types are translated into parent type IDs if need be,
1547
   so they relate to the actual dictionary they are in.  Outside controlled
1548
   circumstances (like linking) it is probably not useful to do more than
1549
   compare these pointers, since there is nothing stopping the user closing the
1550
   source dict whenever they want to.
1551
1552
   Our OOM handling here is just to not do anything, because this is called deep
1553
   enough in the call stack that doing anything useful is painfully difficult:
1554
   the worst consequence if we do OOM is a bit of type duplication anyway.  */
1555
1556
static void
1557
ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
1558
          ctf_dict_t *dst_fp, ctf_id_t dst_type)
1559
0
{
1560
0
  if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1561
0
    src_fp = src_fp->ctf_parent;
1562
1563
0
  src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1564
1565
0
  if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
1566
0
    dst_fp = dst_fp->ctf_parent;
1567
1568
0
  dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
1569
1570
0
  if (dst_fp->ctf_link_type_mapping == NULL)
1571
0
    {
1572
0
      ctf_hash_fun f = ctf_hash_type_key;
1573
0
      ctf_hash_eq_fun e = ctf_hash_eq_type_key;
1574
1575
0
      if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
1576
0
                     NULL)) == NULL)
1577
0
  return;
1578
0
    }
1579
1580
0
  ctf_link_type_key_t *key;
1581
0
  key = calloc (1, sizeof (struct ctf_link_type_key));
1582
0
  if (!key)
1583
0
    return;
1584
1585
0
  key->cltk_fp = src_fp;
1586
0
  key->cltk_idx = src_type;
1587
1588
  /* No OOM checking needed, because if this doesn't work the worst we'll do is
1589
     add a few more duplicate types (which will probably run out of memory
1590
     anyway).  */
1591
0
  ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
1592
0
          (void *) (uintptr_t) dst_type);
1593
0
}
1594
1595
/* Look up a type mapping: return 0 if none.  The DST_FP is modified to point to
1596
   the parent if need be.  The ID returned is from the dst_fp's perspective.  */
1597
static ctf_id_t
1598
ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
1599
0
{
1600
0
  ctf_link_type_key_t key;
1601
0
  ctf_dict_t *target_fp = *dst_fp;
1602
0
  ctf_id_t dst_type = 0;
1603
1604
0
  if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
1605
0
    src_fp = src_fp->ctf_parent;
1606
1607
0
  src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
1608
0
  key.cltk_fp = src_fp;
1609
0
  key.cltk_idx = src_type;
1610
1611
0
  if (target_fp->ctf_link_type_mapping)
1612
0
    dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1613
0
                 &key);
1614
1615
0
  if (dst_type != 0)
1616
0
    {
1617
0
      dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1618
0
             target_fp->ctf_parent != NULL);
1619
0
      *dst_fp = target_fp;
1620
0
      return dst_type;
1621
0
    }
1622
1623
0
  if (target_fp->ctf_parent)
1624
0
    target_fp = target_fp->ctf_parent;
1625
0
  else
1626
0
    return 0;
1627
1628
0
  if (target_fp->ctf_link_type_mapping)
1629
0
    dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
1630
0
                 &key);
1631
1632
0
  if (dst_type)
1633
0
    dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
1634
0
           target_fp->ctf_parent != NULL);
1635
1636
0
  *dst_fp = target_fp;
1637
0
  return dst_type;
1638
0
}
1639
1640
/* The ctf_add_type routine is used to copy a type from a source CTF dictionary
1641
   to a dynamic destination dictionary.  This routine operates recursively by
1642
   following the source type's links and embedded member types.  If the
1643
   destination dict already contains a named type which has the same attributes,
1644
   then we succeed and return this type but no changes occur.  */
1645
static ctf_id_t
1646
ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type,
1647
           ctf_dict_t *proc_tracking_fp)
1648
0
{
1649
0
  ctf_id_t dst_type = CTF_ERR;
1650
0
  uint32_t dst_kind = CTF_K_UNKNOWN;
1651
0
  ctf_dict_t *tmp_fp = dst_fp;
1652
0
  ctf_id_t tmp;
1653
1654
0
  const char *name;
1655
0
  uint32_t kind, forward_kind, flag, vlen;
1656
1657
0
  const ctf_type_t *src_tp, *dst_tp;
1658
0
  ctf_bundle_t src, dst;
1659
0
  ctf_encoding_t src_en, dst_en;
1660
0
  ctf_arinfo_t src_ar, dst_ar;
1661
1662
0
  ctf_funcinfo_t ctc;
1663
1664
0
  ctf_id_t orig_src_type = src_type;
1665
1666
0
  if ((src_tp = ctf_lookup_by_id (&src_fp, src_type)) == NULL)
1667
0
    return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1668
1669
0
  if ((ctf_type_resolve (src_fp, src_type) == CTF_ERR)
1670
0
      && (ctf_errno (src_fp) == ECTF_NONREPRESENTABLE))
1671
0
    return (ctf_set_typed_errno (dst_fp, ECTF_NONREPRESENTABLE));
1672
1673
0
  name = ctf_strptr (src_fp, src_tp->ctt_name);
1674
0
  kind = LCTF_INFO_KIND (src_fp, src_tp->ctt_info);
1675
0
  flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
1676
0
  vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
1677
1678
  /* If this is a type we are currently in the middle of adding, hand it
1679
     straight back.  (This lets us handle self-referential structures without
1680
     considering forwards and empty structures the same as their completed
1681
     forms.)  */
1682
1683
0
  tmp = ctf_type_mapping (src_fp, src_type, &tmp_fp);
1684
1685
0
  if (tmp != 0)
1686
0
    {
1687
0
      if (ctf_dynhash_lookup (proc_tracking_fp->ctf_add_processing,
1688
0
            (void *) (uintptr_t) src_type))
1689
0
  return tmp;
1690
1691
      /* If this type has already been added from this dictionary, and is the
1692
   same kind and (if a struct or union) has the same number of members,
1693
   hand it straight back.  */
1694
1695
0
      if (ctf_type_kind_unsliced (tmp_fp, tmp) == (int) kind)
1696
0
  {
1697
0
    if (kind == CTF_K_STRUCT || kind == CTF_K_UNION
1698
0
        || kind == CTF_K_ENUM)
1699
0
      {
1700
0
        if ((dst_tp = ctf_lookup_by_id (&tmp_fp, dst_type)) != NULL)
1701
0
    if (vlen == LCTF_INFO_VLEN (tmp_fp, dst_tp->ctt_info))
1702
0
      return tmp;
1703
0
      }
1704
0
    else
1705
0
      return tmp;
1706
0
  }
1707
0
    }
1708
1709
0
  forward_kind = kind;
1710
0
  if (kind == CTF_K_FORWARD)
1711
0
    forward_kind = src_tp->ctt_type;
1712
1713
  /* If the source type has a name and is a root type (visible at the top-level
1714
     scope), lookup the name in the destination dictionary and verify that it is
1715
     of the same kind before we do anything else.  */
1716
1717
0
  if ((flag & CTF_ADD_ROOT) && name[0] != '\0'
1718
0
      && (tmp = ctf_lookup_by_rawname (dst_fp, forward_kind, name)) != 0)
1719
0
    {
1720
0
      dst_type = tmp;
1721
0
      dst_kind = ctf_type_kind_unsliced (dst_fp, dst_type);
1722
0
    }
1723
1724
  /* If an identically named dst_type exists, fail with ECTF_CONFLICT
1725
     unless dst_type is a forward declaration and src_type is a struct,
1726
     union, or enum (i.e. the definition of the previous forward decl).
1727
1728
     We also allow addition in the opposite order (addition of a forward when a
1729
     struct, union, or enum already exists), which is a NOP and returns the
1730
     already-present struct, union, or enum.  */
1731
1732
0
  if (dst_type != CTF_ERR && dst_kind != kind)
1733
0
    {
1734
0
      if (kind == CTF_K_FORWARD
1735
0
    && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1736
0
        || dst_kind == CTF_K_UNION))
1737
0
  {
1738
0
    ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1739
0
    return dst_type;
1740
0
  }
1741
1742
0
      if (dst_kind != CTF_K_FORWARD
1743
0
    || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1744
0
        && kind != CTF_K_UNION))
1745
0
  {
1746
0
    ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1747
0
      _("ctf_add_type: conflict for type %s: "
1748
0
        "kinds differ, new: %i; old (ID %lx): %i"),
1749
0
      name, kind, dst_type, dst_kind);
1750
0
    return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1751
0
  }
1752
0
    }
1753
1754
  /* We take special action for an integer, float, or slice since it is
1755
     described not only by its name but also its encoding.  For integers,
1756
     bit-fields exploit this degeneracy.  */
1757
1758
0
  if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT || kind == CTF_K_SLICE)
1759
0
    {
1760
0
      if (ctf_type_encoding (src_fp, src_type, &src_en) != 0)
1761
0
  return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1762
1763
0
      if (dst_type != CTF_ERR)
1764
0
  {
1765
0
    ctf_dict_t *fp = dst_fp;
1766
1767
0
    if ((dst_tp = ctf_lookup_by_id (&fp, dst_type)) == NULL)
1768
0
      return CTF_ERR;
1769
1770
0
    if (ctf_type_encoding (dst_fp, dst_type, &dst_en) != 0)
1771
0
      return CTF_ERR;     /* errno set for us.  */
1772
1773
0
    if (LCTF_INFO_ISROOT (fp, dst_tp->ctt_info) & CTF_ADD_ROOT)
1774
0
      {
1775
        /* The type that we found in the hash is also root-visible.  If
1776
     the two types match then use the existing one; otherwise,
1777
     declare a conflict.  Note: slices are not certain to match
1778
     even if there is no conflict: we must check the contained type
1779
     too.  */
1780
1781
0
        if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1782
0
    {
1783
0
      if (kind != CTF_K_SLICE)
1784
0
        {
1785
0
          ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1786
0
          return dst_type;
1787
0
        }
1788
0
    }
1789
0
        else
1790
0
      {
1791
0
        return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1792
0
      }
1793
0
      }
1794
0
    else
1795
0
      {
1796
        /* We found a non-root-visible type in the hash.  If its encoding
1797
     is the same, we can reuse it, unless it is a slice.  */
1798
1799
0
        if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
1800
0
    {
1801
0
      if (kind != CTF_K_SLICE)
1802
0
        {
1803
0
          ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1804
0
          return dst_type;
1805
0
        }
1806
0
    }
1807
0
      }
1808
0
  }
1809
0
    }
1810
1811
0
  src.ctb_dict = src_fp;
1812
0
  src.ctb_type = src_type;
1813
0
  src.ctb_dtd = NULL;
1814
1815
0
  dst.ctb_dict = dst_fp;
1816
0
  dst.ctb_type = dst_type;
1817
0
  dst.ctb_dtd = NULL;
1818
1819
  /* Now perform kind-specific processing.  If dst_type is CTF_ERR, then we add
1820
     a new type with the same properties as src_type to dst_fp.  If dst_type is
1821
     not CTF_ERR, then we verify that dst_type has the same attributes as
1822
     src_type.  We recurse for embedded references.  Before we start, we note
1823
     that we are processing this type, to prevent infinite recursion: we do not
1824
     re-process any type that appears in this list.  The list is emptied
1825
     wholesale at the end of processing everything in this recursive stack.  */
1826
1827
0
  if (ctf_dynhash_insert (proc_tracking_fp->ctf_add_processing,
1828
0
        (void *) (uintptr_t) src_type, (void *) 1) < 0)
1829
0
    return ctf_set_typed_errno (dst_fp, ENOMEM);
1830
1831
0
  switch (kind)
1832
0
    {
1833
0
    case CTF_K_INTEGER:
1834
      /*  If we found a match we will have either returned it or declared a
1835
    conflict.  */
1836
0
      dst_type = ctf_add_integer (dst_fp, flag, name, &src_en);
1837
0
      break;
1838
1839
0
    case CTF_K_FLOAT:
1840
      /* If we found a match we will have either returned it or declared a
1841
       conflict.  */
1842
0
      dst_type = ctf_add_float (dst_fp, flag, name, &src_en);
1843
0
      break;
1844
1845
0
    case CTF_K_SLICE:
1846
      /* We have checked for conflicting encodings: now try to add the
1847
   contained type.  */
1848
0
      src_type = ctf_type_reference (src_fp, src_type);
1849
0
      src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1850
0
          proc_tracking_fp);
1851
1852
0
      if (src_type == CTF_ERR)
1853
0
  return CTF_ERR;       /* errno is set for us.  */
1854
1855
0
      dst_type = ctf_add_slice (dst_fp, flag, src_type, &src_en);
1856
0
      break;
1857
1858
0
    case CTF_K_POINTER:
1859
0
    case CTF_K_VOLATILE:
1860
0
    case CTF_K_CONST:
1861
0
    case CTF_K_RESTRICT:
1862
0
      src_type = ctf_type_reference (src_fp, src_type);
1863
0
      src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
1864
0
          proc_tracking_fp);
1865
1866
0
      if (src_type == CTF_ERR)
1867
0
  return CTF_ERR;       /* errno is set for us.  */
1868
1869
0
      dst_type = ctf_add_reftype (dst_fp, flag, src_type, kind);
1870
0
      break;
1871
1872
0
    case CTF_K_ARRAY:
1873
0
      if (ctf_array_info (src_fp, src_type, &src_ar) != 0)
1874
0
  return (ctf_set_typed_errno (dst_fp, ctf_errno (src_fp)));
1875
1876
0
      src_ar.ctr_contents =
1877
0
  ctf_add_type_internal (dst_fp, src_fp, src_ar.ctr_contents,
1878
0
             proc_tracking_fp);
1879
0
      src_ar.ctr_index = ctf_add_type_internal (dst_fp, src_fp,
1880
0
            src_ar.ctr_index,
1881
0
            proc_tracking_fp);
1882
0
      src_ar.ctr_nelems = src_ar.ctr_nelems;
1883
1884
0
      if (src_ar.ctr_contents == CTF_ERR || src_ar.ctr_index == CTF_ERR)
1885
0
  return CTF_ERR;       /* errno is set for us.  */
1886
1887
0
      if (dst_type != CTF_ERR)
1888
0
  {
1889
0
    if (ctf_array_info (dst_fp, dst_type, &dst_ar) != 0)
1890
0
      return CTF_ERR;     /* errno is set for us.  */
1891
1892
0
    if (memcmp (&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1893
0
      {
1894
0
        ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1895
0
          _("conflict for type %s against ID %lx: array info "
1896
0
            "differs, old %lx/%lx/%x; new: %lx/%lx/%x"),
1897
0
          name, dst_type, src_ar.ctr_contents,
1898
0
          src_ar.ctr_index, src_ar.ctr_nelems,
1899
0
          dst_ar.ctr_contents, dst_ar.ctr_index,
1900
0
          dst_ar.ctr_nelems);
1901
0
        return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1902
0
      }
1903
0
  }
1904
0
      else
1905
0
  dst_type = ctf_add_array (dst_fp, flag, &src_ar);
1906
0
      break;
1907
1908
0
    case CTF_K_FUNCTION:
1909
0
      ctc.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
1910
0
                src_tp->ctt_type,
1911
0
                proc_tracking_fp);
1912
0
      ctc.ctc_argc = 0;
1913
0
      ctc.ctc_flags = 0;
1914
1915
0
      if (ctc.ctc_return == CTF_ERR)
1916
0
  return CTF_ERR;       /* errno is set for us.  */
1917
1918
0
      dst_type = ctf_add_function (dst_fp, flag, &ctc, NULL);
1919
0
      break;
1920
1921
0
    case CTF_K_STRUCT:
1922
0
    case CTF_K_UNION:
1923
0
      {
1924
0
  ctf_next_t *i = NULL;
1925
0
  ssize_t offset;
1926
0
  const char *membname;
1927
0
  ctf_id_t src_membtype;
1928
1929
  /* Technically to match a struct or union we need to check both
1930
     ways (src members vs. dst, dst members vs. src) but we make
1931
     this more optimal by only checking src vs. dst and comparing
1932
     the total size of the structure (which we must do anyway)
1933
     which covers the possibility of dst members not in src.
1934
     This optimization can be defeated for unions, but is so
1935
     pathological as to render it irrelevant for our purposes.  */
1936
1937
0
  if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
1938
0
      && dst_kind != CTF_K_FORWARD)
1939
0
    {
1940
0
      if (ctf_type_size (src_fp, src_type) !=
1941
0
    ctf_type_size (dst_fp, dst_type))
1942
0
        {
1943
0
    ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1944
0
            _("conflict for type %s against ID %lx: union "
1945
0
        "size differs, old %li, new %li"), name,
1946
0
            dst_type, (long) ctf_type_size (src_fp, src_type),
1947
0
            (long) ctf_type_size (dst_fp, dst_type));
1948
0
    return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1949
0
        }
1950
1951
0
      if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
1952
0
        {
1953
0
    ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
1954
0
            _("conflict for type %s against ID %lx: members "
1955
0
        "differ, see above"), name, dst_type);
1956
0
    return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
1957
0
        }
1958
1959
0
      break;
1960
0
    }
1961
1962
0
  dst_type = ctf_add_struct_sized (dst_fp, flag, name,
1963
0
           ctf_type_size (src_fp, src_type));
1964
0
  if (dst_type == CTF_ERR)
1965
0
    return CTF_ERR;     /* errno is set for us.  */
1966
1967
  /* Pre-emptively add this struct to the type mapping so that
1968
     structures that refer to themselves work.  */
1969
0
  ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1970
1971
0
  while ((offset = ctf_member_next (src_fp, src_type, &i, &membname,
1972
0
            &src_membtype, 0)) >= 0)
1973
0
    {
1974
0
      ctf_dict_t *dst = dst_fp;
1975
0
      ctf_id_t dst_membtype = ctf_type_mapping (src_fp, src_membtype, &dst);
1976
1977
0
      if (dst_membtype == 0)
1978
0
        {
1979
0
    dst_membtype = ctf_add_type_internal (dst_fp, src_fp,
1980
0
                  src_membtype,
1981
0
                  proc_tracking_fp);
1982
0
    if (dst_membtype == CTF_ERR)
1983
0
      {
1984
0
        if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
1985
0
          {
1986
0
      ctf_next_destroy (i);
1987
0
      break;
1988
0
          }
1989
0
      }
1990
0
        }
1991
1992
0
      if (ctf_add_member_offset (dst_fp, dst_type, membname,
1993
0
               dst_membtype, offset) < 0)
1994
0
        {
1995
0
    ctf_next_destroy (i);
1996
0
    break;
1997
0
        }
1998
0
    }
1999
0
  if (ctf_errno (src_fp) != ECTF_NEXT_END)
2000
0
    return CTF_ERR;     /* errno is set for us.  */
2001
0
  break;
2002
0
      }
2003
2004
0
    case CTF_K_ENUM:
2005
0
      if (dst_type != CTF_ERR && kind != CTF_K_FORWARD
2006
0
    && dst_kind != CTF_K_FORWARD)
2007
0
  {
2008
0
    if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
2009
0
        || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
2010
0
      {
2011
0
        ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
2012
0
          _("conflict for enum %s against ID %lx: members "
2013
0
            "differ, see above"), name, dst_type);
2014
0
        return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
2015
0
      }
2016
0
  }
2017
0
      else
2018
0
  {
2019
0
    ctf_snapshot_id_t snap = ctf_snapshot (dst_fp);
2020
2021
0
    dst_type = ctf_add_enum (dst_fp, flag, name);
2022
0
    if ((dst.ctb_type = dst_type) == CTF_ERR
2023
0
        || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
2024
0
      {
2025
0
        ctf_rollback (dst_fp, snap);
2026
0
        return CTF_ERR;     /* errno is set for us */
2027
0
      }
2028
0
  }
2029
0
      break;
2030
2031
0
    case CTF_K_FORWARD:
2032
0
      if (dst_type == CTF_ERR)
2033
0
    dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
2034
0
      break;
2035
2036
0
    case CTF_K_TYPEDEF:
2037
0
      src_type = ctf_type_reference (src_fp, src_type);
2038
0
      src_type = ctf_add_type_internal (dst_fp, src_fp, src_type,
2039
0
          proc_tracking_fp);
2040
2041
0
      if (src_type == CTF_ERR)
2042
0
  return CTF_ERR;       /* errno is set for us.  */
2043
2044
      /* If dst_type is not CTF_ERR at this point, we should check if
2045
   ctf_type_reference(dst_fp, dst_type) != src_type and if so fail with
2046
   ECTF_CONFLICT.  However, this causes problems with bitness typedefs
2047
   that vary based on things like if 32-bit then pid_t is int otherwise
2048
   long.  We therefore omit this check and assume that if the identically
2049
   named typedef already exists in dst_fp, it is correct or
2050
   equivalent.  */
2051
2052
0
      if (dst_type == CTF_ERR)
2053
0
    dst_type = ctf_add_typedef (dst_fp, flag, name, src_type);
2054
2055
0
      break;
2056
2057
0
    default:
2058
0
      return (ctf_set_typed_errno (dst_fp, ECTF_CORRUPT));
2059
0
    }
2060
2061
0
  if (dst_type != CTF_ERR)
2062
0
    ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
2063
0
  return dst_type;
2064
0
}
2065
2066
ctf_id_t
2067
ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
2068
0
{
2069
0
  ctf_id_t id;
2070
2071
0
  if (!src_fp->ctf_add_processing)
2072
0
    src_fp->ctf_add_processing = ctf_dynhash_create (ctf_hash_integer,
2073
0
                 ctf_hash_eq_integer,
2074
0
                 NULL, NULL);
2075
2076
  /* We store the hash on the source, because it contains only source type IDs:
2077
     but callers will invariably expect errors to appear on the dest.  */
2078
0
  if (!src_fp->ctf_add_processing)
2079
0
    return (ctf_set_typed_errno (dst_fp, ENOMEM));
2080
2081
0
  id = ctf_add_type_internal (dst_fp, src_fp, src_type, src_fp);
2082
0
  ctf_dynhash_empty (src_fp->ctf_add_processing);
2083
2084
0
  return id;
2085
0
}