Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/libctf/ctf-archive.c
Line
Count
Source (jump to first uncovered line)
1
/* CTF archive files.
2
   Copyright (C) 2019-2025 Free Software Foundation, Inc.
3
4
   This file is part of libctf.
5
6
   libctf is free software; you can redistribute it and/or modify it under
7
   the terms of the GNU General Public License as published by the Free
8
   Software Foundation; either version 3, or (at your option) any later
9
   version.
10
11
   This program is distributed in the hope that it will be useful, but
12
   WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
   See the GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; see the file COPYING.  If not see
18
   <http://www.gnu.org/licenses/>.  */
19
20
#include <ctf-impl.h>
21
#include <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.  */
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
    {
401
0
      struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
402
0
      return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
403
0
               + sizeof (uint64_t));
404
0
    }
405
0
  else
406
0
    return (const ctf_preamble_t *) ctfsect->cts_data;
407
0
}
408
409
/* Open a CTF archive or dictionary from data in a buffer (which the caller must
410
   preserve until ctf_arc_close() time).  Returns the archive, or NULL and an
411
   error in *err (if not NULL).  */
412
ctf_archive_t *
413
ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
414
     const ctf_sect_t *strsect, int *errp)
415
0
{
416
0
  struct ctf_archive *arc = NULL;
417
0
  int is_archive;
418
0
  ctf_dict_t *fp = NULL;
419
420
0
  if (ctfsect->cts_data != NULL
421
0
      && ctfsect->cts_size > sizeof (uint64_t)
422
0
      && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
423
0
    {
424
      /* The archive is mmappable, so this operation is trivial.
425
426
   This buffer is nonmodifiable, so the trick involving mmapping only part
427
   of it and storing the length in the magic number is not applicable: so
428
   record this fact in the archive-wrapper header.  (We cannot record it
429
   in the archive, because the archive may very well be a read-only
430
   mapping.)  */
431
432
0
      is_archive = 1;
433
0
      arc = (struct ctf_archive *) ctfsect->cts_data;
434
0
    }
435
0
  else
436
0
    {
437
0
      is_archive = 0;
438
0
      if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
439
0
  {
440
0
    ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
441
0
    return NULL;
442
0
  }
443
0
    }
444
0
  return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
445
0
           errp);
446
0
}
447
448
/* Open a CTF archive.  Returns the archive, or NULL and an error in *err (if
449
   not NULL).  */
450
struct ctf_archive *
451
ctf_arc_open_internal (const char *filename, int *errp)
452
0
{
453
0
  const char *errmsg;
454
0
  int fd;
455
0
  struct stat s;
456
0
  struct ctf_archive *arc;    /* (Actually the whole file.)  */
457
458
0
  libctf_init_debug();
459
0
  if ((fd = open (filename, O_RDONLY)) < 0)
460
0
    {
461
0
      errmsg = N_("ctf_arc_open(): cannot open %s");
462
0
      goto err;
463
0
    }
464
0
  if (fstat (fd, &s) < 0)
465
0
    {
466
0
      errmsg = N_("ctf_arc_open(): cannot stat %s");
467
0
      goto err_close;
468
0
    }
469
470
0
  if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
471
0
    {
472
0
      errmsg = N_("ctf_arc_open(): cannot read in %s");
473
0
      goto err_close;
474
0
    }
475
476
0
  if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
477
0
    {
478
0
      errmsg = N_("ctf_arc_open(): %s: invalid magic number");
479
0
      errno = ECTF_FMT;
480
0
      goto err_unmap;
481
0
    }
482
483
  /* This horrible hack lets us know how much to unmap when the file is
484
     closed.  (We no longer need the magic number, and the mapping
485
     is private.)  */
486
0
  arc->ctfa_magic = s.st_size;
487
0
  close (fd);
488
489
0
  if (errp)
490
0
    *errp = 0;
491
492
0
  return arc;
493
494
0
err_unmap:
495
0
  arc_mmap_unmap (arc, s.st_size, NULL);
496
0
err_close:
497
0
  close (fd);
498
0
err:
499
0
  if (errp)
500
0
    *errp = errno;
501
0
  ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
502
0
  return NULL;
503
0
}
504
505
/* Close an archive.  */
506
void
507
ctf_arc_close_internal (struct ctf_archive *arc)
508
0
{
509
0
  if (arc == NULL)
510
0
    return;
511
512
  /* See the comment in ctf_arc_open().  */
513
0
  arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
514
0
}
515
516
/* Public entry point: close an archive, or CTF file.  */
517
void
518
ctf_arc_close (ctf_archive_t *arc)
519
0
{
520
0
  if (arc == NULL)
521
0
    return;
522
523
0
  if (arc->ctfi_is_archive)
524
0
    {
525
0
      if (arc->ctfi_unmap_on_close)
526
0
  ctf_arc_close_internal (arc->ctfi_archive);
527
0
    }
528
0
  else
529
0
    ctf_dict_close (arc->ctfi_dict);
530
0
  free (arc->ctfi_symdicts);
531
0
  free (arc->ctfi_symnamedicts);
532
0
  ctf_dynhash_destroy (arc->ctfi_dicts);
533
0
  if (arc->ctfi_free_symsect)
534
0
    free ((void *) arc->ctfi_symsect.cts_data);
535
0
  if (arc->ctfi_free_strsect)
536
0
    free ((void *) arc->ctfi_strsect.cts_data);
537
0
  free (arc->ctfi_data);
538
0
  if (arc->ctfi_bfd_close)
539
0
    arc->ctfi_bfd_close (arc);
540
0
  free (arc);
541
0
}
542
543
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
544
   non-NULL.  A name of NULL means to open the default file.  */
