Coverage Report

Created: 2026-03-10 08:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/libctf/ctf-archive.c
Line
Count
Source
1
/* CTF archive files.
2
   Copyright (C) 2019-2026 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/types.h>
22
#include <sys/stat.h>
23
#include <elf.h>
24
#include "ctf-endian.h"
25
#include <errno.h>
26
#include <fcntl.h>
27
#include <stdio.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#ifdef HAVE_MMAP
32
#include <sys/mman.h>
33
#endif
34
35
static off_t arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold);
36
static ctf_dict_t *ctf_dict_open_by_offset (const struct ctf_archive *arc,
37
              const ctf_sect_t *symsect,
38
              const ctf_sect_t *strsect,
39
              size_t offset, int little_endian,
40
              int *errp);
41
static int sort_modent_by_name (const void *one, const void *two, void *n);
42
static void *arc_mmap_header (int fd, size_t headersz);
43
static void *arc_mmap_file (int fd, size_t size);
44
static int arc_mmap_writeout (int fd, void *header, size_t headersz,
45
            const char **errmsg);
46
static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
47
static int ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp,
48
          int *errp);
49
50
/* Flag to indicate "symbol not present" in ctf_archive_internal.ctfi_symdicts
51
   and ctfi_symnamedicts.  Never initialized.  */
52
static ctf_dict_t enosym;
53
54
/* Write out a CTF archive to the start of the file referenced by the passed-in
55
   fd.  The entries in CTF_DICTS are referenced by name: the names are passed in
56
   the names array, which must have CTF_DICTS entries.
57
58
   Returns 0 on success, or an errno, or an ECTF_* value.  */
59
int
60
ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
61
      const char **names, size_t threshold)
62
0
{
63
0
  const char *errmsg;
64
0
  struct ctf_archive *archdr;
65
0
  size_t i;
66
0
  char dummy = 0;
67
0
  size_t headersz;
68
0
  ssize_t namesz;
69
0
  size_t ctf_startoffs;   /* Start of the section we are working over.  */
70
0
  char *nametbl = NULL;   /* The name table.  */
71
0
  char *np;
72
0
  off_t nameoffs;
73
0
  struct ctf_archive_modent *modent;
74
75
0
  ctf_dprintf ("Writing CTF archive with %lu files\n",
76
0
         (unsigned long) ctf_dict_cnt);
77
78
  /* Figure out the size of the mmap()ed header, including the
79
     ctf_archive_modent array.  We assume that all of this needs no
80
     padding: a likely assumption, given that it's all made up of
81
     uint64_t's.  */
82
0
  headersz = sizeof (struct ctf_archive)
83
0
    + (ctf_dict_cnt * sizeof (uint64_t) * 2);
84
0
  ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
85
86
  /* From now on we work in two pieces: an mmap()ed region from zero up to the
87
     headersz, and a region updated via write() starting after that, containing
88
     all the tables.  Platforms that do not support mmap() just use write().  */
89
0
  ctf_startoffs = headersz;
90
0
  if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
91
0
    {
92
0
      errmsg = N_("ctf_arc_write(): cannot extend file while writing");
93
0
      goto err;
94
0
    }
95
96
0
  if (write (fd, &dummy, 1) < 0)
97
0
    {
98
0
      errmsg = N_("ctf_arc_write(): cannot extend file while writing");
99
0
      goto err;
100
0
    }
101
102
0
  if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
103
0
    {
104
0
      errmsg = N_("ctf_arc_write(): cannot mmap");
105
0
      goto err;
106
0
    }
107
108
  /* Fill in everything we can, which is everything other than the name
109
     table offset.  */
110
0
  archdr->ctfa_magic = htole64 (CTFA_MAGIC);
111
0
  archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
112
0
  archdr->ctfa_ctfs = htole64 (ctf_startoffs);
113
114
  /* We could validate that all CTF files have the same data model, but
115
     since any reasonable construction process will be building things of
116
     only one bitness anyway, this is pretty pointless, so just use the
117
     model of the first CTF file for all of them.  (It *is* valid to
118
     create an empty archive: the value of ctfa_model is irrelevant in
119
     this case, but we must be sure not to dereference uninitialized
120
     memory.)  */
121
122
0
  if (ctf_dict_cnt > 0)
123
0
    archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
124
125
  /* Now write out the CTFs: ctf_archive_modent array via the mapping,
126
     ctfs via write().  The names themselves have not been written yet: we
127
     track them in a local strtab until the time is right, and sort the
128
     modents array after construction.
129
130
    The name table is not sorted.  */
131
132
0
  for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
133
0
    namesz += strlen (names[i]) + 1;
134
135
0
  nametbl = malloc (namesz);
136
0
  if (nametbl == NULL)
137
0
    {
138
0
      errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
139
0
      goto err_unmap;
140
0
    }
141
142
0
  for (i = 0, namesz = 0,
143
0
       modent = (ctf_archive_modent_t *) ((char *) archdr
144
0
            + sizeof (struct ctf_archive));
145
0
       i < le64toh (archdr->ctfa_ndicts); i++)
146
0
    {
147
0
      off_t off;
148
149
0
      strcpy (&nametbl[namesz], names[i]);
150
151
0
      off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
152
0
      if ((off < 0) && (off > -ECTF_BASE))
153
0
  {
154
0
    errmsg = N_("ctf_arc_write(): cannot determine file "
155
0
          "position while writing to archive");
156
0
    goto err_free;
157
0
  }
158
0
      if (off < 0)
159
0
  {
160
0
    errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
161
0
    errno = off * -1;
162
0
    goto err_free;
163
0
  }
164
165
0
      modent->name_offset = htole64 (namesz);
166
0
      modent->ctf_offset = htole64 (off - ctf_startoffs);
167
0
      namesz += strlen (names[i]) + 1;
168
0
      modent++;
169
0
    }
170
171
0
  ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
172
0
           + sizeof (struct ctf_archive)),
