Automatic date update in version.in
[binutils-gdb.git] / libctf / ctf-archive.c
blobb73999cacb59661a98bbd98a6ada449e99b7da2c
1 /* CTF archive files.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
4 This file is part of libctf.
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.
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.
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/>. */
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>
31 #ifdef HAVE_MMAP
32 #include <sys/mman.h>
33 #endif
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);
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;
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.
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)
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;
75 ctf_dprintf ("Writing CTF archive with %lu files\n",
76 (unsigned long) ctf_dict_cnt);
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);
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)
92 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
93 goto err;
96 if (write (fd, &dummy, 1) < 0)
98 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
99 goto err;
102 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
104 errmsg = N_("ctf_arc_write(): cannot mmap");
105 goto err;
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);
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.) */
122 if (ctf_dict_cnt > 0)
123 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
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.
130 The name table is not sorted. */
132 for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
133 namesz += strlen (names[i]) + 1;
135 nametbl = malloc (namesz);
136 if (nametbl == NULL)
138 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
139 goto err_unmap;
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++)
147 off_t off;
149 strcpy (&nametbl[namesz], names[i]);
151 off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
152 if ((off < 0) && (off > -ECTF_BASE))
154 errmsg = N_("ctf_arc_write(): cannot determine file "
155 "position while writing to archive");
156 goto err_free;
158 if (off < 0)
160 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
161 errno = off * -1;
162 goto err_free;
165 modent->name_offset = htole64 (namesz);
166 modent->ctf_offset = htole64 (off - ctf_startoffs);
167 namesz += strlen (names[i]) + 1;
168 modent++;
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);
177 /* Now the name table. */
179 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
181 errmsg = N_("ctf_arc_write(): cannot get current file position "
182 "in archive");
183 goto err_free;
185 archdr->ctfa_names = htole64 (nameoffs);
186 np = nametbl;
187 while (namesz > 0)
189 ssize_t len;
190 if ((len = write (fd, np, namesz)) < 0)
192 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
193 goto err_free;
195 namesz -= len;
196 np += len;
198 free (nametbl);
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;
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;
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.
222 If the filename is NULL, create a temporary file and return a pointer to it.
224 Returns 0 on success, or an errno, or an ECTF_* value. */
226 ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
227 const char **names, size_t threshold)
229 int err;
230 int fd;
232 if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
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;
239 err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
240 if (err)
241 goto err_close;
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;
248 err_close:
249 (void) close (fd);
250 err:
251 if (err < 0)
252 unlink (file);
254 return err;
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)
264 off_t off, end_off;
265 uint64_t ctfsz = 0;
266 char *ctfszp;
267 size_t ctfsz_len;
269 if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
270 return errno * -1;
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)
277 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
278 if (writelen < 0)
279 return errno * -1;
280 ctfsz_len -= writelen;
281 ctfszp += writelen;
284 if (ctf_write_thresholded (f, fd, threshold) != 0)
285 return f->ctf_errno * -1;
287 if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
288 return errno * -1;
289 ctfsz = htole64 (end_off - off);
291 if ((lseek (fd, off, SEEK_SET)) < 0)
292 return errno * -1;
294 /* ... here. */
295 ctfsz_len = sizeof (ctfsz);
296 ctfszp = (char *) &ctfsz;
297 while (ctfsz_len > 0)
299 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
300 if (writelen < 0)
301 return errno * -1;
302 ctfsz_len -= writelen;
303 ctfszp += writelen;
306 end_off = LCTF_ALIGN_OFFS (end_off, 8);
307 if ((lseek (fd, end_off, SEEK_SET)) < 0)
308 return errno * -1;
310 return off;
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)
318 const struct ctf_archive_modent *a = one;
319 const struct ctf_archive_modent *b = two;
320 char *nametbl = n;
322 return strcmp (&nametbl[le64toh (a->name_offset)],
323 &nametbl[le64toh (b->name_offset)]);
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)
331 const char *k = key;
332 const struct ctf_archive_modent *v = ent;
333 const char *search_nametbl = arg;
335 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
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. */
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)
349 struct ctf_archive_internal *arci;
351 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
353 if (is_archive)
355 if (unmap_on_close)
356 ctf_arc_close_internal (arc);
358 else
359 ctf_dict_close (fp);
360 return (ctf_set_open_errno (errp, errno));
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;
376 return arci;
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)
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);
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. */
394 const ctf_preamble_t *
395 ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
397 if (ctfsect->cts_data != NULL
398 && ctfsect->cts_size > sizeof (uint64_t)
399 && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
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));
405 else
406 return (const ctf_preamble_t *) ctfsect->cts_data;
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)
416 struct ctf_archive *arc = NULL;
417 int is_archive;
418 ctf_dict_t *fp = NULL;
420 if (ctfsect->cts_data != NULL
421 && ctfsect->cts_size > sizeof (uint64_t)
422 && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
424 /* The archive is mmappable, so this operation is trivial.
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.) */
432 is_archive = 1;
433 arc = (struct ctf_archive *) ctfsect->cts_data;
435 else
437 is_archive = 0;
438 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
440 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
441 return NULL;
444 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
445 errp);
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)
453 const char *errmsg;
454 int fd;
455 struct stat s;
456 struct ctf_archive *arc; /* (Actually the whole file.) */
458 libctf_init_debug();
459 if ((fd = open (filename, O_RDONLY)) < 0)
461 errmsg = N_("ctf_arc_open(): cannot open %s");
462 goto err;
464 if (fstat (fd, &s) < 0)
466 errmsg = N_("ctf_arc_open(): cannot stat %s");
467 goto err_close;
470 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
472 errmsg = N_("ctf_arc_open(): cannot read in %s");
473 goto err_close;
476 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
478 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
479 errno = ECTF_FMT;
480 goto err_unmap;
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 return arc;
490 err_unmap:
491 arc_mmap_unmap (arc, s.st_size, NULL);
492 err_close:
493 close (fd);
494 err:
495 if (errp)
496 *errp = errno;
497 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
498 return NULL;
501 /* Close an archive. */
502 void
503 ctf_arc_close_internal (struct ctf_archive *arc)
505 if (arc == NULL)
506 return;
508 /* See the comment in ctf_arc_open(). */
509 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
512 /* Public entry point: close an archive, or CTF file. */
513 void
514 ctf_arc_close (ctf_archive_t *arc)
516 if (arc == NULL)
517 return;
519 if (arc->ctfi_is_archive)
521 if (arc->ctfi_unmap_on_close)
522 ctf_arc_close_internal (arc->ctfi_archive);
524 else
525 ctf_dict_close (arc->ctfi_dict);
526 free (arc->ctfi_symdicts);
527 free (arc->ctfi_symnamedicts);
528 ctf_dynhash_destroy (arc->ctfi_dicts);
529 if (arc->ctfi_free_symsect)
530 free ((void *) arc->ctfi_symsect.cts_data);
531 if (arc->ctfi_free_strsect)
532 free ((void *) arc->ctfi_strsect.cts_data);
533 free (arc->ctfi_data);
534 if (arc->ctfi_bfd_close)
535 arc->ctfi_bfd_close (arc);
536 free (arc);
539 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
540 non-NULL. A name of NULL means to open the default file. */
541 static ctf_dict_t *
542 ctf_dict_open_internal (const struct ctf_archive *arc,
543 const ctf_sect_t *symsect,
544 const ctf_sect_t *strsect,
545 const char *name, int little_endian,
546 int *errp)
548 struct ctf_archive_modent *modent;
549 const char *search_nametbl;
551 if (name == NULL)
552 name = _CTF_SECTION; /* The default name. */
554 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
556 modent = (ctf_archive_modent_t *) ((char *) arc
557 + sizeof (struct ctf_archive));
559 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
560 modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
561 sizeof (struct ctf_archive_modent),
562 search_modent_by_name, (void *) search_nametbl);
564 /* This is actually a common case and normal operation: no error
565 debug output. */
566 if (modent == NULL)
568 if (errp)
569 *errp = ECTF_ARNNAME;
570 return NULL;
573 return ctf_dict_open_by_offset (arc, symsect, strsect,
574 le64toh (modent->ctf_offset),
575 little_endian, errp);
578 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
579 non-NULL. A name of NULL means to open the default file.
581 Use the specified string and symbol table sections.
583 Public entry point. */
584 ctf_dict_t *
585 ctf_dict_open_sections (const ctf_archive_t *arc,
586 const ctf_sect_t *symsect,
587 const ctf_sect_t *strsect,
588 const char *name,
589 int *errp)
591 if (arc->ctfi_is_archive)
593 ctf_dict_t *ret;
594 ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
595 name, arc->ctfi_symsect_little_endian,
596 errp);
597 if (ret)
599 ret->ctf_archive = (ctf_archive_t *) arc;
600 if (ctf_arc_import_parent (arc, ret, errp) < 0)
602 ctf_dict_close (ret);
603 return NULL;
606 return ret;
609 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
611 if (errp)
612 *errp = ECTF_ARNNAME;
613 return NULL;
615 arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
617 /* Bump the refcount so that the user can ctf_dict_close() it. */
618 arc->ctfi_dict->ctf_refcnt++;
619 return arc->ctfi_dict;
622 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
623 non-NULL. A name of NULL means to open the default file.
625 Public entry point. */
626 ctf_dict_t *
627 ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
629 const ctf_sect_t *symsect = &arc->ctfi_symsect;
630 const ctf_sect_t *strsect = &arc->ctfi_strsect;
632 if (symsect->cts_name == NULL)
633 symsect = NULL;
634 if (strsect->cts_name == NULL)
635 strsect = NULL;
637 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
640 static void
641 ctf_cached_dict_close (void *fp)
643 ctf_dict_close ((ctf_dict_t *) fp);
646 /* Return the ctf_dict_t with the given name and cache it in the archive's
647 ctfi_dicts. If this is the first cached dict, designate it the
648 crossdict_cache. */
649 static ctf_dict_t *
650 ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
652 ctf_dict_t *fp;
653 char *dupname;
655 /* Just return from the cache if possible. */
656 if (arc->ctfi_dicts
657 && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
659 fp->ctf_refcnt++;
660 return fp;
663 /* Not yet cached: open it. */
664 fp = ctf_dict_open (arc, name, errp);
665 dupname = strdup (name);
667 if (!fp || !dupname)
668 goto oom;
670 if (arc->ctfi_dicts == NULL)
671 if ((arc->ctfi_dicts
672 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
673 free, ctf_cached_dict_close)) == NULL)
674 goto oom;
676 if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
677 goto oom;
678 fp->ctf_refcnt++;
680 if (arc->ctfi_crossdict_cache == NULL)
681 arc->ctfi_crossdict_cache = fp;
683 return fp;
685 oom:
686 ctf_dict_close (fp);
687 free (dupname);
688 if (errp)
689 *errp = ENOMEM;
690 return NULL;
693 /* Flush any caches the CTF archive may have open. */
694 void
695 ctf_arc_flush_caches (ctf_archive_t *wrapper)
697 free (wrapper->ctfi_symdicts);
698 ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
699 ctf_dynhash_destroy (wrapper->ctfi_dicts);
700 wrapper->ctfi_symdicts = NULL;
701 wrapper->ctfi_symnamedicts = NULL;
702 wrapper->ctfi_dicts = NULL;
703 wrapper->ctfi_crossdict_cache = NULL;
706 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
707 none, setting 'err' if non-NULL. */
708 static ctf_dict_t *
709 ctf_dict_open_by_offset (const struct ctf_archive *arc,
710 const ctf_sect_t *symsect,
711 const ctf_sect_t *strsect, size_t offset,
712 int little_endian, int *errp)
714 ctf_sect_t ctfsect;
715 ctf_dict_t *fp;
717 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
719 memset (&ctfsect, 0, sizeof (ctf_sect_t));
721 offset += le64toh (arc->ctfa_ctfs);
723 ctfsect.cts_name = _CTF_SECTION;
724 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
725 ctfsect.cts_entsize = 1;
726 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
727 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
728 if (fp)
730 ctf_setmodel (fp, le64toh (arc->ctfa_model));
731 if (little_endian >= 0)
732 ctf_symsect_endianness (fp, little_endian);
734 return fp;
737 /* Backward compatibility. */
738 ctf_dict_t *
739 ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
740 int *errp)
742 return ctf_dict_open (arc, name, errp);
745 ctf_dict_t *
746 ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
747 const ctf_sect_t *symsect,
748 const ctf_sect_t *strsect,
749 const char *name,
750 int *errp)
752 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
755 /* Import the parent into a ctf archive, if this is a child, the parent is not
756 already set, and a suitable archive member exists. No error is raised if
757 this is not possible: this is just a best-effort helper operation to give
758 people useful dicts to start with. */
759 static int
760 ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
762 if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
764 int err;
765 ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
766 fp->ctf_parname, &err);
767 if (errp)
768 *errp = err;
770 if (parent)
772 ctf_import (fp, parent);
773 ctf_dict_close (parent);
775 else if (err != ECTF_ARNNAME)
776 return -1; /* errno is set for us. */
778 return 0;
781 /* Return the number of members in an archive. */
782 size_t
783 ctf_archive_count (const ctf_archive_t *wrapper)
785 if (!wrapper->ctfi_is_archive)
786 return 1;
788 return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
791 /* Look up a symbol in an archive by name or index (if the name is set, a lookup
792 by name is done). Return the dict in the archive that the symbol is found
793 in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
794 have to look it up yourself). The dict is cached, so repeated lookups are
795 nearly free.
797 As usual, you should ctf_dict_close() the returned dict once you are done
798 with it.
800 Returns NULL on error, and an error in errp (if set). */
802 static ctf_dict_t *
803 ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
804 const char *symname, ctf_id_t *typep, int *errp)
806 ctf_dict_t *fp;
807 void *fpkey;
808 ctf_id_t type;
810 /* The usual non-archive-transparent-wrapper special case. */
811 if (!wrapper->ctfi_is_archive)
813 if (!symname)
815 if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
817 if (errp)
818 *errp = ctf_errno (wrapper->ctfi_dict);
819 return NULL;
822 else
824 if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
825 symname)) == CTF_ERR)
827 if (errp)
828 *errp = ctf_errno (wrapper->ctfi_dict);
829 return NULL;
832 if (typep)
833 *typep = type;
834 wrapper->ctfi_dict->ctf_refcnt++;
835 return wrapper->ctfi_dict;
838 if (wrapper->ctfi_symsect.cts_name == NULL
839 || wrapper->ctfi_symsect.cts_data == NULL
840 || wrapper->ctfi_symsect.cts_size == 0
841 || wrapper->ctfi_symsect.cts_entsize == 0)
843 if (errp)
844 *errp = ECTF_NOSYMTAB;
845 return NULL;
848 /* Make enough space for all possible symbol indexes, if not already done. We
849 cache the originating dictionary of all symbols. The dict links are weak,
850 to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
851 We also cache similar mappings for symbol names: these are ordinary
852 dynhashes, with weak links to dicts. */
854 if (!wrapper->ctfi_symdicts)
856 if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
857 / wrapper->ctfi_symsect.cts_entsize,
858 sizeof (ctf_dict_t *))) == NULL)
860 if (errp)
861 *errp = ENOMEM;
862 return NULL;
865 if (!wrapper->ctfi_symnamedicts)
867 if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
868 ctf_hash_eq_string,
869 free, NULL)) == NULL)
871 if (errp)
872 *errp = ENOMEM;
873 return NULL;
877 /* Perhaps the dict in which we found a previous lookup is cached. If it's
878 supposed to be cached but we don't find it, pretend it was always not
879 found: this should never happen, but shouldn't be allowed to cause trouble
880 if it does. */
882 if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
883 symname, NULL, &fpkey))
884 || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
886 if (symname)
887 fp = (ctf_dict_t *) fpkey;
888 else
889 fp = wrapper->ctfi_symdicts[symidx];
891 if (fp == &enosym)
892 goto no_sym;
894 if (symname)
896 if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
897 goto cache_no_sym;
899 else
901 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
902 goto cache_no_sym;
905 if (typep)
906 *typep = type;
907 fp->ctf_refcnt++;
908 return fp;
911 /* Not cached: find it and cache it. We must track open errors ourselves even
912 if our caller doesn't, to be able to distinguish no-error end-of-iteration
913 from open errors. */
915 int local_err;
916 int *local_errp;
917 ctf_next_t *i = NULL;
918 const char *name;
920 if (errp)
921 local_errp = errp;
922 else
923 local_errp = &local_err;
925 while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
927 if (!symname)
929 if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
930 wrapper->ctfi_symdicts[symidx] = fp;
932 else
934 if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
936 char *tmp;
937 /* No error checking, as above. */
938 if ((tmp = strdup (symname)) != NULL)
939 ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
943 if (type != CTF_ERR)
945 if (typep)
946 *typep = type;
947 ctf_next_destroy (i);
948 return fp;
950 if (ctf_errno (fp) != ECTF_NOTYPEDAT)
952 if (errp)
953 *errp = ctf_errno (fp);
954 ctf_dict_close (fp);
955 ctf_next_destroy (i);
956 return NULL; /* errno is set for us. */
958 ctf_dict_close (fp);
960 if (*local_errp != ECTF_NEXT_END)
962 ctf_next_destroy (i);
963 return NULL;
966 /* Don't leak end-of-iteration to the caller. */
967 *local_errp = 0;
969 cache_no_sym:
970 if (!symname)
971 wrapper->ctfi_symdicts[symidx] = &enosym;
972 else
974 char *tmp;
976 /* No error checking: if caching fails, there is only a slight performance
977 impact. */
978 if ((tmp = strdup (symname)) != NULL)
979 if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
980 free (tmp);
983 no_sym:
984 if (errp)
985 *errp = ECTF_NOTYPEDAT;
986 if (typep)
987 *typep = CTF_ERR;
988 return NULL;
991 /* The public API for looking up a symbol by index. */
992 ctf_dict_t *
993 ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
994 ctf_id_t *typep, int *errp)
996 return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
999 /* The public API for looking up a symbol by name. */
1001 ctf_dict_t *
1002 ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
1003 ctf_id_t *typep, int *errp)
1005 return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1008 /* Return all enumeration constants with a given NAME across all dicts in an
1009 archive, similar to ctf_lookup_enumerator_next. The DICT is cached, so
1010 opening costs are paid only once, but (unlike ctf_arc_lookup_symbol*
1011 above) the results of the iterations are not cached. dict and errp are
1012 not optional. */
1014 ctf_id_t
1015 ctf_arc_lookup_enumerator_next (ctf_archive_t *arc, const char *name,
1016 ctf_next_t **it, int64_t *enum_value,
1017 ctf_dict_t **dict, int *errp)
1019 ctf_next_t *i = *it;
1020 ctf_id_t type;
1021 int opened_this_time = 0;
1022 int err;
1024 /* We have two nested iterators in here: ctn_next tracks archives, while
1025 within it ctn_next_inner tracks enumerators within an archive. We
1026 keep track of the dict by simply reusing the passed-in arg: if it's
1027 changed by the caller, the caller will get an ECTF_WRONGFP error,
1028 so this is quite safe and means we don't have to track the arc and fp
1029 simultaneously in the ctf_next_t. */
1031 if (!i)
1033 if ((i = ctf_next_create ()) == NULL)
1035 err = ENOMEM;
1036 goto err;
1038 i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
1039 i->cu.ctn_arc = arc;
1040 *it = i;
1043 if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
1045 err = ECTF_NEXT_WRONGFUN;
1046 goto err;
1049 if (arc != i->cu.ctn_arc)
1051 err = ECTF_NEXT_WRONGFP;
1052 goto err;
1055 /* Prevent any earlier end-of-iteration on this dict from confusing the
1056 test below. */
1057 if (i->ctn_next != NULL)
1058 ctf_set_errno (*dict, 0);
1062 /* At end of one dict, or not started any iterations yet?
1063 Traverse to next dict. If we never returned this dict to the
1064 caller, close it ourselves: the caller will never see it and cannot
1065 do so. */
1067 if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
1069 if (opened_this_time)
1071 ctf_dict_close (*dict);
1072 *dict = NULL;
1073 opened_this_time = 0;
1076 *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
1077 if (!*dict)
1078 goto err;
1079 opened_this_time = 1;
1082 type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
1083 enum_value);
1085 while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);
1087 if (type == CTF_ERR)
1089 err = ctf_errno (*dict);
1090 goto err;
1093 /* If this dict is being reused from the previous iteration, bump its
1094 refcnt: the caller is going to close it and has no idea that we didn't
1095 open it this time round. */
1096 if (!opened_this_time)
1097 ctf_ref (*dict);
1099 return type;
1101 err: /* Also ECTF_NEXT_END. */
1102 if (opened_this_time)
1104 ctf_dict_close (*dict);
1105 *dict = NULL;
1108 ctf_next_destroy (i);
1109 *it = NULL;
1110 if (errp)
1111 *errp = err;
1112 return CTF_ERR;
1115 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
1116 CTF files in turn to the specified callback function. */
1117 static int
1118 ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1119 ctf_archive_raw_member_f *func, void *data)
1121 int rc;
1122 size_t i;
1123 struct ctf_archive_modent *modent;
1124 const char *nametbl;
1126 modent = (ctf_archive_modent_t *) ((char *) arc
1127 + sizeof (struct ctf_archive));
1128 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1130 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
1132 const char *name;
1133 char *fp;
1135 name = &nametbl[le64toh (modent[i].name_offset)];
1136 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1137 + le64toh (modent[i].ctf_offset));
1139 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1140 le64toh (*((uint64_t *) fp)), data)) != 0)
1141 return rc;
1143 return 0;
1146 /* Raw iteration over all CTF files in an archive: public entry point.
1148 Returns -EINVAL if not supported for this sort of archive. */
1150 ctf_archive_raw_iter (const ctf_archive_t *arc,
1151 ctf_archive_raw_member_f * func, void *data)
1153 if (arc->ctfi_is_archive)
1154 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1156 return -EINVAL; /* Not supported. */
1159 /* Iterate over all CTF files in an archive: public entry point. We pass all
1160 CTF files in turn to the specified callback function. */
1162 ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1163 void *data)
1165 ctf_next_t *i = NULL;
1166 ctf_dict_t *fp;
1167 const char *name;
1168 int err = 0;
1170 while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
1172 int rc;
1174 if ((rc = func (fp, name, data)) != 0)
1176 ctf_dict_close (fp);
1177 ctf_next_destroy (i);
1178 return rc;
1180 ctf_dict_close (fp);
1182 if (err != ECTF_NEXT_END && err != 0)
1184 ctf_next_destroy (i);
1185 return -1;
1187 return 0;
1190 /* Iterate over all CTF files in an archive, returning each dict in turn as a
1191 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
1192 responsibility to close it. Parent dicts may be skipped.
1194 The archive member is cached for rapid return on future calls.
1196 We identify parents by name rather than by flag value: for now, with the
1197 linker only emitting parents named _CTF_SECTION, this works well enough. */
1199 ctf_dict_t *
1200 ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1201 int skip_parent, int *errp)
1203 ctf_dict_t *f;
1204 ctf_next_t *i = *it;
1205 struct ctf_archive *arc;
1206 struct ctf_archive_modent *modent;
1207 const char *nametbl;
1208 const char *name_;
1210 if (!i)
1212 if ((i = ctf_next_create()) == NULL)
1214 if (errp)
1215 *errp = ENOMEM;
1216 return NULL;
1218 i->cu.ctn_arc = wrapper;
1219 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1220 *it = i;
1223 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1225 if (errp)
1226 *errp = ECTF_NEXT_WRONGFUN;
1227 return NULL;
1230 if (wrapper != i->cu.ctn_arc)
1232 if (errp)
1233 *errp = ECTF_NEXT_WRONGFP;
1234 return NULL;
1237 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1238 transparently wrapped in a single-member archive. These are parents: if
1239 skip_parent is on, they are skipped and the iterator terminates
1240 immediately. */
1242 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1244 i->ctn_n++;
1245 if (!skip_parent)
1247 wrapper->ctfi_dict->ctf_refcnt++;
1248 if (name)
1249 *name = _CTF_SECTION;
1250 return wrapper->ctfi_dict;
1254 arc = wrapper->ctfi_archive;
1256 /* The loop keeps going when skip_parent is on as long as the member we find
1257 is the parent (i.e. at most two iterations, but possibly an early return if
1258 *all* we have is a parent). */
1262 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1264 ctf_next_destroy (i);
1265 *it = NULL;
1266 if (errp)
1267 *errp = ECTF_NEXT_END;
1268 return NULL;
1271 modent = (ctf_archive_modent_t *) ((char *) arc
1272 + sizeof (struct ctf_archive));
1273 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1275 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1276 i->ctn_n++;
1278 while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1280 if (name)
1281 *name = name_;
1283 f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1284 return f;
1287 #ifdef HAVE_MMAP
1288 /* Map the header in. Only used on new, empty files. */
1289 static void *arc_mmap_header (int fd, size_t headersz)
1291 void *hdr;
1292 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1293 0)) == MAP_FAILED)
1294 return NULL;
1295 return hdr;
1298 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
1299 need to modify the region, but don't need anyone else to see the
1300 modifications.) */
1301 static void *arc_mmap_file (int fd, size_t size)
1303 void *arc;
1304 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1305 fd, 0)) == MAP_FAILED)
1306 return NULL;
1307 return arc;
1310 /* Persist the header to disk. */
1311 static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1312 size_t headersz, const char **errmsg)
1314 if (msync (header, headersz, MS_ASYNC) < 0)
1316 if (errmsg)
1317 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1318 "to %s: %s");
1319 return -1;
1321 return 0;
1324 /* Unmap the region. */
1325 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1327 if (munmap (header, headersz) < 0)
1329 if (errmsg)
1330 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1331 "to %s: %s");
1332 return -1;
1334 return 0;
1336 #else
1337 /* Map the header in. Only used on new, empty files. */
1338 static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1340 void *hdr;
1341 if ((hdr = malloc (headersz)) == NULL)
1342 return NULL;
1343 return hdr;
1346 /* Pull in the whole file, for reading only. We assume the current file
1347 position is at the start of the file. */
1348 static void *arc_mmap_file (int fd, size_t size)
1350 char *data;
1352 if ((data = malloc (size)) == NULL)
1353 return NULL;
1355 if (ctf_pread (fd, data, size, 0) < 0)
1357 free (data);
1358 return NULL;
1360 return data;
1363 /* Persist the header to disk. */
1364 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1365 const char **errmsg)
1367 ssize_t len;
1368 char *data = (char *) header;
1369 ssize_t count = headersz;
1371 if ((lseek (fd, 0, SEEK_SET)) < 0)
1373 if (errmsg)
1374 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1375 "%s: %s");
1376 return -1;
1379 while (headersz > 0)
1381 if ((len = write (fd, data, count)) < 0)
1383 if (errmsg)
1384 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1385 return len;
1387 if (len == EINTR)
1388 continue;
1390 if (len == 0) /* EOF. */
1391 break;
1393 count -= len;
1394 data += len;
1396 return 0;
1399 /* Unmap the region. */
1400 static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1401 const char **errmsg _libctf_unused_)
1403 free (header);
1404 return 0;
1406 #endif