545
static ctf_dict_t *
546
ctf_dict_open_internal (const struct ctf_archive *arc,
547
      const ctf_sect_t *symsect,
548
      const ctf_sect_t *strsect,
549
      const char *name, int little_endian,
550
      int *errp)
551
0
{
552
0
  struct ctf_archive_modent *modent;
553
0
  const char *search_nametbl;
554
555
0
  if (name == NULL)
556
0
    name = _CTF_SECTION;    /* The default name.  */
557
558
0
  ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
559
560
0
  modent = (ctf_archive_modent_t *) ((char *) arc
561
0
             + sizeof (struct ctf_archive));
562
563
0
  search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
564
0
  modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
565
0
          sizeof (struct ctf_archive_modent),
566
0
          search_modent_by_name, (void *) search_nametbl);
567
568
  /* This is actually a common case and normal operation: no error
569
     debug output.  */
570
0
  if (modent == NULL)
571
0
    {
572
0
      if (errp)
573
0
  *errp = ECTF_ARNNAME;
574
0
      return NULL;
575
0
    }
576
577
0
  return ctf_dict_open_by_offset (arc, symsect, strsect,
578
0
          le64toh (modent->ctf_offset),
579
0
          little_endian, errp);
580
0
}
581
582
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
583
   non-NULL.  A name of NULL means to open the default file.
584
585
   Use the specified string and symbol table sections.
586
587
   Public entry point.  */
588
ctf_dict_t *
589
ctf_dict_open_sections (const ctf_archive_t *arc,
590
      const ctf_sect_t *symsect,
591
      const ctf_sect_t *strsect,
592
      const char *name,
593
      int *errp)
594
0
{
595
0
  if (errp)
596
0
    *errp = 0;
597
598
0
  if (arc->ctfi_is_archive)
599
0
    {
600
0
      ctf_dict_t *ret;
601
0
      ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
602
0
            name, arc->ctfi_symsect_little_endian,
603
0
            errp);
604
0
      if (ret)
605
0
  {
606
0
    ret->ctf_archive = (ctf_archive_t *) arc;
607
0
    if (ctf_arc_import_parent (arc, ret, errp) < 0)
608
0
      {
609
0
        ctf_dict_close (ret);
610
0
        return NULL;
611
0
      }
612
0
  }
613
0
      return ret;
614
0
    }
615
616
0
  if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
617
0
    {
618
0
      if (errp)
619
0
  *errp = ECTF_ARNNAME;
620
0
      return NULL;
621
0
    }
622
0
  arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
623
624
  /* Bump the refcount so that the user can ctf_dict_close() it.  */
625
0
  arc->ctfi_dict->ctf_refcnt++;
626
0
  return arc->ctfi_dict;
627
0
}
628
629
/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
630
   non-NULL.  A name of NULL means to open the default file.