173
0
         le64toh (archdr->ctfa_ndicts),
174
0
         sizeof (struct ctf_archive_modent), sort_modent_by_name,
175
0
         nametbl);
176
177
   /* Now the name table.  */
178
179
0
  if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
180
0
    {
181
0
      errmsg = N_("ctf_arc_write(): cannot get current file position "
182
0
      "in archive");
183
0
      goto err_free;
184
0
    }
185
0
  archdr->ctfa_names = htole64 (nameoffs);
186
0
  np = nametbl;
187
0
  while (namesz > 0)
188
0
    {
189
0
      ssize_t len;
190
0
      if ((len = write (fd, np, namesz)) < 0)
191
0
  {
192
0
    errmsg = N_("ctf_arc_write(): cannot write name table to archive");
193
0
    goto err_free;
194
0
  }
195
0
      namesz -= len;
196
0
      np += len;
197
0
    }
198
0
  free (nametbl);
199
200
0
  if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
201
0
    goto err_unmap;
202
0
  if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
203
0
    goto err;
204
0
  return 0;
205
206
0
err_free:
207
0
  free (nametbl);
208
0
err_unmap:
209
0
  arc_mmap_unmap (archdr, headersz, NULL);
210
0
err:
211
  /* We report errors into the first file in the archive, if any: if this is a
212
     zero-file archive, put it in the open-errors stream for lack of anywhere
213
     else for it to go.  */
214
0
  ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
215
0
    gettext (errmsg));
216
0
  return errno;
217
0
}
218
219
/* Write out a CTF archive.  The entries in CTF_DICTS are referenced by name:
220
   the names are passed in the names array, which must have CTF_DICTS entries.
221
222
   If the filename is NULL, create a temporary file and return a pointer to it.
223
224
   Returns 0 on success, or an errno, or an ECTF_* value.  */
225
int
226
ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
227
         const char **names, size_t threshold)
228
0
{
229
0
  int err;
230
0
  int fd;
231
232
0
  if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
233
0
    {
234
0
      ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
235
0
        _("ctf_arc_write(): cannot create %s"), file);
236
0
      return errno;
237
0
    }
238
239
0
  err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
240
0
  if (err)
241
0
    goto err_close;
242
243
0
  if ((err = close (fd)) < 0)
244
0
    ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
245
0
      _("ctf_arc_write(): cannot close after writing to archive"));
246
0
  goto err;
247
248
0
 err_close:
249
0
  (void) close (fd);
250
0
 err:
251
0
  if (err < 0)
252
0
    unlink (file);
253
254
0
  return err;
255
0
}
256
257
/* Write one CTF dict out.  Return the file position of the written file (or
258
   rather, of the file-size uint64_t that precedes it): negative return is a
259
   negative errno or ctf_errno value.  On error, the file position may no longer
260
   be at the end of the file.  */
261
static off_t
262
arc_write_one_ctf (ctf_dict_t *f, int fd, size_t threshold)
263
0
{
264
0
  off_t off, end_off;
265
0
  uint64_t ctfsz = 0;
266
0
  char *ctfszp;
267
0
  size_t ctfsz_len;
268
269
0
  if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
270
0
    return errno * -1;
271
272
  /* This zero-write turns into the size in a moment. */
273
0
  ctfsz_len = sizeof (ctfsz);
274
0
  ctfszp = (char *) &ctfsz;
275
0
  while (ctfsz_len > 0)
276
0
    {
277
0
      ssize_t writelen = write (fd, ctfszp, ctfsz_len);
278
0
      if (writelen < 0)
279
0
  return errno * -1;
280
0
      ctfsz_len -= writelen;
281
0
      ctfszp += writelen;
282
0
    }
283
284
0
  if (ctf_write_thresholded (f, fd, threshold) != 0)
285
0
    return f->ctf_errno * -1;
286
287
0
  if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
288
0
    return errno * -1;
289
0
  ctfsz = htole64 (end_off - off);
290
291
0
  if ((lseek (fd, off, SEEK_SET)) < 0)
292
0
    return errno * -1;
293
294
  /* ... here.  */
295
0
  ctfsz_len = sizeof (ctfsz);
296
0
  ctfszp = (char *) &ctfsz;
297
0
  while (ctfsz_len > 0)
298
0
    {
299
0
      ssize_t writelen = write (fd, ctfszp, ctfsz_len);
300
0
      if (writelen < 0)
301
0
  return errno * -1;
302
0
      ctfsz_len -= writelen;
303
0
      ctfszp += writelen;
304
0
    }
305
306
0
  end_off = LCTF_ALIGN_OFFS (end_off, 8);
307
0
  if ((lseek (fd, end_off, SEEK_SET)) < 0)
308
0
    return errno * -1;
309
310
0
  return off;
311
0
}
312
313
/* qsort() function to sort the array of struct ctf_archive_modents into
314
   ascending name order.  */
315
static int
316
sort_modent_by_name (const void *one, const void *two, void *n)
317
0
{
318
0
  const struct ctf_archive_modent *a = one;
319
0
  const struct ctf_archive_modent *b = two;
320
0
  char *nametbl = n;
321
322
0
  return strcmp (&nametbl[le64toh (a->name_offset)],
323
0
     &nametbl[le64toh (b->name_offset)]);
324
0
}
325
326
/* bsearch_r() function to search for a given name in the sorted array of struct
327
   ctf_archive_modents.  */
328
static int
329
search_modent_by_name (const void *key, const void *ent, void *arg)
330
0
{
331
0
  const char *k = key;
332
0
  const struct ctf_archive_modent *v = ent;
333
0
  const char *search_nametbl = arg;
334
335
0
  return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
336
0
}
337
338
/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
339
   ctf_dict.  Closes ARC and/or FP on error.  Arrange to free the SYMSECT or
340
   STRSECT, as needed, on close.  Possibly do not unmap on close.  */
