Coverage Report

Created: 2024-05-21 06:29

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