631
632
   Public entry point.  */
633
ctf_dict_t *
634
ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
635
0
{
636
0
  const ctf_sect_t *symsect = &arc->ctfi_symsect;
637
0
  const ctf_sect_t *strsect = &arc->ctfi_strsect;
638
639
0
  if (symsect->cts_name == NULL)
640
0
    symsect = NULL;
641
0
  if (strsect->cts_name == NULL)
642
0
    strsect = NULL;
643
644
0
  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
645
0
}
646
647
static void
648
ctf_cached_dict_close (void *fp)
649
0
{
650
0
  ctf_dict_close ((ctf_dict_t *) fp);
651
0
}
652
653
/* Return the ctf_dict_t with the given name and cache it in the archive's
654
   ctfi_dicts.  If this is the first cached dict, designate it the
655
   crossdict_cache.  */
656
static ctf_dict_t *
657
ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
658
0
{
659
0
  ctf_dict_t *fp;
660
0
  char *dupname;
661
662
  /* Just return from the cache if possible.  */
663
0
  if (arc->ctfi_dicts
664
0
      && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
665
0
    {
666
0
      fp->ctf_refcnt++;
667
0
      return fp;
668
0
    }
669
670
  /* Not yet cached: open it.  */
671
0
  fp = ctf_dict_open (arc, name, errp);
672
0
  dupname = strdup (name);
673
674
0
  if (!fp || !dupname)
675
0
    goto oom;
676
677
0
  if (arc->ctfi_dicts == NULL)
678
0
    if ((arc->ctfi_dicts
679
0
   = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
680
0
             free, ctf_cached_dict_close)) == NULL)
681
0
      goto oom;
682
683
0
  if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
684
0
    goto oom;
685
0
  fp->ctf_refcnt++;
686
687
0
  if (arc->ctfi_crossdict_cache == NULL)
688
0
    arc->ctfi_crossdict_cache = fp;
689
690
0
  return fp;
691
692
0
 oom:
693
0
  ctf_dict_close (fp);
694
0
  free (dupname);
695
0
  if (errp)
696
0
    *errp = ENOMEM;
697
0
  return NULL;
698
0
}
699
700
/* Flush any caches the CTF archive may have open.  */
701
void
702
ctf_arc_flush_caches (ctf_archive_t *wrapper)
703
0
{
704
0
  free (wrapper->ctfi_symdicts);
705
0
  ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
706
0
  ctf_dynhash_destroy (wrapper->ctfi_dicts);
707
0
  wrapper->ctfi_symdicts = NULL;
708
0
  wrapper->ctfi_symnamedicts = NULL;
709
0
  wrapper->ctfi_dicts = NULL;
710
0
  wrapper->ctfi_crossdict_cache = NULL;
711
0
}
712
713
/* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
714
   none, setting 'err' if non-NULL.  */
715
static ctf_dict_t *
716
ctf_dict_open_by_offset (const struct ctf_archive *arc,
717
       const ctf_sect_t *symsect,
718
       const ctf_sect_t *strsect, size_t offset,
719
       int little_endian, int *errp)
720
0
{
721
0
  ctf_sect_t ctfsect;
722
0
  ctf_dict_t *fp;
723
724
0
  ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
725
726
0
  memset (&ctfsect, 0, sizeof (ctf_sect_t));
727
728
0
  offset += le64toh (arc->ctfa_ctfs);
729
730
0
  ctfsect.cts_name = _CTF_SECTION;
731
0
  ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
732
0
  ctfsect.cts_entsize = 1;
733
0
  ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
734
0
  fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
735
0
  if (fp)
736
0
    {
737
0
      ctf_setmodel (fp, le64toh (arc->ctfa_model));
738
0
      if (little_endian >= 0)
739
0
  ctf_symsect_endianness (fp, little_endian);
740
0
    }
741
0
  return fp;
742
0
}
743
744
/* Backward compatibility.  */
745
ctf_dict_t *
746
ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
747
          int *errp)
748
0
{
749
0
  return ctf_dict_open (arc, name, errp);
750
0
}
751
752
ctf_dict_t *
753
ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
754
             const ctf_sect_t *symsect,
755
             const ctf_sect_t *strsect,
756
             const char *name,