341
342
struct ctf_archive_internal *
343
ctf_new_archive_internal (int is_archive, int unmap_on_close,
344
        struct ctf_archive *arc,
345
        ctf_dict_t *fp, const ctf_sect_t *symsect,
346
        const ctf_sect_t *strsect,
347
        int *errp)
348
0
{
349
0
  struct ctf_archive_internal *arci;
350
351
0
  if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
352
0
    {
353
0
      if (is_archive)
354
0
  {
355
0
    if (unmap_on_close)
356
0
      ctf_arc_close_internal (arc);
357
0
  }
358
0
      else
359
0
  ctf_dict_close (fp);
360
0
      return (ctf_set_open_errno (errp, errno));
361
0
    }
362
0
  arci->ctfi_is_archive = is_archive;
363
0
  if (is_archive)
364
0
    arci->ctfi_archive = arc;
365
0
  else
366
0
    arci->ctfi_dict = fp;
367
0
  if (symsect)
368
0
     memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
369
0
  if (strsect)
370
0
     memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
371
0
  arci->ctfi_free_symsect = 0;
372
0
  arci->ctfi_free_strsect = 0;
373
0
  arci->ctfi_unmap_on_close = unmap_on_close;
374
0
  arci->ctfi_symsect_little_endian = -1;
375
376
0
  return arci;
377
0
}
378
379
/* Set the symbol-table endianness of an archive (defaulting the symtab
380
   endianness of all ctf_file_t's opened from that archive).  */
381
void
382
ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
383
0
{
384
0
  arc->ctfi_symsect_little_endian = !!little_endian;
385
0
  if (!arc->ctfi_is_archive)
386
0
    ctf_symsect_endianness (arc->ctfi_dict, arc->ctfi_symsect_little_endian);
387
0
}
388
389
/* Get the CTF preamble from data in a buffer, which may be either an archive or
390
   a CTF dict.  If multiple dicts are present in an archive, the preamble comes
391
   from an arbitrary dict.  The preamble is a pointer into the ctfsect passed
392
   in.  Returns NULL if this cannot be a CTF archive or dict at all.  */
393
394
const ctf_preamble_t *
395
ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
396
0
{
397
0
  if (ctfsect->cts_data == NULL
398
0
      || ctfsect->cts_size < sizeof (uint64_t)
399
0
      || (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC
400
0
    && ctfsect->cts_size < (sizeof (ctf_archive_t) + sizeof (uint64_t))))
401
0
    return NULL;
402
403
0
  if (ctfsect->cts_size >= (sizeof (struct ctf_archive) + sizeof (uint64_t))
404
0
      && le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC)
405
0
    {
406
0
      struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
407
0
      return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
408
0
               + sizeof (uint64_t));
409
0
    }
410
0
  else
411
0
    return (const ctf_preamble_t *) ctfsect->cts_data;
412
0
}
413
414
/* Open a CTF archive or dictionary from data in a buffer (which the caller must
415
   preserve until ctf_arc_close() time).  Returns the archive, or NULL and an
416
   error in *err (if not NULL).  */
417
ctf_archive_t *
418
ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
419
     const ctf_sect_t *strsect, int *errp)
420
0
{
421
0
  struct ctf_archive *arc = NULL;
422
0
  int is_archive;
423
0
  ctf_dict_t *fp = NULL;
424
425
0
  if (ctfsect->cts_data != NULL
426
0
      && ctfsect->cts_size >= sizeof (struct ctf_archive)
427
0
      && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
428
0
    {
429
      /* The archive is mmappable, so this operation is trivial.
430
431
   This buffer is nonmodifiable, so the trick involving mmapping only part
432
   of it and storing the length in the magic number is not applicable: so
433
   record this fact in the archive-wrapper header.  (We cannot record it
434
   in the archive, because the archive may very well be a read-only
435
   mapping.)  */
436
437
0
      is_archive = 1;
438
0
      arc = (struct ctf_archive *) ctfsect->cts_data;
439
0
    }
440
0
  else
441
0
    {
442
0
      is_archive = 0;
443
0
      if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
444
0
  {
445
0
    ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
446
0
    return NULL;
447
0
  }
448
0
    }
449
0
  return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
450
0
           errp);
451
0
}
452
453
/* Open a CTF archive.  Returns the archive, or NULL and an error in *err (if
454
   not NULL).  */
455
struct ctf_archive *
456
ctf_arc_open_internal (const char *filename, int *errp)
457
0
{
458
0
  const char *errmsg;
459
0
  int fd;
460
0
  struct stat s;
461
0
  struct ctf_archive *arc;    /* (Actually the whole file.)  */
462
463
0
  libctf_init_debug();
464
0
  if ((fd = open (filename, O_RDONLY)) < 0)
465
0
    {
466
0
      errmsg = N_("ctf_arc_open(): cannot open %s");
467
0
      goto err;
468
0
    }
469
0
  if (fstat (fd, &s) < 0)
470
0
    {
471
0
      errmsg = N_("ctf_arc_open(): cannot stat %s");
472
0
      goto err_close;
473
0
    }
474
475
0
  if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
476
0
    {
477
0
      errmsg = N_("ctf_arc_open(): cannot read in %s");
478
0
      goto err_close;
479
0
    }
480
481
0
  if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
482
0
    {
483
0
      errmsg = N_("ctf_arc_open(): %s: invalid magic number");
484
0
      errno = ECTF_FMT;
485
0
      goto err_unmap;
486
0
    }
487
488
  /* This horrible hack lets us know how much to unmap when the file is
489
     closed.  (We no longer need the magic number, and the mapping
490
     is private.)  */
491
0
  arc->ctfa_magic = s.st_size;
492
0
  close (fd);
493
494
0
  if (errp)
495
0
    *errp = 0;
496
497
0
  return arc;
498
499
0
err_unmap:
500
0
  arc_mmap_unmap (arc, s.st_size, NULL);
501
0
err_close:
502
0
  close (fd);
503
0
err:
504
0
  if (errp)
505
0
    *errp = errno;
506
0
  ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
507
0
  return NULL;
508
0
}
509
510
/* Close an archive.  */
511
void
512
ctf_arc_close_internal (struct ctf_archive *arc)
513
0
{
514
0
  if (arc == NULL)
515
0
    return;
516
517
  /* See the comment in ctf_arc_open().  */
518
0
  arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
519
0
}
520
521
/* Public entry point: close an archive, or CTF file.  */
522
void
523
ctf_arc_close (ctf_archive_t *arc)
524
0
{
525
0
  if (arc == NULL)
526
0
    return;
527
528
0
  if (arc->ctfi_is_archive)
529
0
    {
530
0
      if (arc->ctfi_unmap_on_close)
531
0
  ctf_arc_close_internal (arc->ctfi_archive);
532
0
    }
533
0
  else
534
0
    ctf_dict_close (arc->ctfi_dict);
535
0
  free (arc->ctfi_symdicts);
536
0
  free (arc->ctfi_symnamedicts);
537
0
  ctf_dynhash_destroy (arc->ctfi_dicts);
538
0
  if (arc->ctfi_free_symsect)
539
0
    free ((void *) arc->ctfi_symsect.cts_data);
540
0
  if (arc->ctfi_free_strsect)
541
0
    free ((void *) arc->ctfi_strsect.cts_data);
542
0
  free (arc->ctfi_data);
543
0
  if (arc->ctfi_bfd_close)
544
0
    arc->ctfi_bfd_close (arc);
545
0
  free (arc);
546
0
}
547
548
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
549
   non-NULL.  A name of NULL means to open the default file.  */
