Home | History | Annotate | Line # | Download | only in libctf
      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 {
     63   const char *errmsg;
     64   struct ctf_archive *archdr;
     65   size_t i;
     66   char dummy = 0;
     67   size_t headersz;
     68   ssize_t namesz;
     69   size_t ctf_startoffs;		/* Start of the section we are working over.  */
     70   char *nametbl = NULL;		/* The name table.  */
     71   char *np;
     72   off_t nameoffs;
     73   struct ctf_archive_modent *modent;
     74 
     75   ctf_dprintf ("Writing CTF archive with %lu files\n",
     76 	       (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   headersz = sizeof (struct ctf_archive)
     83     + (ctf_dict_cnt * sizeof (uint64_t) * 2);
     84   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   ctf_startoffs = headersz;
     90   if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
     91     {
     92       errmsg = N_("ctf_arc_write(): cannot extend file while writing");
     93       goto err;
     94     }
     95 
     96   if (write (fd, &dummy, 1) < 0)
     97     {
     98       errmsg = N_("ctf_arc_write(): cannot extend file while writing");
     99       goto err;
    100     }
    101 
    102   if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
    103     {
    104       errmsg = N_("ctf_arc_write(): cannot mmap");
    105       goto err;
    106     }
    107 
    108   /* Fill in everything we can, which is everything other than the name
    109      table offset.  */
    110   archdr->ctfa_magic = htole64 (CTFA_MAGIC);
    111   archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
    112   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   if (ctf_dict_cnt > 0)
    123     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   for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
    133     namesz += strlen (names[i]) + 1;
    134 
    135   nametbl = malloc (namesz);
    136   if (nametbl == NULL)
    137     {
    138       errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
    139       goto err_unmap;
    140     }
    141 
    142   for (i = 0, namesz = 0,
    143        modent = (ctf_archive_modent_t *) ((char *) archdr
    144 					  + sizeof (struct ctf_archive));
    145        i < le64toh (archdr->ctfa_ndicts); i++)
    146     {
    147       off_t off;
    148 
    149       strcpy (&nametbl[namesz], names[i]);
    150 
    151       off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
    152       if ((off < 0) && (off > -ECTF_BASE))
    153 	{
    154 	  errmsg = N_("ctf_arc_write(): cannot determine file "
    155 		      "position while writing to archive");
    156 	  goto err_free;
    157 	}
    158       if (off < 0)
    159 	{
    160 	  errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
    161 	  errno = off * -1;
    162 	  goto err_free;
    163 	}
    164 
    165       modent->name_offset = htole64 (namesz);
    166       modent->ctf_offset = htole64 (off - ctf_startoffs);
    167       namesz += strlen (names[i]) + 1;
    168       modent++;
    169     }
    170 
    171   ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
    172 					 + sizeof (struct ctf_archive)),
    173 	       le64toh (archdr->ctfa_ndicts),
    174 	       sizeof (struct ctf_archive_modent), sort_modent_by_name,
    175 	       nametbl);
    176 
    177    /* Now the name table.  */
    178 
    179   if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
    180     {
    181       errmsg = N_("ctf_arc_write(): cannot get current file position "
    182 		  "in archive");
    183       goto err_free;
    184     }
    185   archdr->ctfa_names = htole64 (nameoffs);
    186   np = nametbl;
    187   while (namesz > 0)
    188     {
    189       ssize_t len;
    190       if ((len = write (fd, np, namesz)) < 0)
    191 	{
    192 	  errmsg = N_("ctf_arc_write(): cannot write name table to archive");
    193 	  goto err_free;
    194 	}
    195       namesz -= len;
    196       np += len;
    197     }
    198   free (nametbl);
    199 
    200   if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
    201     goto err_unmap;
    202   if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
    203     goto err;
    204   return 0;
    205 
    206 err_free:
    207   free (nametbl);
    208 err_unmap:
    209   arc_mmap_unmap (archdr, headersz, NULL);
    210 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   ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
    215 		gettext (errmsg));
    216   return errno;
    217 }
    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 {
    229   int err;
    230   int fd;
    231 
    232   if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
    233     {
    234       ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
    235 		    _("ctf_arc_write(): cannot create %s"), file);
    236       return errno;
    237     }
    238 
    239   err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
    240   if (err)
    241     goto err_close;
    242 
    243   if ((err = close (fd)) < 0)
    244     ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
    245 		  _("ctf_arc_write(): cannot close after writing to archive"));
    246   goto err;
    247 
    248  err_close:
    249   (void) close (fd);
    250  err:
    251   if (err < 0)
    252     unlink (file);
    253 
    254   return err;
    255 }
    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 {
    264   off_t off, end_off;
    265   uint64_t ctfsz = 0;
    266   char *ctfszp;
    267   size_t ctfsz_len;
    268 
    269   if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
    270     return errno * -1;
    271 
    272   /* This zero-write turns into the size in a moment. */
    273   ctfsz_len = sizeof (ctfsz);
    274   ctfszp = (char *) &ctfsz;
    275   while (ctfsz_len > 0)
    276     {
    277       ssize_t writelen = write (fd, ctfszp, ctfsz_len);
    278       if (writelen < 0)
    279 	return errno * -1;
    280       ctfsz_len -= writelen;
    281       ctfszp += writelen;
    282     }
    283 
    284   if (ctf_write_thresholded (f, fd, threshold) != 0)
    285     return f->ctf_errno * -1;
    286 
    287   if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
    288     return errno * -1;
    289   ctfsz = htole64 (end_off - off);
    290 
    291   if ((lseek (fd, off, SEEK_SET)) < 0)
    292     return errno * -1;
    293 
    294   /* ... here.  */
    295   ctfsz_len = sizeof (ctfsz);
    296   ctfszp = (char *) &ctfsz;
    297   while (ctfsz_len > 0)
    298     {
    299       ssize_t writelen = write (fd, ctfszp, ctfsz_len);
    300       if (writelen < 0)
    301 	return errno * -1;
    302       ctfsz_len -= writelen;
    303       ctfszp += writelen;
    304     }
    305 
    306   end_off = LCTF_ALIGN_OFFS (end_off, 8);
    307   if ((lseek (fd, end_off, SEEK_SET)) < 0)
    308     return errno * -1;
    309 
    310   return off;
    311 }
    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 {
    318   const struct ctf_archive_modent *a = one;
    319   const struct ctf_archive_modent *b = two;
    320   char *nametbl = n;
    321 
    322   return strcmp (&nametbl[le64toh (a->name_offset)],
    323 		 &nametbl[le64toh (b->name_offset)]);
    324 }
    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 {
    331   const char *k = key;
    332   const struct ctf_archive_modent *v = ent;
    333   const char *search_nametbl = arg;
    334 
    335   return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
    336 }
    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 {
    349   struct ctf_archive_internal *arci;
    350 
    351   if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
    352     {
    353       if (is_archive)
    354 	{
    355 	  if (unmap_on_close)
    356 	    ctf_arc_close_internal (arc);
    357 	}
    358       else
    359 	ctf_dict_close (fp);
    360       return (ctf_set_open_errno (errp, errno));
    361     }
    362   arci->ctfi_is_archive = is_archive;
    363   if (is_archive)
    364     arci->ctfi_archive = arc;
    365   else
    366     arci->ctfi_dict = fp;
    367   if (symsect)
    368      memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
    369   if (strsect)
    370      memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
    371   arci->ctfi_free_symsect = 0;
    372   arci->ctfi_free_strsect = 0;
    373   arci->ctfi_unmap_on_close = unmap_on_close;
    374   arci->ctfi_symsect_little_endian = -1;
    375 
    376   return arci;
    377 }
    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 {
    384   arc->ctfi_symsect_little_endian = !!little_endian;
    385   if (!arc->ctfi_is_archive)
    386     ctf_symsect_endianness (arc->ctfi_dict, arc->ctfi_symsect_little_endian);
    387 }
    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 {
    397   if (ctfsect->cts_data != NULL
    398       && ctfsect->cts_size >= sizeof (struct ctf_archive)
    399       && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
    400     {
    401       struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
    402       return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
    403 				       + sizeof (uint64_t));
    404     }
    405   else
    406     return (const ctf_preamble_t *) ctfsect->cts_data;
    407 }
    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 {
    416   struct ctf_archive *arc = NULL;
    417   int is_archive;
    418   ctf_dict_t *fp = NULL;
    419 
    420   if (ctfsect->cts_data != NULL
    421       && ctfsect->cts_size >= sizeof (struct ctf_archive)
    422       && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
    423     {
    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       is_archive = 1;
    433       arc = (struct ctf_archive *) ctfsect->cts_data;
    434     }
    435   else
    436     {
    437       is_archive = 0;
    438       if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
    439 	{
    440 	  ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
    441 	  return NULL;
    442 	}
    443     }
    444   return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
    445 				   errp);
    446 }
    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 {
    453   const char *errmsg;
    454   int fd;
    455   struct stat s;
    456   struct ctf_archive *arc;		/* (Actually the whole file.)  */
    457 
    458   libctf_init_debug();
    459   if ((fd = open (filename, O_RDONLY)) < 0)
    460     {
    461       errmsg = N_("ctf_arc_open(): cannot open %s");
    462       goto err;
    463     }
    464   if (fstat (fd, &s) < 0)
    465     {
    466       errmsg = N_("ctf_arc_open(): cannot stat %s");
    467       goto err_close;
    468     }
    469 
    470   if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
    471     {
    472       errmsg = N_("ctf_arc_open(): cannot read in %s");
    473       goto err_close;
    474     }
    475 
    476   if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
    477     {
    478       errmsg = N_("ctf_arc_open(): %s: invalid magic number");
    479       errno = ECTF_FMT;
    480       goto err_unmap;
    481     }
    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   arc->ctfa_magic = s.st_size;
    487   close (fd);
    488 
    489   if (errp)
    490     *errp = 0;
    491 
    492   return arc;
    493 
    494 err_unmap:
    495   arc_mmap_unmap (arc, s.st_size, NULL);
    496 err_close:
    497   close (fd);
    498 err:
    499   if (errp)
    500     *errp = errno;
    501   ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
    502   return NULL;
    503 }
    504 
    505 /* Close an archive.  */
    506 void
    507 ctf_arc_close_internal (struct ctf_archive *arc)
    508 {
    509   if (arc == NULL)
    510     return;
    511 
    512   /* See the comment in ctf_arc_open().  */
    513   arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
    514 }
    515 
    516 /* Public entry point: close an archive, or CTF file.  */
    517 void
    518 ctf_arc_close (ctf_archive_t *arc)
    519 {
    520   if (arc == NULL)
    521     return;
    522 
    523   if (arc->ctfi_is_archive)
    524     {
    525       if (arc->ctfi_unmap_on_close)
    526 	ctf_arc_close_internal (arc->ctfi_archive);
    527     }
    528   else
    529     ctf_dict_close (arc->ctfi_dict);
    530   free (arc->ctfi_symdicts);
    531   free (arc->ctfi_symnamedicts);
    532   ctf_dynhash_destroy (arc->ctfi_dicts);
    533   if (arc->ctfi_free_symsect)
    534     free ((void *) arc->ctfi_symsect.cts_data);
    535   if (arc->ctfi_free_strsect)
    536     free ((void *) arc->ctfi_strsect.cts_data);
    537   free (arc->ctfi_data);
    538   if (arc->ctfi_bfd_close)
    539     arc->ctfi_bfd_close (arc);
    540   free (arc);
    541 }
    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 {
    552   struct ctf_archive_modent *modent;
    553   const char *search_nametbl;
    554 
    555   if (name == NULL)
    556     name = _CTF_SECTION;		 /* The default name.  */
    557 
    558   ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
    559 
    560   modent = (ctf_archive_modent_t *) ((char *) arc
    561 				     + sizeof (struct ctf_archive));
    562 
    563   search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
    564   modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
    565 		      sizeof (struct ctf_archive_modent),
    566 		      search_modent_by_name, (void *) search_nametbl);
    567 
    568   /* This is actually a common case and normal operation: no error
    569      debug output.  */
    570   if (modent == NULL)
    571     {
    572       if (errp)
    573 	*errp = ECTF_ARNNAME;
    574       return NULL;
    575     }
    576 
    577   return ctf_dict_open_by_offset (arc, symsect, strsect,
    578 				  le64toh (modent->ctf_offset),
    579 				  little_endian, errp);
    580 }
    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 {
    595   if (errp)
    596     *errp = 0;
    597 
    598   if (arc->ctfi_is_archive)
    599     {
    600       ctf_dict_t *ret;
    601       ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
    602 				    name, arc->ctfi_symsect_little_endian,
    603 				    errp);
    604       if (ret)
    605 	{
    606 	  ret->ctf_archive = (ctf_archive_t *) arc;
    607 	  if (ctf_arc_import_parent (arc, ret, errp) < 0)
    608 	    {
    609 	      ctf_dict_close (ret);
    610 	      return NULL;
    611 	    }
    612 	}
    613       return ret;
    614     }
    615 
    616   if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
    617     {
    618       if (errp)
    619 	*errp = ECTF_ARNNAME;
    620       return NULL;
    621     }
    622   arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
    623 
    624   /* Bump the refcount so that the user can ctf_dict_close() it.  */
    625   arc->ctfi_dict->ctf_refcnt++;
    626   return arc->ctfi_dict;
    627 }
    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 {
    636   const ctf_sect_t *symsect = &arc->ctfi_symsect;
    637   const ctf_sect_t *strsect = &arc->ctfi_strsect;
    638 
    639   if (symsect->cts_name == NULL)
    640     symsect = NULL;
    641   if (strsect->cts_name == NULL)
    642     strsect = NULL;
    643 
    644   return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
    645 }
    646 
    647 static void
    648 ctf_cached_dict_close (void *fp)
    649 {
    650   ctf_dict_close ((ctf_dict_t *) fp);
    651 }
    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 {
    659   ctf_dict_t *fp;
    660   char *dupname;
    661 
    662   /* Just return from the cache if possible.  */
    663   if (arc->ctfi_dicts
    664       && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
    665     {
    666       fp->ctf_refcnt++;
    667       return fp;
    668     }
    669 
    670   /* Not yet cached: open it.  */
    671   fp = ctf_dict_open (arc, name, errp);
    672   dupname = strdup (name);
    673 
    674   if (!fp || !dupname)
    675     goto oom;
    676 
    677   if (arc->ctfi_dicts == NULL)
    678     if ((arc->ctfi_dicts
    679 	 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
    680 			       free, ctf_cached_dict_close)) == NULL)
    681       goto oom;
    682 
    683   if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
    684     goto oom;
    685   fp->ctf_refcnt++;
    686 
    687   if (arc->ctfi_crossdict_cache == NULL)
    688     arc->ctfi_crossdict_cache = fp;
    689 
    690   return fp;
    691 
    692  oom:
    693   ctf_dict_close (fp);
    694   free (dupname);
    695   if (errp)
    696     *errp = ENOMEM;
    697   return NULL;
    698 }
    699 
    700 /* Flush any caches the CTF archive may have open.  */
    701 void
    702 ctf_arc_flush_caches (ctf_archive_t *wrapper)
    703 {
    704   free (wrapper->ctfi_symdicts);
    705   ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
    706   ctf_dynhash_destroy (wrapper->ctfi_dicts);
    707   wrapper->ctfi_symdicts = NULL;
    708   wrapper->ctfi_symnamedicts = NULL;
    709   wrapper->ctfi_dicts = NULL;
    710   wrapper->ctfi_crossdict_cache = NULL;
    711 }
    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 {
    721   ctf_sect_t ctfsect;
    722   ctf_dict_t *fp;
    723 
    724   ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
    725 
    726   memset (&ctfsect, 0, sizeof (ctf_sect_t));
    727 
    728   offset += le64toh (arc->ctfa_ctfs);
    729 
    730   ctfsect.cts_name = _CTF_SECTION;
    731   ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
    732   ctfsect.cts_entsize = 1;
    733   ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
    734   fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
    735   if (fp)
    736     {
    737       ctf_setmodel (fp, le64toh (arc->ctfa_model));
    738       if (little_endian >= 0)
    739 	ctf_symsect_endianness (fp, little_endian);
    740     }
    741   return fp;
    742 }
    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 {
    749   return ctf_dict_open (arc, name, errp);
    750 }
    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 {
    759   return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
    760 }
    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 {
    769   if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
    770     {
    771       int err = 0;
    772       ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
    773 						 fp->ctf_parname, &err);
    774       if (errp)
    775 	*errp = err;
    776 
    777       if (parent)
    778 	{
    779 	  ctf_import (fp, parent);
    780 	  ctf_dict_close (parent);
    781 	}
    782       else if (err != ECTF_ARNNAME)
    783 	return -1;				/* errno is set for us.  */
    784     }
    785   return 0;
    786 }
    787 
    788 /* Return the number of members in an archive.  */
    789 size_t
    790 ctf_archive_count (const ctf_archive_t *wrapper)
    791 {
    792   if (!wrapper->ctfi_is_archive)
    793     return 1;
    794 
    795   return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
    796 }
    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 {
    813   ctf_dict_t *fp;
    814   void *fpkey;
    815   ctf_id_t type;
    816 
    817   /* The usual non-archive-transparent-wrapper special case.  */
    818   if (!wrapper->ctfi_is_archive)
    819     {
    820       if (!symname)
    821 	{
    822 	  if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
    823 	    {
    824 	      if (errp)
    825 		*errp = ctf_errno (wrapper->ctfi_dict);
    826 	      return NULL;
    827 	    }
    828 	}
    829       else
    830 	{
    831 	  if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
    832 						 symname)) == CTF_ERR)
    833 	    {
    834 	      if (errp)
    835 		*errp = ctf_errno (wrapper->ctfi_dict);
    836 	      return NULL;
    837 	    }
    838 	}
    839       if (typep)
    840 	*typep = type;
    841       wrapper->ctfi_dict->ctf_refcnt++;
    842       return wrapper->ctfi_dict;
    843     }
    844 
    845   if (wrapper->ctfi_symsect.cts_name == NULL
    846       || wrapper->ctfi_symsect.cts_data == NULL
    847       || wrapper->ctfi_symsect.cts_size == 0
    848       || wrapper->ctfi_symsect.cts_entsize == 0)
    849     {
    850       if (errp)
    851 	*errp = ECTF_NOSYMTAB;
    852       return NULL;
    853     }
    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   if (!wrapper->ctfi_symdicts)
    862     {
    863       if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
    864 					    / wrapper->ctfi_symsect.cts_entsize,
    865 					    sizeof (ctf_dict_t *))) == NULL)
    866 	{
    867 	  if (errp)
    868 	    *errp = ENOMEM;
    869 	  return NULL;
    870 	}
    871     }
    872   if (!wrapper->ctfi_symnamedicts)
    873     {
    874       if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
    875 							    ctf_hash_eq_string,
    876 							    free, NULL)) == NULL)
    877 	{
    878 	  if (errp)
    879 	    *errp = ENOMEM;
    880 	  return NULL;
    881 	}
    882     }
    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   if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
    890 					 symname, NULL, &fpkey))
    891       || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
    892     {
    893       if (symname)
    894 	fp = (ctf_dict_t *) fpkey;
    895       else
    896 	fp = wrapper->ctfi_symdicts[symidx];
    897 
    898       if (fp == &enosym)
    899 	goto no_sym;
    900 
    901       if (symname)
    902 	{
    903 	  if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
    904 	    goto cache_no_sym;
    905 	}
    906       else
    907 	{
    908 	  if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
    909 	    goto cache_no_sym;
    910 	}
    911 
    912       if (typep)
    913 	*typep = type;
    914       fp->ctf_refcnt++;
    915       return fp;
    916     }
    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   int local_err;
    923   int *local_errp;
    924   ctf_next_t *i = NULL;
    925   const char *name;
    926 
    927   if (errp)
    928     local_errp = errp;
    929   else
    930     local_errp = &local_err;
    931 
    932   while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
    933     {
    934       if (!symname)
    935 	{
    936 	  if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
    937 	    wrapper->ctfi_symdicts[symidx] = fp;
    938 	}
    939       else
    940 	{
    941 	  if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
    942 	    {
    943 	      char *tmp;
    944 	      /* No error checking, as above.  */
    945 	      if ((tmp = strdup (symname)) != NULL)
    946 		ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
    947 	    }
    948 	}
    949 
    950       if (type != CTF_ERR)
    951 	{
    952 	  if (typep)
    953 	    *typep = type;
    954 	  ctf_next_destroy (i);
    955 	  return fp;
    956 	}
    957       if (ctf_errno (fp) != ECTF_NOTYPEDAT)
    958 	{
    959 	  if (errp)
    960 	    *errp = ctf_errno (fp);
    961 	  ctf_dict_close (fp);
    962 	  ctf_next_destroy (i);
    963 	  return NULL;				/* errno is set for us.  */
    964 	}
    965       ctf_dict_close (fp);
    966     }
    967   if (*local_errp != ECTF_NEXT_END)
    968     {
    969       ctf_next_destroy (i);
    970       return NULL;
    971     }
    972 
    973   /* Don't leak end-of-iteration to the caller.  */
    974   *local_errp = 0;
    975 
    976  cache_no_sym:
    977   if (!symname)
    978     wrapper->ctfi_symdicts[symidx] = &enosym;
    979   else
    980     {
    981       char *tmp;
    982 
    983       /* No error checking: if caching fails, there is only a slight performance
    984 	 impact.  */
    985       if ((tmp = strdup (symname)) != NULL)
    986 	if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
    987 	  free (tmp);
    988     }
    989 
    990  no_sym:
    991   if (errp)
    992     *errp = ECTF_NOTYPEDAT;
    993   if (typep)
    994     *typep = CTF_ERR;
    995   return NULL;
    996 }
    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 {
   1003   return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
   1004 }
   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 {
   1012   return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
   1013 }
   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 {
   1026   ctf_next_t *i = *it;
   1027   ctf_id_t type;
   1028   int opened_this_time = 0;
   1029   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   if (!i)
   1039     {
   1040       if ((i = ctf_next_create ()) == NULL)
   1041 	{
   1042 	  err = ENOMEM;
   1043 	  goto err;
   1044 	}
   1045       i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
   1046       i->cu.ctn_arc = arc;
   1047       *it = i;
   1048     }
   1049 
   1050   if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
   1051     {
   1052       err = ECTF_NEXT_WRONGFUN;
   1053       goto err;
   1054     }
   1055 
   1056   if (arc != i->cu.ctn_arc)
   1057     {
   1058       err = ECTF_NEXT_WRONGFP;
   1059       goto err;
   1060     }
   1061 
   1062   /* Prevent any earlier end-of-iteration on this dict from confusing the
   1063      test below.  */
   1064   if (i->ctn_next != NULL)
   1065     ctf_set_errno (*dict, 0);
   1066 
   1067   do
   1068     {
   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       if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
   1075 	{
   1076 	  if (opened_this_time)
   1077 	    {
   1078 	      ctf_dict_close (*dict);
   1079 	      *dict = NULL;
   1080 	      opened_this_time = 0;
   1081 	    }
   1082 
   1083 	  *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
   1084 	  if (!*dict)
   1085 	    goto err;
   1086 	  opened_this_time = 1;
   1087 	}
   1088 
   1089       type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
   1090 					 enum_value);
   1091     }
   1092   while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);
   1093 
   1094   if (type == CTF_ERR)
   1095     {
   1096       err = ctf_errno (*dict);
   1097       goto err;
   1098     }
   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   if (!opened_this_time)
   1104     ctf_ref (*dict);
   1105 
   1106   return type;
   1107 
   1108  err:						/* Also ECTF_NEXT_END. */
   1109   if (opened_this_time)
   1110     {
   1111       ctf_dict_close (*dict);
   1112       *dict = NULL;
   1113     }
   1114 
   1115   ctf_next_destroy (i);
   1116   *it = NULL;
   1117   if (errp)
   1118     *errp = err;
   1119   return CTF_ERR;
   1120 }
   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 {
   1128   int rc;
   1129   size_t i;
   1130   struct ctf_archive_modent *modent;
   1131   const char *nametbl;
   1132 
   1133   modent = (ctf_archive_modent_t *) ((char *) arc
   1134 				     + sizeof (struct ctf_archive));
   1135   nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
   1136 
   1137   for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
   1138     {
   1139       const char *name;
   1140       char *fp;
   1141 
   1142       name = &nametbl[le64toh (modent[i].name_offset)];
   1143       fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
   1144 	    + le64toh (modent[i].ctf_offset));
   1145 
   1146       if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
   1147 		      le64toh (*((uint64_t *) fp)), data)) != 0)
   1148 	return rc;
   1149     }
   1150   return 0;
   1151 }
   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 {
   1160   if (arc->ctfi_is_archive)
   1161     return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
   1162 
   1163   return -EINVAL;			 /* Not supported. */
   1164 }
   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 {
   1172   ctf_next_t *i = NULL;
   1173   ctf_dict_t *fp;
   1174   const char *name;
   1175   int err = 0;
   1176 
   1177   while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
   1178     {
   1179       int rc;
   1180 
   1181       if ((rc = func (fp, name, data)) != 0)
   1182 	{
   1183 	  ctf_dict_close (fp);
   1184 	  ctf_next_destroy (i);
   1185 	  return rc;
   1186 	}
   1187       ctf_dict_close (fp);
   1188     }
   1189   if (err != ECTF_NEXT_END && err != 0)
   1190     {
   1191       ctf_next_destroy (i);
   1192       return -1;
   1193     }
   1194   return 0;
   1195 }
   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 {
   1210   ctf_dict_t *f;
   1211   ctf_next_t *i = *it;
   1212   struct ctf_archive *arc;
   1213   struct ctf_archive_modent *modent;
   1214   const char *nametbl;
   1215   const char *name_;
   1216 
   1217   if (!i)
   1218     {
   1219       if ((i = ctf_next_create()) == NULL)
   1220 	{
   1221 	  if (errp)
   1222 	    *errp = ENOMEM;
   1223 	  return NULL;
   1224 	}
   1225       i->cu.ctn_arc = wrapper;
   1226       i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
   1227       *it = i;
   1228     }
   1229 
   1230   if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
   1231     {
   1232       if (errp)
   1233 	*errp = ECTF_NEXT_WRONGFUN;
   1234       return NULL;
   1235     }
   1236 
   1237   if (wrapper != i->cu.ctn_arc)
   1238     {
   1239       if (errp)
   1240 	*errp = ECTF_NEXT_WRONGFP;
   1241       return NULL;
   1242     }
   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   if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
   1250     {
   1251       i->ctn_n++;
   1252       if (!skip_parent)
   1253 	{
   1254 	  wrapper->ctfi_dict->ctf_refcnt++;
   1255 	  if (name)
   1256 	    *name = _CTF_SECTION;
   1257 	  return wrapper->ctfi_dict;
   1258 	}
   1259     }
   1260 
   1261   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   do
   1268     {
   1269       if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
   1270 	{
   1271 	  ctf_next_destroy (i);
   1272 	  *it = NULL;
   1273 	  if (errp)
   1274 	    *errp = ECTF_NEXT_END;
   1275 	  return NULL;
   1276 	}
   1277 
   1278       modent = (ctf_archive_modent_t *) ((char *) arc
   1279 					 + sizeof (struct ctf_archive));
   1280       nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
   1281 
   1282       name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
   1283       i->ctn_n++;
   1284     }
   1285   while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
   1286 
   1287   if (name)
   1288     *name = name_;
   1289 
   1290   f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
   1291   return f;
   1292 }
   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 {
   1298   void *hdr;
   1299   if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
   1300 		   0)) == MAP_FAILED)
   1301     return NULL;
   1302   return hdr;
   1303 }
   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 {
   1310   void *arc;
   1311   if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
   1312 		   fd, 0)) == MAP_FAILED)
   1313     return NULL;
   1314   return arc;
   1315 }
   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 {
   1321     if (msync (header, headersz, MS_ASYNC) < 0)
   1322     {
   1323       if (errmsg)
   1324 	*errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
   1325 		     "to %s: %s");
   1326       return -1;
   1327     }
   1328     return 0;
   1329 }
   1330 
   1331 /* Unmap the region.  */
   1332 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
   1333 {
   1334   if (munmap (header, headersz) < 0)
   1335     {
   1336       if (errmsg)
   1337 	*errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
   1338 		     "to %s: %s");
   1339       return -1;
   1340     }
   1341     return 0;
   1342 }
   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
   1414