757
             int *errp)
758
0
{
759
0
  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
760
0
}
761
762
/* Import the parent into a ctf archive, if this is a child, the parent is not
763
   already set, and a suitable archive member exists.  No error is raised if
764
   this is not possible: this is just a best-effort helper operation to give
765
   people useful dicts to start with.  */
766
static int
767
ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
768
0
{
769
0
  if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
770
0
    {
771
0
      int err = 0;
772
0
      ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
773
0
             fp->ctf_parname, &err);
774
0
      if (errp)
775
0
  *errp = err;
776
777
0
      if (parent)
778
0
  {
779
0
    ctf_import (fp, parent);
780
0
    ctf_dict_close (parent);
781
0
  }
782
0
      else if (err != ECTF_ARNNAME)
783
0
  return -1;       /* errno is set for us.  */
784
0
    }
785
0
  return 0;
786
0
}
787
788
/* Return the number of members in an archive.  */
789
size_t
790
ctf_archive_count (const ctf_archive_t *wrapper)
791
0
{
792
0
  if (!wrapper->ctfi_is_archive)
793
0
    return 1;
794
795
0
  return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
796
0
}
797
798
/* Look up a symbol in an archive by name or index (if the name is set, a lookup
799
   by name is done).  Return the dict in the archive that the symbol is found
800
   in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
801
   have to look it up yourself).  The dict is cached, so repeated lookups are
802
   nearly free.
803
804
   As usual, you should ctf_dict_close() the returned dict once you are done
805
   with it.
806
807
   Returns NULL on error, and an error in errp (if set).  */
808
809
static ctf_dict_t *
810
ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
811
          const char *symname, ctf_id_t *typep, int *errp)
812
0
{
813
0
  ctf_dict_t *fp;
814
0
  void *fpkey;
815
0
  ctf_id_t type;
816
817
  /* The usual non-archive-transparent-wrapper special case.  */
818
0
  if (!wrapper->ctfi_is_archive)
819
0
    {
820
0
      if (!symname)
821
0
  {
822
0
    if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
823
0
      {
824
0
        if (errp)
825
0
    *errp = ctf_errno (wrapper->ctfi_dict);
826
0
        return NULL;
827
0
      }
828
0
  }
829
0
      else
830
0
  {
831
0
    if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
832
0
             symname)) == CTF_ERR)
833
0
      {
834
0
        if (errp)
835
0
    *errp = ctf_errno (wrapper->ctfi_dict);
836
0
        return NULL;
837
0
      }
838
0
  }
839
0
      if (typep)
840
0
  *typep = type;
841
0
      wrapper->ctfi_dict->ctf_refcnt++;
842
0
      return wrapper->ctfi_dict;
843
0
    }
844
845
0
  if (wrapper->ctfi_symsect.cts_name == NULL
846
0
      || wrapper->ctfi_symsect.cts_data == NULL
847
0
      || wrapper->ctfi_symsect.cts_size == 0
848
0
      || wrapper->ctfi_symsect.cts_entsize == 0)
849
0
    {
850
0
      if (errp)
851
0
  *errp = ECTF_NOSYMTAB;
852
0
      return NULL;
853
0
    }
854
855
  /* Make enough space for all possible symbol indexes, if not already done.  We
856
     cache the originating dictionary of all symbols.  The dict links are weak,
857
     to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
858
     We also cache similar mappings for symbol names: these are ordinary
859
     dynhashes, with weak links to dicts.  */
860
861
0
  if (!wrapper->ctfi_symdicts)
862
0
    {
863
0
      if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
864
0
              / wrapper->ctfi_symsect.cts_entsize,
865
0
              sizeof (ctf_dict_t *))) == NULL)
866
0
  {
867
0
    if (errp)
868
0
      *errp = ENOMEM;
869
0
    return NULL;
870
0
  }
871
0
    }
872
0
  if (!wrapper->ctfi_symnamedicts)
873
0
    {
874
0
      if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
875
0
                  ctf_hash_eq_string,
876
0
                  free, NULL)) == NULL)
877
0
  {
878
0
    if (errp)
879
0
      *errp = ENOMEM;
880
0
    return NULL;
881
0
  }
882
0
    }