550
static ctf_dict_t *
551
ctf_dict_open_internal (const struct ctf_archive *arc,
552
      const ctf_sect_t *symsect,
553
      const ctf_sect_t *strsect,
554
      const char *name, int little_endian,
555
      int *errp)
556
0
{
557
0
  struct ctf_archive_modent *modent;
558
0
  const char *search_nametbl;
559
560
0
  if (name == NULL)
561
0
    name = _CTF_SECTION;    /* The default name.  */
562
563
0
  ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
564
565
0
  modent = (ctf_archive_modent_t *) ((char *) arc
566
0
             + sizeof (struct ctf_archive));
567
568
0
  search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
569
0
  modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
570
0
          sizeof (struct ctf_archive_modent),
571
0
          search_modent_by_name, (void *) search_nametbl);
572
573
  /* This is actually a common case and normal operation: no error
574
     debug output.  */
575
0
  if (modent == NULL)
576
0
    {
577
0
      if (errp)
578
0
  *errp = ECTF_ARNNAME;
579
0
      return NULL;
580
0
    }
581
582
0
  return ctf_dict_open_by_offset (arc, symsect, strsect,
583
0
          le64toh (modent->ctf_offset),
584
0
          little_endian, errp);
585
0
}
586
587
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
588
   non-NULL.  A name of NULL means to open the default file.
589
590
   Use the specified string and symbol table sections.
591
592
   Public entry point.  */
593
ctf_dict_t *
594
ctf_dict_open_sections (const ctf_archive_t *arc,
595
      const ctf_sect_t *symsect,
596
      const ctf_sect_t *strsect,
597
      const char *name,
598
      int *errp)
599
0
{
600
0
  if (errp)
601
0
    *errp = 0;
602
603
0
  if (arc->ctfi_is_archive)
604
0
    {
605
0
      ctf_dict_t *ret;
606
0
      ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
607
0
            name, arc->ctfi_symsect_little_endian,
608
0
            errp);
609
0
      if (ret)
610
0
  {
611
0
    ret->ctf_archive = (ctf_archive_t *) arc;
612
0
    if (ctf_arc_import_parent (arc, ret, errp) < 0)
613
0
      {
614
0
        ctf_dict_close (ret);
615
0
        return NULL;
616
0
      }
617
0
  }
618
0
      return ret;
619
0
    }
620
621
0
  if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
622
0
    {
623
0
      if (errp)
624
0
  *errp = ECTF_ARNNAME;
625
0
      return NULL;
626
0
    }
627
0
  arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
628
629
  /* Bump the refcount so that the user can ctf_dict_close() it.  */
630
0
  arc->ctfi_dict->ctf_refcnt++;
631
0
  return arc->ctfi_dict;
632
0
}
633
634
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
635
   non-NULL.  A name of NULL means to open the default file.
636
637
   Public entry point.  */
638
ctf_dict_t *
639
ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
640
0
{
641
0
  const ctf_sect_t *symsect = &arc->ctfi_symsect;
642
0
  const ctf_sect_t *strsect = &arc->ctfi_strsect;
643
644
0
  if (symsect->cts_name == NULL)
645
0
    symsect = NULL;
646
0
  if (strsect->cts_name == NULL)
647
0
    strsect = NULL;
648
649
0
  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
650
0
}
651
652
static void
653
ctf_cached_dict_close (void *fp)
654
0
{
655
0
  ctf_dict_close ((ctf_dict_t *) fp);
656
0
}
657
658
/* Return the ctf_dict_t with the given name and cache it in the archive's
659
   ctfi_dicts.  If this is the first cached dict, designate it the
660
   crossdict_cache.  */
