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