883
884
  /* Perhaps the dict in which we found a previous lookup is cached.  If it's
885
     supposed to be cached but we don't find it, pretend it was always not
886
     found: this should never happen, but shouldn't be allowed to cause trouble
887
     if it does.  */
888
889
0
  if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
890
0
           symname, NULL, &fpkey))
891
0
      || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
892
0
    {
893
0
      if (symname)
894
0
  fp = (ctf_dict_t *) fpkey;
895
0
      else
896
0
  fp = wrapper->ctfi_symdicts[symidx];
897
898
0
      if (fp == &enosym)
899
0
  goto no_sym;
900
901
0
      if (symname)
902
0
  {
903
0
    if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
904
0
      goto cache_no_sym;
905
0
  }
906
0
      else
907
0
  {
908
0
    if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
909
0
      goto cache_no_sym;
910
0
  }
911
912
0
      if (typep)
913
0
  *typep = type;
914
0
      fp->ctf_refcnt++;
915
0
      return fp;
916
0
    }
917
918
  /* Not cached: find it and cache it.  We must track open errors ourselves even
919
     if our caller doesn't, to be able to distinguish no-error end-of-iteration
920
     from open errors.  */
921
922
0
  int local_err;
923
0
  int *local_errp;
924
0
  ctf_next_t *i = NULL;
925
0
  const char *name;
926
927
0
  if (errp)
928
0
    local_errp = errp;
929
0
  else
930
0
    local_errp = &local_err;
931
932
0
  while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
933
0
    {
934
0
      if (!symname)
935
0
  {
936
0
    if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
937
0
      wrapper->ctfi_symdicts[symidx] = fp;
938
0
  }
939
0
      else
940
0
  {
941
0
    if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
942
0
      {
943
0
        char *tmp;
944
        /* No error checking, as above.  */
945
0
        if ((tmp = strdup (symname)) != NULL)
946
0
    ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
947
0
      }
948
0
  }
949
950
0
      if (type != CTF_ERR)
951
0
  {
952
0
    if (typep)
953
0
      *typep = type;
954
0
    ctf_next_destroy (i);
955
0
    return fp;
956
0
  }
957
0
      if (ctf_errno (fp) != ECTF_NOTYPEDAT)
958
0
  {
959
0
    if (errp)
960
0
      *errp = ctf_errno (fp);
961
0
    ctf_dict_close (fp);
962
0
    ctf_next_destroy (i);
963
0
    return NULL;        /* errno is set for us.  */
964
0
  }
965
0
      ctf_dict_close (fp);
966
0
    }
967
0
  if (*local_errp != ECTF_NEXT_END)
968
0
    {
969
0
      ctf_next_destroy (i);
970
0
      return NULL;
971
0
    }
972
973
  /* Don't leak end-of-iteration to the caller.  */
974
0
  *local_errp = 0;
975
976
0
 cache_no_sym:
977
0
  if (!symname)
978
0
    wrapper->ctfi_symdicts[symidx] = &enosym;
979
0
  else
980
0
    {
981
0
      char *tmp;
982
983
      /* No error checking: if caching fails, there is only a slight performance
984
   impact.  */
985
0
      if ((tmp = strdup (symname)) != NULL)
986
0
  if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
987
0
    free (tmp);
988
0
    }
989
990
0
 no_sym:
991
0
  if (errp)
992
0
    *errp = ECTF_NOTYPEDAT;
993
0
  if (typep)
994
0
    *typep = CTF_ERR;
995
0
  return NULL;
996
0
}
997
998
/* The public API for looking up a symbol by index.  */
999
ctf_dict_t *
1000
ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
1001
           ctf_id_t *typep, int *errp)
1002
0
{
1003
0
  return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
1004
0
}
1005
1006
/* The public API for looking up a symbol by name. */
1007
1008
ctf_dict_t *
1009
ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
1010
          ctf_id_t *typep, int *errp)
1011
0
{
1012
0
  return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1013
0
}
1014
1015
/* Return all enumeration constants with a given NAME across all dicts in an
1016
   archive, similar to ctf_lookup_enumerator_next.  The DICT is cached, so
1017
   opening costs are paid only once, but (unlike ctf_arc_lookup_symbol*
1018
   above) the results of the iterations are not cached.  dict and errp are
1019
   not optional.  */