661
static ctf_dict_t *
662
ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
663
0
{
664
0
  ctf_dict_t *fp;
665
0
  char *dupname;
666
667
  /* Just return from the cache if possible.  */
668
0
  if (arc->ctfi_dicts
669
0
      && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
670
0
    {
671
0
      fp->ctf_refcnt++;
672
0
      return fp;
673
0
    }
674
675
  /* Not yet cached: open it.  */
676
0
  fp = ctf_dict_open (arc, name, errp);
677
0
  dupname = strdup (name);
678
679
0
  if (!fp || !dupname)
680
0
    goto oom;
681
682
0
  if (arc->ctfi_dicts == NULL)
683
0
    if ((arc->ctfi_dicts
684
0
   = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
685
0
             free, ctf_cached_dict_close)) == NULL)
686
0
      goto oom;
687
688
0
  if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
689
0
    goto oom;
690
0
  fp->ctf_refcnt++;
691
692
0
  if (arc->ctfi_crossdict_cache == NULL)
693
0
    arc->ctfi_crossdict_cache = fp;
694
695
0
  return fp;
696
697
0
 oom:
698
0
  ctf_dict_close (fp);
699
0
  free (dupname);
700
0
  if (errp)
701
0
    *errp = ENOMEM;
702
0
  return NULL;
703
0
}
704
705
/* Flush any caches the CTF archive may have open.  */
706
void
707
ctf_arc_flush_caches (ctf_archive_t *wrapper)
708
0
{
709
0
  free (wrapper->ctfi_symdicts);
710
0
  ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
711
0
  ctf_dynhash_destroy (wrapper->ctfi_dicts);
712
0
  wrapper->ctfi_symdicts = NULL;
713
0
  wrapper->ctfi_symnamedicts = NULL;
714
0
  wrapper->ctfi_dicts = NULL;
715
0
  wrapper->ctfi_crossdict_cache = NULL;
716
0
}
717
718
/* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
719
   none, setting 'err' if non-NULL.  */
720
static ctf_dict_t *
721
ctf_dict_open_by_offset (const struct ctf_archive *arc,
722
       const ctf_sect_t *symsect,
723
       const ctf_sect_t *strsect, size_t offset,
724
       int little_endian, int *errp)
725
0
{
726
0
  ctf_sect_t ctfsect;
727
0
  ctf_dict_t *fp;
728
729
0
  ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
730
731
0
  memset (&ctfsect, 0, sizeof (ctf_sect_t));
732
733
0
  offset += le64toh (arc->ctfa_ctfs);
734
735
0
  ctfsect.cts_name = _CTF_SECTION;
736
0
  ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
737
0
  ctfsect.cts_entsize = 1;
738
0
  ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
739
0
  fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
740
0
  if (fp)
741
0
    {
742
0
      ctf_setmodel (fp, le64toh (arc->ctfa_model));
743
0
      if (little_endian >= 0)
744
0
  ctf_symsect_endianness (fp, little_endian);
745
0
    }
746
0
  return fp;
747
0
}
748
749
/* Backward compatibility.  */
750
ctf_dict_t *
751
ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
752
          int *errp)
753
0
{
754
0
  return ctf_dict_open (arc, name, errp);
755
0
}
756
757
ctf_dict_t *
758
ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
759
             const ctf_sect_t *symsect,
760
             const ctf_sect_t *strsect,
761
             const char *name,
762
             int *errp)
763
0
{
764
0
  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
765
0
}
766
767
/* Import the parent into a ctf archive, if this is a child, the parent is not
768
   already set, and a suitable archive member exists.  No error is raised if
769
   this is not possible: this is just a best-effort helper operation to give
770
   people useful dicts to start with.  */
771
static int
772
ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
773
0
{
774
0
  if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
775
0
    {
776
0
      int err = 0;
777
0
      ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
778
0
             fp->ctf_parname, &err);
779
0
      if (errp)
780
0
  *errp = err;
781
782
0
      if (parent)
783
0
  {
784
0
    ctf_import (fp, parent);
785
0
    ctf_dict_close (parent);
786
0
  }
787
0
      else if (err != ECTF_ARNNAME)
788
0
  return -1;       /* errno is set for us.  */
789
0
    }
790
0
  return 0;
791
0
}
792
793
/* Return the number of members in an archive.  */
794
size_t
795
ctf_archive_count (const ctf_archive_t *wrapper)
796
0
{
797
0
  if (!wrapper->ctfi_is_archive)
798
0
    return 1;
799
800
0
  return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
801
0
}
802
803
/* Look up a symbol in an archive by name or index (if the name is set, a lookup
804
   by name is done).  Return the dict in the archive that the symbol is found
805
   in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
806
   have to look it up yourself).  The dict is cached, so repeated lookups are
807
   nearly free.
808
809
   As usual, you should ctf_dict_close() the returned dict once you are done
810
   with it.
811
812
   Returns NULL on error, and an error in errp (if set).  */
813
814
static ctf_dict_t *
815
ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
816
          const char *symname, ctf_id_t *typep, int *errp)
817
0
{
818
0
  ctf_dict_t *fp;
819
0
  void *fpkey;
820
0
  ctf_id_t type;
821
822
  /* The usual non-archive-transparent-wrapper special case.  */
823
0
  if (!wrapper->ctfi_is_archive)
824
0
    {
825
0
      if (!symname)
826
0
  {
827
0
    if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
828
0
      {
829
0
        if (errp)
830
0
    *errp = ctf_errno (wrapper->ctfi_dict);
831
0
        return NULL;
832
0
      }
833
0
  }
834
0
      else
835
0
  {
836
0
    if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
837
0
             symname)) == CTF_ERR)
838
0
      {
839
0
        if (errp)
840
0
    *errp = ctf_errno (wrapper->ctfi_dict);
841
0
        return NULL;
842
0
      }
843
0
  }
844
0
      if (typep)
845
0
  *typep = type;
846
0
      wrapper->ctfi_dict->ctf_refcnt++;
847
0
      return wrapper->ctfi_dict;
848
0
    }
849
850
0
  if (wrapper->ctfi_symsect.cts_name == NULL
851
0
      || wrapper->ctfi_symsect.cts_data == NULL
852
0
      || wrapper->ctfi_symsect.cts_size == 0
853
0
      || wrapper->ctfi_symsect.cts_entsize == 0)
854
0
    {
855
0
      if (errp)
856
0
  *errp = ECTF_NOSYMTAB;
857
0
      return NULL;
858
0
    }
859
860
  /* Make enough space for all possible symbol indexes, if not already done.  We
861
     cache the originating dictionary of all symbols.  The dict links are weak,
862
     to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
863
     We also cache similar mappings for symbol names: these are ordinary
864
     dynhashes, with weak links to dicts.  */
865
866
0
  if (!wrapper->ctfi_symdicts)
867
0
    {
868
0
      if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
869
0
              / wrapper->ctfi_symsect.cts_entsize,
870
0
              sizeof (ctf_dict_t *))) == NULL)
871
0
  {
872
0
    if (errp)
873
0
      *errp = ENOMEM;
874
0
    return NULL;
875
0
  }
876
0
    }
877
0
  if (!wrapper->ctfi_symnamedicts)
878
0
    {
879
0
      if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
880
0
                  ctf_hash_eq_string,
881
0
                  free, NULL)) == NULL)
882
0
  {
883
0
    if (errp)
884
0
      *errp = ENOMEM;
885
0
    return NULL;
886
0
  }
887
0
    }
888
889
  /* Perhaps the dict in which we found a previous lookup is cached.  If it's
890
     supposed to be cached but we don't find it, pretend it was always not
891
     found: this should never happen, but shouldn't be allowed to cause trouble
892
     if it does.  */
893
894
0
  if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
895
0
           symname, NULL, &fpkey))
896
0
      || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
897
0
    {
898
0
      if (symname)
899
0
  fp = (ctf_dict_t *) fpkey;
900
0
      else
901
0
  fp = wrapper->ctfi_symdicts[symidx];
902
903
0
      if (fp == &enosym)
904
0
  goto no_sym;
905
906
0
      if (symname)
907
0
  {
908
0
    if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
909
0
      goto cache_no_sym;
910
0
  }
911
0
      else
912
0
  {
913
0
    if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
914
0
      goto cache_no_sym;
915
0
  }
916
917
0
      if (typep)
918
0
  *typep = type;
919
0
      fp->ctf_refcnt++;
920
0
      return fp;
921
0
    }
922
923
  /* Not cached: find it and cache it.  We must track open errors ourselves even
924
     if our caller doesn't, to be able to distinguish no-error end-of-iteration
925
     from open errors.  */
926
927
0
  int local_err;
928
0
  int *local_errp;
929
0
  ctf_next_t *i = NULL;
930
0
  const char *name;
931
932
0
  if (errp)
933
0
    local_errp = errp;
934
0
  else
935
0
    local_errp = &local_err;
936
937
0
  while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
938
0
    {
939
0
      if (!symname)
940
0
  {
941
0
    if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
942
0
      wrapper->ctfi_symdicts[symidx] = fp;
943
0
  }
944
0
      else
945
0
  {
946
0
    if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
947
0
      {
948
0
        char *tmp;
949
        /* No error checking, as above.  */
950
0
        if ((tmp = strdup (symname)) != NULL)
951
0
    ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
952
0
      }
953
0
  }
954
955
0
      if (type != CTF_ERR)
956
0
  {
957
0
    if (typep)
958
0
      *typep = type;
959
0
    ctf_next_destroy (i);
960
0
    return fp;
961
0
  }
962
0
      if (ctf_errno (fp) != ECTF_NOTYPEDAT)
963
0
  {
964
0
    if (errp)
965
0
      *errp = ctf_errno (fp);
966
0
    ctf_dict_close (fp);
967
0
    ctf_next_destroy (i);
968
0
    return NULL;       /* errno is set for us.  */
969
0
  }
970
0
      ctf_dict_close (fp);
971
0
    }
972
0
  if (*local_errp != ECTF_NEXT_END)
973
0
    {
974
0
      ctf_next_destroy (i);
975
0
      return NULL;
976
0
    }
977
978
  /* Don't leak end-of-iteration to the caller.  */
979
0
  *local_errp = 0;
980
981
0
 cache_no_sym:
982
0
  if (!symname)
983
0
    wrapper->ctfi_symdicts[symidx] = &enosym;
984
0
  else
985
0
    {
986
0
      char *tmp;
987
988
      /* No error checking: if caching fails, there is only a slight performance
989
   impact.  */
990
0
      if ((tmp = strdup (symname)) != NULL)
991
0
  if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
992
0
    free (tmp);
993
0
    }
994
995
0
 no_sym:
996
0
  if (errp)
997
0
    *errp = ECTF_NOTYPEDAT;
998
0
  if (typep)
999
0
    *typep = CTF_ERR;
1000
0
  return NULL;
1001
0
}
1002
1003
/* The public API for looking up a symbol by index.  */
1004
ctf_dict_t *
1005
ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
1006
           ctf_id_t *typep, int *errp)
1007
0
{
1008
0
  return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
1009
0
}
1010
1011
/* The public API for looking up a symbol by name. */
1012
1013
ctf_dict_t *
1014
ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
1015
          ctf_id_t *typep, int *errp)
1016
0
{
1017
0
  return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1018
0
}
1019
1020
/* Return all enumeration constants with a given NAME across all dicts in an
1021
   archive, similar to ctf_lookup_enumerator_next.  The DICT is cached, so
1022
   opening costs are paid only once, but (unlike ctf_arc_lookup_symbol*
1023
   above) the results of the iterations are not cached.  dict and errp are
1024
   not optional.  */
1025
1026
ctf_id_t
1027
ctf_arc_lookup_enumerator_next (ctf_archive_t *arc, const char *name,
1028
        ctf_next_t **it, int64_t *enum_value,
1029
        ctf_dict_t **dict, int *errp)