1020
1021
ctf_id_t
1022
ctf_arc_lookup_enumerator_next (ctf_archive_t *arc, const char *name,
1023
        ctf_next_t **it, int64_t *enum_value,
1024
        ctf_dict_t **dict, int *errp)
1025
0
{
1026
0
  ctf_next_t *i = *it;
1027
0
  ctf_id_t type;
1028
0
  int opened_this_time = 0;
1029
0
  int err;
1030
1031
  /* We have two nested iterators in here: ctn_next tracks archives, while
1032
     within it ctn_next_inner tracks enumerators within an archive.  We
1033
     keep track of the dict by simply reusing the passed-in arg: if it's
1034
     changed by the caller, the caller will get an ECTF_WRONGFP error,
1035
     so this is quite safe and means we don't have to track the arc and fp
1036
     simultaneously in the ctf_next_t.  */
1037
1038
0
  if (!i)
1039
0
    {
1040
0
      if ((i = ctf_next_create ()) == NULL)
1041
0
  {
1042
0
    err = ENOMEM;
1043
0
    goto err;
1044
0
  }
1045
0
      i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
1046
0
      i->cu.ctn_arc = arc;
1047
0
      *it = i;
1048
0
    }
1049
1050
0
  if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
1051
0
    {
1052
0
      err = ECTF_NEXT_WRONGFUN;
1053
0
      goto err;
1054
0
    }
1055
1056
0
  if (arc != i->cu.ctn_arc)
1057
0
    {
1058
0
      err = ECTF_NEXT_WRONGFP;
1059
0
      goto err;
1060
0
    }
1061
1062
  /* Prevent any earlier end-of-iteration on this dict from confusing the
1063
     test below.  */
1064
0
  if (i->ctn_next != NULL)
1065
0
    ctf_set_errno (*dict, 0);
1066
1067
0
  do
1068
0
    {
1069
      /* At end of one dict, or not started any iterations yet?
1070
   Traverse to next dict.  If we never returned this dict to the
1071
   caller, close it ourselves: the caller will never see it and cannot
1072
   do so.  */
1073
1074
0
      if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
1075
0
  {
1076
0
    if (opened_this_time)
1077
0
      {
1078
0
        ctf_dict_close (*dict);
1079
0
        *dict = NULL;
1080
0
        opened_this_time = 0;
1081
0
      }
1082
1083
0
    *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
1084
0
    if (!*dict)
1085
0
      goto err;
1086
0
    opened_this_time = 1;
1087
0
  }
1088
1089
0
      type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
1090
0
           enum_value);
1091
0
    }
1092
0
  while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);
1093
1094
0
  if (type == CTF_ERR)
1095
0
    {
1096
0
      err = ctf_errno (*dict);
1097
0
      goto err;
1098
0
    }
1099
1100
  /* If this dict is being reused from the previous iteration, bump its
1101
     refcnt: the caller is going to close it and has no idea that we didn't
1102
     open it this time round.  */
1103
0
  if (!opened_this_time)
1104
0
    ctf_ref (*dict);
1105
1106
0
  return type;
1107
1108
0
 err:            /* Also ECTF_NEXT_END. */
1109
0
  if (opened_this_time)
1110
0
    {
1111
0
      ctf_dict_close (*dict);
1112
0
      *dict = NULL;
1113
0
    }
1114
1115
0
  ctf_next_destroy (i);
1116
0
  *it = NULL;
1117
0
  if (errp)
1118
0
    *errp = err;
1119
0
  return CTF_ERR;
1120
0
}
1121
1122
/* Raw iteration over all CTF files in an archive.  We pass the raw data for all
1123
   CTF files in turn to the specified callback function.  */
1124
static int
1125
ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1126
             ctf_archive_raw_member_f *func, void *data)
1127
0
{
1128
0
  int rc;
1129
0
  size_t i;
1130
0
  struct ctf_archive_modent *modent;
1131
0
  const char *nametbl;
1132
1133
0
  modent = (ctf_archive_modent_t *) ((char *) arc
1134
0
             + sizeof (struct ctf_archive));
1135
0
  nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1136
1137
0
  for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
1138
0
    {
1139
0
      const char *name;
1140
0
      char *fp;
1141
1142
0
      name = &nametbl[le64toh (modent[i].name_offset)];
1143
0
      fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1144
0
      + le64toh (modent[i].ctf_offset));
1145
1146
0
      if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1147
0
          le64toh (*((uint64_t *) fp)), data)) != 0)