1030
0
{
1031
0
  ctf_next_t *i = *it;
1032
0
  ctf_id_t type;
1033
0
  int opened_this_time = 0;
1034
0
  int err;
1035
1036
  /* We have two nested iterators in here: ctn_next tracks archives, while
1037
     within it ctn_next_inner tracks enumerators within an archive.  We
1038
     keep track of the dict by simply reusing the passed-in arg: if it's
1039
     changed by the caller, the caller will get an ECTF_WRONGFP error,
1040
     so this is quite safe and means we don't have to track the arc and fp
1041
     simultaneously in the ctf_next_t.  */
1042
1043
0
  if (!i)
1044
0
    {
1045
0
      if ((i = ctf_next_create ()) == NULL)
1046
0
  {
1047
0
    err = ENOMEM;
1048
0
    goto err;
1049
0
  }
1050
0
      i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
1051
0
      i->cu.ctn_arc = arc;
1052
0
      *it = i;
1053
0
    }
1054
1055
0
  if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
1056
0
    {
1057
0
      err = ECTF_NEXT_WRONGFUN;
1058
0
      goto err;
1059
0
    }
1060
1061
0
  if (arc != i->cu.ctn_arc)
1062
0
    {
1063
0
      err = ECTF_NEXT_WRONGFP;
1064
0
      goto err;
1065
0
    }
1066
1067
  /* Prevent any earlier end-of-iteration on this dict from confusing the
1068
     test below.  */
1069
0
  if (i->ctn_next != NULL)
1070
0
    ctf_set_errno (*dict, 0);
1071
1072
0
  do
1073
0
    {
1074
      /* At end of one dict, or not started any iterations yet?
1075
   Traverse to next dict.  If we never returned this dict to the
1076
   caller, close it ourselves: the caller will never see it and cannot
1077
   do so.  */
1078
1079
0
      if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
1080
0
  {
1081
0
    if (opened_this_time)
1082
0
      {
1083
0
        ctf_dict_close (*dict);
1084
0
        *dict = NULL;
1085
0
        opened_this_time = 0;
1086
0
      }
1087
1088
0
    *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
1089
0
    if (!*dict)
1090
0
      goto err;
1091
0
    opened_this_time = 1;
1092
0
  }
1093
1094
0
      type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
1095
0
           enum_value);
1096
0
    }
1097
0
  while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);
1098
1099
0
  if (type == CTF_ERR)
1100
0
    {
1101
0
      err = ctf_errno (*dict);
1102
0
      goto err;
1103
0
    }
1104
1105
  /* If this dict is being reused from the previous iteration, bump its
1106
     refcnt: the caller is going to close it and has no idea that we didn't
1107
     open it this time round.  */
1108
0
  if (!opened_this_time)
1109
0
    ctf_ref (*dict);
1110
1111
0
  return type;
1112
1113
0
 err:            /* Also ECTF_NEXT_END. */
1114
0
  if (opened_this_time)
1115
0
    {
1116
0
      ctf_dict_close (*dict);
1117
0
      *dict = NULL;
1118
0
    }
1119
1120
0
  ctf_next_destroy (i);
1121
0
  *it = NULL;
1122
0
  if (errp)
1123
0
    *errp = err;
1124
0
  return CTF_ERR;
1125
0
}
1126
1127
/* Raw iteration over all CTF files in an archive.  We pass the raw data for all
1128
   CTF files in turn to the specified callback function.  */
1129
static int
1130
ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1131
             ctf_archive_raw_member_f *func, void *data)
1132
0
{
1133
0
  int rc;
1134
0
  size_t i;
1135
0
  struct ctf_archive_modent *modent;
1136
0
  const char *nametbl;
1137
1138
0
  modent = (ctf_archive_modent_t *) ((char *) arc
1139
0
             + sizeof (struct ctf_archive));
1140
0
  nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1141
1142
0
  for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
1143
0
    {
1144
0
      const char *name;
1145
0
      char *fp;
1146
1147
0
      name = &nametbl[le64toh (modent[i].name_offset)];
1148
0
      fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1149
0
      + le64toh (modent[i].ctf_offset));
1150
1151
0
      if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1152
0
          le64toh (*((uint64_t *) fp)), data)) != 0)
1153
0
  return rc;
1154
0
    }
1155
0
  return 0;
1156
0
}
1157
1158
/* Raw iteration over all CTF files in an archive: public entry point.
1159
1160
   Returns -EINVAL if not supported for this sort of archive.  */
1161
int
1162
ctf_archive_raw_iter (const ctf_archive_t *arc,
1163
          ctf_archive_raw_member_f * func, void *data)
1164
0
{
1165
0
  if (arc->ctfi_is_archive)
1166
0
    return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1167
1168
0
  return -EINVAL;      /* Not supported. */
1169
0
}
1170
1171
/* Iterate over all CTF files in an archive: public entry point.  We pass all
1172
   CTF files in turn to the specified callback function.  */
1173
int
1174
ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1175
      void *data)
1176
0
{
1177
0
  ctf_next_t *i = NULL;
1178
0
  ctf_dict_t *fp;
1179
0
  const char *name;
1180
0
  int err = 0;
1181
1182
0
  while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
1183
0
    {
1184
0
      int rc;
1185
1186
0
      if ((rc = func (fp, name, data)) != 0)
1187
0
  {
1188
0
    ctf_dict_close (fp);
1189
0
    ctf_next_destroy (i);
1190
0
    return rc;
1191
0
  }
1192
0
      ctf_dict_close (fp);
1193
0
    }
1194
0
  if (err != ECTF_NEXT_END && err != 0)
1195
0
    {
1196
0
      ctf_next_destroy (i);
1197
0
      return -1;
1198
0
    }
1199
0
  return 0;
1200
0
}
1201
1202
/* Iterate over all CTF files in an archive, returning each dict in turn as a
1203
   ctf_dict_t, and NULL on error or end of iteration.  It is the caller's
1204
   responsibility to close it.  Parent dicts may be skipped.
1205
1206
   The archive member is cached for rapid return on future calls.
1207
1208
   We identify parents by name rather than by flag value: for now, with the
1209
   linker only emitting parents named _CTF_SECTION, this works well enough.  */
1210
1211
ctf_dict_t *
1212
ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1213
      int skip_parent, int *errp)