1148
0
  return rc;
1149
0
    }
1150
0
  return 0;
1151
0
}
1152
1153
/* Raw iteration over all CTF files in an archive: public entry point.
1154
1155
   Returns -EINVAL if not supported for this sort of archive.  */
1156
int
1157
ctf_archive_raw_iter (const ctf_archive_t *arc,
1158
          ctf_archive_raw_member_f * func, void *data)
1159
0
{
1160
0
  if (arc->ctfi_is_archive)
1161
0
    return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1162
1163
0
  return -EINVAL;      /* Not supported. */
1164
0
}
1165
1166
/* Iterate over all CTF files in an archive: public entry point.  We pass all
1167
   CTF files in turn to the specified callback function.  */
1168
int
1169
ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1170
      void *data)
1171
0
{
1172
0
  ctf_next_t *i = NULL;
1173
0
  ctf_dict_t *fp;
1174
0
  const char *name;
1175
0
  int err = 0;
1176
1177
0
  while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
1178
0
    {
1179
0
      int rc;
1180
1181
0
      if ((rc = func (fp, name, data)) != 0)
1182
0
  {
1183
0
    ctf_dict_close (fp);
1184
0
    ctf_next_destroy (i);
1185
0
    return rc;
1186
0
  }
1187
0
      ctf_dict_close (fp);
1188
0
    }
1189
0
  if (err != ECTF_NEXT_END && err != 0)
1190
0
    {
1191
0
      ctf_next_destroy (i);
1192
0
      return -1;
1193
0
    }
1194
0
  return 0;
1195
0
}
1196
1197
/* Iterate over all CTF files in an archive, returning each dict in turn as a
1198
   ctf_dict_t, and NULL on error or end of iteration.  It is the caller's
1199
   responsibility to close it.  Parent dicts may be skipped.
1200
1201
   The archive member is cached for rapid return on future calls.
1202
1203
   We identify parents by name rather than by flag value: for now, with the
1204
   linker only emitting parents named _CTF_SECTION, this works well enough.  */
1205
1206
ctf_dict_t *
1207
ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1208
      int skip_parent, int *errp)
1209
0
{
1210
0
  ctf_dict_t *f;
1211
0
  ctf_next_t *i = *it;
1212
0
  struct ctf_archive *arc;
1213
0
  struct ctf_archive_modent *modent;
1214
0
  const char *nametbl;
1215
0
  const char *name_;
1216
1217
0
  if (!i)
1218
0
    {
1219
0
      if ((i = ctf_next_create()) == NULL)
1220
0
  {
1221
0
    if (errp)
1222
0
      *errp = ENOMEM;
1223
0
    return NULL;
1224
0
  }
1225
0
      i->cu.ctn_arc = wrapper;
1226
0
      i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1227
0
      *it = i;
1228
0
    }
1229
1230
0
  if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1231
0
    {
1232
0
      if (errp)
1233
0
  *errp = ECTF_NEXT_WRONGFUN;
1234
0
      return NULL;
1235
0
    }
1236
1237
0
  if (wrapper != i->cu.ctn_arc)
1238
0
    {
1239
0
      if (errp)
1240
0
  *errp = ECTF_NEXT_WRONGFP;
1241
0
      return NULL;
1242
0
    }
1243
1244
  /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1245
     transparently wrapped in a single-member archive.  These are parents: if
1246
     skip_parent is on, they are skipped and the iterator terminates
1247
     immediately.  */
1248
1249
0
  if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1250
0
    {
1251
0
      i->ctn_n++;
1252
0
      if (!skip_parent)
1253
0
  {
1254
0
    wrapper->ctfi_dict->ctf_refcnt++;
1255
0
    if (name)
1256
0
      *name = _CTF_SECTION;
1257
0
    return wrapper->ctfi_dict;
1258
0
  }
1259
0
    }
1260
1261
0
  arc = wrapper->ctfi_archive;
1262
1263
  /* The loop keeps going when skip_parent is on as long as the member we find
1264
     is the parent (i.e. at most two iterations, but possibly an early return if
1265
     *all* we have is a parent).  */
1266
1267
0
  do
1268
0
    {
1269
0
      if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1270
0
  {
1271
0
    ctf_next_destroy (i);
1272
0
    *it = NULL;
1273
0
    if (errp)
1274
0
      *errp = ECTF_NEXT_END;
1275
0
    return NULL;
1276
0
  }
1277
1278
0
      modent = (ctf_archive_modent_t *) ((char *) arc
1279
0
           + sizeof (struct ctf_archive));
1280
0
      nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1281
1282
0
      name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1283
0
      i->ctn_n++;
1284
0
    }
1285
0
  while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1286
1287
0
  if (name)
1288
0
    *name = name_;
1289
1290
0
  f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1291
0
  return f;
1292
0
}
1293
1294
#ifdef HAVE_MMAP
1295
/* Map the header in.  Only used on new, empty files.  */
1296
static void *arc_mmap_header (int fd, size_t headersz)
1297
0
{
1298
0
  void *hdr;
1299
0
  if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1300
0
       0)) == MAP_FAILED)