1214
0
{
1215
0
  ctf_dict_t *f;
1216
0
  ctf_next_t *i = *it;
1217
0
  struct ctf_archive *arc;
1218
0
  struct ctf_archive_modent *modent;
1219
0
  const char *nametbl;
1220
0
  const char *name_;
1221
1222
0
  if (!i)
1223
0
    {
1224
0
      if ((i = ctf_next_create()) == NULL)
1225
0
  {
1226
0
    if (errp)
1227
0
      *errp = ENOMEM;
1228
0
    return NULL;
1229
0
  }
1230
0
      i->cu.ctn_arc = wrapper;
1231
0
      i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1232
0
      *it = i;
1233
0
    }
1234
1235
0
  if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1236
0
    {
1237
0
      if (errp)
1238
0
  *errp = ECTF_NEXT_WRONGFUN;
1239
0
      return NULL;
1240
0
    }
1241
1242
0
  if (wrapper != i->cu.ctn_arc)
1243
0
    {
1244
0
      if (errp)
1245
0
  *errp = ECTF_NEXT_WRONGFP;
1246
0
      return NULL;
1247
0
    }
1248
1249
  /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1250
     transparently wrapped in a single-member archive.  These are parents: if
1251
     skip_parent is on, they are skipped and the iterator terminates
1252
     immediately.  */
1253
1254
0
  if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1255
0
    {
1256
0
      i->ctn_n++;
1257
0
      if (!skip_parent)
1258
0
  {
1259
0
    wrapper->ctfi_dict->ctf_refcnt++;
1260
0
    if (name)
1261
0
      *name = _CTF_SECTION;
1262
0
    return wrapper->ctfi_dict;
1263
0
  }
1264
0
    }
1265
1266
0
  arc = wrapper->ctfi_archive;
1267
1268
  /* The loop keeps going when skip_parent is on as long as the member we find
1269
     is the parent (i.e. at most two iterations, but possibly an early return if
1270
     *all* we have is a parent).  */
1271
1272
0
  do
1273
0
    {
1274
0
      if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1275
0
  {
1276
0
    ctf_next_destroy (i);
1277
0
    *it = NULL;
1278
0
    if (errp)
1279
0
      *errp = ECTF_NEXT_END;
1280
0
    return NULL;
1281
0
  }
1282
1283
0
      modent = (ctf_archive_modent_t *) ((char *) arc
1284
0
           + sizeof (struct ctf_archive));
1285
0
      nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1286
1287
0
      name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1288
0
      i->ctn_n++;
1289
0
    }
1290
0
  while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1291
1292
0
  if (name)
1293
0
    *name = name_;
1294
1295
0
  f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1296
0
  return f;
1297
0
}
1298
1299
#ifdef HAVE_MMAP
1300
/* Map the header in.  Only used on new, empty files.  */
1301
static void *arc_mmap_header (int fd, size_t headersz)
1302
0
{
1303
0
  void *hdr;
1304
0
  if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1305
0
       0)) == MAP_FAILED)
1306
0
    return NULL;
1307
0
  return hdr;
1308
0
}
1309
1310
/* mmap() the whole file, for reading only.  (Map it writably, but privately: we
1311
   need to modify the region, but don't need anyone else to see the
1312
   modifications.)  */
1313
static void *arc_mmap_file (int fd, size_t size)
1314
0
{
1315
0
  void *arc;
1316
0
  if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1317
0
       fd, 0)) == MAP_FAILED)
1318
0
    return NULL;
1319
0
  return arc;
1320
0
}
1321
1322
/* Persist the header to disk.  */
1323
static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1324
            size_t headersz, const char **errmsg)
1325
0
{
1326
0
    if (msync (header, headersz, MS_ASYNC) < 0)
1327
0
    {
1328
0
      if (errmsg)
1329
0
  *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1330
0
         "to %s: %s");
1331
0
      return -1;
1332
0
    }
1333
0
    return 0;
1334
0
}
1335
1336
/* Unmap the region.  */
1337
static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1338
0
{
1339
0
  if (munmap (header, headersz) < 0)
1340
0
    {
1341
0
      if (errmsg)
1342
0
  *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1343
0
         "to %s: %s");
1344
0
      return -1;
1345
0
    }
1346
0
    return 0;
1347
0
}
1348
#else
1349
/* Map the header in.  Only used on new, empty files.  */
1350
static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1351
{
1352
  void *hdr;
1353
  if ((hdr = malloc (headersz)) == NULL)
1354
    return NULL;
1355
  return hdr;
1356
}
1357
1358
/* Pull in the whole file, for reading only.  We assume the current file
1359
   position is at the start of the file.  */
1360
static void *arc_mmap_file (int fd, size_t size)
1361
{
1362
  char *data;
1363
1364
  if ((data = malloc (size)) == NULL)
1365
    return NULL;
1366
1367
  if (ctf_pread (fd, data, size, 0) < 0)
1368
    {
1369
      free (data);
1370
      return NULL;
1371
    }
1372
  return data;
1373
}
1374
1375
/* Persist the header to disk.  */
1376
static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1377
            const char **errmsg)
1378
{
1379
  ssize_t len;
1380
  char *data = (char *) header;
1381
  ssize_t count = headersz;
1382
1383
  if ((lseek (fd, 0, SEEK_SET)) < 0)
1384
    {
1385
      if (errmsg)
1386
  *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1387
         "%s: %s");
1388
      return -1;
1389
    }
1390
1391
  while (headersz > 0)
1392
    {
1393
      if ((len = write (fd, data, count)) < 0)
1394
  {
1395
    if (errmsg)
1396
      *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1397
    return len;
1398
  }
1399
      if (len == EINTR)
1400
  continue;
1401
1402
      if (len == 0)       /* EOF.  */
1403
  break;
1404
1405
      count -= len;
1406
      data += len;
1407
    }
1408
  return 0;
1409
}
1410
1411
/* Unmap the region.  */
1412
static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1413
         const char **errmsg _libctf_unused_)
1414
{
1415
  free (header);
1416
  return 0;
1417
}
1418
#endif