1301
0
    return NULL;
1302
0
  return hdr;
1303
0
}
1304
1305
/* mmap() the whole file, for reading only.  (Map it writably, but privately: we
1306
   need to modify the region, but don't need anyone else to see the
1307
   modifications.)  */
1308
static void *arc_mmap_file (int fd, size_t size)
1309
0
{
1310
0
  void *arc;
1311
0
  if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1312
0
       fd, 0)) == MAP_FAILED)
1313
0
    return NULL;
1314
0
  return arc;
1315
0
}
1316
1317
/* Persist the header to disk.  */
1318
static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1319
            size_t headersz, const char **errmsg)
1320
0
{
1321
0
    if (msync (header, headersz, MS_ASYNC) < 0)
1322
0
    {
1323
0
      if (errmsg)
1324
0
  *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1325
0
         "to %s: %s");
1326
0
      return -1;
1327
0
    }
1328
0
    return 0;
1329
0
}
1330
1331
/* Unmap the region.  */
1332
static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1333
0
{
1334
0
  if (munmap (header, headersz) < 0)
1335
0
    {
1336
0
      if (errmsg)
1337
0
  *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1338
0
         "to %s: %s");
1339
0
      return -1;
1340
0
    }
1341
0
    return 0;
1342
0
}
1343
#else
1344
/* Map the header in.  Only used on new, empty files.  */
1345
static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1346
{
1347
  void *hdr;
1348
  if ((hdr = malloc (headersz)) == NULL)
1349
    return NULL;
1350
  return hdr;
1351
}
1352
1353
/* Pull in the whole file, for reading only.  We assume the current file
1354
   position is at the start of the file.  */
1355
static void *arc_mmap_file (int fd, size_t size)
1356
{
1357
  char *data;
1358
1359
  if ((data = malloc (size)) == NULL)
1360
    return NULL;
1361
1362
  if (ctf_pread (fd, data, size, 0) < 0)
1363
    {
1364
      free (data);
1365
      return NULL;
1366
    }
1367
  return data;
1368
}
1369
1370
/* Persist the header to disk.  */
1371
static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1372
            const char **errmsg)
1373
{
1374
  ssize_t len;
1375
  char *data = (char *) header;
1376
  ssize_t count = headersz;
1377
1378
  if ((lseek (fd, 0, SEEK_SET)) < 0)
1379
    {
1380
      if (errmsg)
1381
  *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1382
         "%s: %s");
1383
      return -1;
1384
    }
1385
1386
  while (headersz > 0)
1387
    {
1388
      if ((len = write (fd, data, count)) < 0)
1389
  {
1390
    if (errmsg)
1391
      *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1392
    return len;
1393
  }
1394
      if (len == EINTR)
1395
  continue;
1396
1397
      if (len == 0)       /* EOF.  */
1398
  break;
1399
1400
      count -= len;
1401
      data += len;
1402
    }
1403
  return 0;
1404
}
1405
1406
/* Unmap the region.  */
1407
static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1408
         const char **errmsg _libctf_unused_)
1409
{
1410
  free (header);
1411
  return 0;
1412
}
1413
#endif