change and rename gmp_string_asprintf to return an std::string
[binutils-gdb.git] / libctf / ctf-archive.c
blobdc312d3fd68367d24d7c8405efbc04a7ae240dc2
1 /* CTF archive files.
2 Copyright (C) 2019-2020 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 *errp);
40 static int sort_modent_by_name (const void *one, const void *two, void *n);
41 static void *arc_mmap_header (int fd, size_t headersz);
42 static void *arc_mmap_file (int fd, size_t size);
43 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
44 const char **errmsg);
45 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
46 static void ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp);
48 /* Flag to indicate "symbol not present" in
49 ctf_archive_internal.ctfi_symdicts. Never initialized. */
50 static ctf_dict_t enosym;
52 /* Write out a CTF archive to the start of the file referenced by the passed-in
53 fd. The entries in CTF_DICTS are referenced by name: the names are passed in
54 the names array, which must have CTF_DICTS entries.
56 Returns 0 on success, or an errno, or an ECTF_* value. */
57 int
58 ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
59 const char **names, size_t threshold)
61 const char *errmsg;
62 struct ctf_archive *archdr;
63 size_t i;
64 char dummy = 0;
65 size_t headersz;
66 ssize_t namesz;
67 size_t ctf_startoffs; /* Start of the section we are working over. */
68 char *nametbl = NULL; /* The name table. */
69 char *np;
70 off_t nameoffs;
71 struct ctf_archive_modent *modent;
73 ctf_dprintf ("Writing CTF archive with %lu files\n",
74 (unsigned long) ctf_dict_cnt);
76 /* Figure out the size of the mmap()ed header, including the
77 ctf_archive_modent array. We assume that all of this needs no
78 padding: a likely assumption, given that it's all made up of
79 uint64_t's. */
80 headersz = sizeof (struct ctf_archive)
81 + (ctf_dict_cnt * sizeof (uint64_t) * 2);
82 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
84 /* From now on we work in two pieces: an mmap()ed region from zero up to the
85 headersz, and a region updated via write() starting after that, containing
86 all the tables. Platforms that do not support mmap() just use write(). */
87 ctf_startoffs = headersz;
88 if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
90 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
91 goto err;
94 if (write (fd, &dummy, 1) < 0)
96 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
97 goto err;
100 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
102 errmsg = N_("ctf_arc_write(): cannot mmap");
103 goto err;
106 /* Fill in everything we can, which is everything other than the name
107 table offset. */
108 archdr->ctfa_magic = htole64 (CTFA_MAGIC);
109 archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
110 archdr->ctfa_ctfs = htole64 (ctf_startoffs);
112 /* We could validate that all CTF files have the same data model, but
113 since any reasonable construction process will be building things of
114 only one bitness anyway, this is pretty pointless, so just use the
115 model of the first CTF file for all of them. (It *is* valid to
116 create an empty archive: the value of ctfa_model is irrelevant in
117 this case, but we must be sure not to dereference uninitialized
118 memory.) */
120 if (ctf_dict_cnt > 0)
121 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
123 /* Now write out the CTFs: ctf_archive_modent array via the mapping,
124 ctfs via write(). The names themselves have not been written yet: we
125 track them in a local strtab until the time is right, and sort the
126 modents array after construction.
128 The name table is not sorted. */
130 for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
131 namesz += strlen (names[i]) + 1;
133 nametbl = malloc (namesz);
134 if (nametbl == NULL)
136 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
137 goto err_unmap;
140 for (i = 0, namesz = 0,
141 modent = (ctf_archive_modent_t *) ((char *) archdr
142 + sizeof (struct ctf_archive));
143 i < le64toh (archdr->ctfa_ndicts); i++)
145 off_t off;
147 strcpy (&nametbl[namesz], names[i]);
149 off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
150 if ((off < 0) && (off > -ECTF_BASE))
152 errmsg = N_("ctf_arc_write(): cannot determine file "
153 "position while writing to archive");
154 goto err_free;
156 if (off < 0)
158 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
159 errno = off * -1;
160 goto err_free;
163 modent->name_offset = htole64 (namesz);
164 modent->ctf_offset = htole64 (off - ctf_startoffs);
165 namesz += strlen (names[i]) + 1;
166 modent++;
169 ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
170 + sizeof (struct ctf_archive)),
171 le64toh (archdr->ctfa_ndicts),
172 sizeof (struct ctf_archive_modent), sort_modent_by_name,
173 nametbl);
175 /* Now the name table. */
177 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
179 errmsg = N_("ctf_arc_write(): cannot get current file position "
180 "in archive");
181 goto err_free;
183 archdr->ctfa_names = htole64 (nameoffs);
184 np = nametbl;
185 while (namesz > 0)
187 ssize_t len;
188 if ((len = write (fd, np, namesz)) < 0)
190 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
191 goto err_free;
193 namesz -= len;
194 np += len;
196 free (nametbl);
198 if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
199 goto err_unmap;
200 if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
201 goto err;
202 return 0;
204 err_free:
205 free (nametbl);
206 err_unmap:
207 arc_mmap_unmap (archdr, headersz, NULL);
208 err:
209 /* We report errors into the first file in the archive, if any: if this is a
210 zero-file archive, put it in the open-errors stream for lack of anywhere
211 else for it to go. */
212 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
213 gettext (errmsg));
214 return errno;
217 /* Write out a CTF archive. The entries in CTF_DICTS are referenced by name:
218 the names are passed in the names array, which must have CTF_DICTS entries.
220 If the filename is NULL, create a temporary file and return a pointer to it.
222 Returns 0 on success, or an errno, or an ECTF_* value. */
224 ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
225 const char **names, size_t threshold)
227 int err;
228 int fd;
230 if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
232 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
233 _("ctf_arc_write(): cannot create %s"), file);
234 return errno;
237 err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
238 if (err)
239 goto err_close;
241 if ((err = close (fd)) < 0)
242 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
243 _("ctf_arc_write(): cannot close after writing to archive"));
244 goto err;
246 err_close:
247 (void) close (fd);
248 err:
249 if (err < 0)
250 unlink (file);
252 return err;
255 /* Write one CTF file out. Return the file position of the written file (or
256 rather, of the file-size uint64_t that precedes it): negative return is a
257 negative errno or ctf_errno value. On error, the file position may no longer
258 be at the end of the file. */
259 static off_t
260 arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold)
262 off_t off, end_off;
263 uint64_t ctfsz = 0;
264 char *ctfszp;
265 size_t ctfsz_len;
266 int (*writefn) (ctf_dict_t * fp, int fd);
268 if (ctf_serialize (f) < 0)
269 return f->ctf_errno * -1;
271 if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
272 return errno * -1;
274 if (f->ctf_size > threshold)
275 writefn = ctf_compress_write;
276 else
277 writefn = ctf_write;
279 /* This zero-write turns into the size in a moment. */
280 ctfsz_len = sizeof (ctfsz);
281 ctfszp = (char *) &ctfsz;
282 while (ctfsz_len > 0)
284 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
285 if (writelen < 0)
286 return errno * -1;
287 ctfsz_len -= writelen;
288 ctfszp += writelen;
291 if (writefn (f, fd) != 0)
292 return f->ctf_errno * -1;
294 if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
295 return errno * -1;
296 ctfsz = htole64 (end_off - off);
298 if ((lseek (fd, off, SEEK_SET)) < 0)
299 return errno * -1;
301 /* ... here. */
302 ctfsz_len = sizeof (ctfsz);
303 ctfszp = (char *) &ctfsz;
304 while (ctfsz_len > 0)
306 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
307 if (writelen < 0)
308 return errno * -1;
309 ctfsz_len -= writelen;
310 ctfszp += writelen;
313 end_off = LCTF_ALIGN_OFFS (end_off, 8);
314 if ((lseek (fd, end_off, SEEK_SET)) < 0)
315 return errno * -1;
317 return off;
320 /* qsort() function to sort the array of struct ctf_archive_modents into
321 ascending name order. */
322 static int
323 sort_modent_by_name (const void *one, const void *two, void *n)
325 const struct ctf_archive_modent *a = one;
326 const struct ctf_archive_modent *b = two;
327 char *nametbl = n;
329 return strcmp (&nametbl[le64toh (a->name_offset)],
330 &nametbl[le64toh (b->name_offset)]);
333 /* bsearch_r() function to search for a given name in the sorted array of struct
334 ctf_archive_modents. */
335 static int
336 search_modent_by_name (const void *key, const void *ent, void *arg)
338 const char *k = key;
339 const struct ctf_archive_modent *v = ent;
340 const char *search_nametbl = arg;
342 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
345 /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
346 ctf_dict. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
347 STRSECT, as needed, on close. Possibly do not unmap on close. */
349 struct ctf_archive_internal *
350 ctf_new_archive_internal (int is_archive, int unmap_on_close,
351 struct ctf_archive *arc,
352 ctf_dict_t *fp, const ctf_sect_t *symsect,
353 const ctf_sect_t *strsect,
354 int *errp)
356 struct ctf_archive_internal *arci;
358 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
360 if (is_archive)
362 if (unmap_on_close)
363 ctf_arc_close_internal (arc);
365 else
366 ctf_dict_close (fp);
367 return (ctf_set_open_errno (errp, errno));
369 arci->ctfi_is_archive = is_archive;
370 if (is_archive)
371 arci->ctfi_archive = arc;
372 else
373 arci->ctfi_dict = fp;
374 if (symsect)
375 memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
376 if (strsect)
377 memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
378 arci->ctfi_free_symsect = 0;
379 arci->ctfi_free_strsect = 0;
380 arci->ctfi_unmap_on_close = unmap_on_close;
382 return arci;
385 /* Get the CTF preamble from data in a buffer, which may be either an archive or
386 a CTF dict. If multiple dicts are present in an archive, the preamble comes
387 from an arbitrary dict. The preamble is a pointer into the ctfsect passed
388 in. */
390 const ctf_preamble_t *
391 ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
393 if (ctfsect->cts_size > sizeof (uint64_t) &&
394 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
396 struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
397 return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
398 + sizeof (uint64_t));
400 else
401 return (const ctf_preamble_t *) ctfsect->cts_data;
404 /* Open a CTF archive or dictionary from data in a buffer (which the caller must
405 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
406 error in *err (if not NULL). */
407 ctf_archive_t *
408 ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
409 const ctf_sect_t *strsect, int *errp)
411 struct ctf_archive *arc = NULL;
412 int is_archive;
413 ctf_dict_t *fp = NULL;
415 if (ctfsect->cts_size > sizeof (uint64_t) &&
416 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
418 /* The archive is mmappable, so this operation is trivial.
420 This buffer is nonmodifiable, so the trick involving mmapping only part
421 of it and storing the length in the magic number is not applicable: so
422 record this fact in the archive-wrapper header. (We cannot record it
423 in the archive, because the archive may very well be a read-only
424 mapping.) */
426 is_archive = 1;
427 arc = (struct ctf_archive *) ctfsect->cts_data;
429 else
431 is_archive = 0;
432 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
434 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
435 return NULL;
438 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
439 errp);
442 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
443 not NULL). */
444 struct ctf_archive *
445 ctf_arc_open_internal (const char *filename, int *errp)
447 const char *errmsg;
448 int fd;
449 struct stat s;
450 struct ctf_archive *arc; /* (Actually the whole file.) */
452 libctf_init_debug();
453 if ((fd = open (filename, O_RDONLY)) < 0)
455 errmsg = N_("ctf_arc_open(): cannot open %s");
456 goto err;
458 if (fstat (fd, &s) < 0)
460 errmsg = N_("ctf_arc_open(): cannot stat %s");
461 goto err_close;
464 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
466 errmsg = N_("ctf_arc_open(): cannot read in %s");
467 goto err_close;
470 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
472 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
473 errno = ECTF_FMT;
474 goto err_unmap;
477 /* This horrible hack lets us know how much to unmap when the file is
478 closed. (We no longer need the magic number, and the mapping
479 is private.) */
480 arc->ctfa_magic = s.st_size;
481 close (fd);
482 return arc;
484 err_unmap:
485 arc_mmap_unmap (arc, s.st_size, NULL);
486 err_close:
487 close (fd);
488 err:
489 if (errp)
490 *errp = errno;
491 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
492 return NULL;
495 /* Close an archive. */
496 void
497 ctf_arc_close_internal (struct ctf_archive *arc)
499 if (arc == NULL)
500 return;
502 /* See the comment in ctf_arc_open(). */
503 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
506 /* Public entry point: close an archive, or CTF file. */
507 void
508 ctf_arc_close (ctf_archive_t *arc)
510 if (arc == NULL)
511 return;
513 if (arc->ctfi_is_archive)
515 if (arc->ctfi_unmap_on_close)
516 ctf_arc_close_internal (arc->ctfi_archive);
518 else
519 ctf_dict_close (arc->ctfi_dict);
520 free (arc->ctfi_syms);
521 free (arc->ctfi_symdicts);
522 ctf_dynhash_destroy (arc->ctfi_dicts);
523 if (arc->ctfi_free_symsect)
524 free ((void *) arc->ctfi_symsect.cts_data);
525 if (arc->ctfi_free_strsect)
526 free ((void *) arc->ctfi_strsect.cts_data);
527 free (arc->ctfi_data);
528 if (arc->ctfi_bfd_close)
529 arc->ctfi_bfd_close (arc);
530 free (arc);
533 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
534 non-NULL. A name of NULL means to open the default file. */
535 static ctf_dict_t *
536 ctf_dict_open_internal (const struct ctf_archive *arc,
537 const ctf_sect_t *symsect,
538 const ctf_sect_t *strsect,
539 const char *name, int *errp)
541 struct ctf_archive_modent *modent;
542 const char *search_nametbl;
544 if (name == NULL)
545 name = _CTF_SECTION; /* The default name. */
547 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
549 modent = (ctf_archive_modent_t *) ((char *) arc
550 + sizeof (struct ctf_archive));
552 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
553 modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
554 sizeof (struct ctf_archive_modent),
555 search_modent_by_name, (void *) search_nametbl);
557 /* This is actually a common case and normal operation: no error
558 debug output. */
559 if (modent == NULL)
561 if (errp)
562 *errp = ECTF_ARNNAME;
563 return NULL;
566 return ctf_dict_open_by_offset (arc, symsect, strsect,
567 le64toh (modent->ctf_offset), errp);
570 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
571 non-NULL. A name of NULL means to open the default file.
573 Use the specified string and symbol table sections.
575 Public entry point. */
576 ctf_dict_t *
577 ctf_dict_open_sections (const ctf_archive_t *arc,
578 const ctf_sect_t *symsect,
579 const ctf_sect_t *strsect,
580 const char *name,
581 int *errp)
583 if (arc->ctfi_is_archive)
585 ctf_dict_t *ret;
586 ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
587 name, errp);
588 if (ret)
590 ret->ctf_archive = (ctf_archive_t *) arc;
591 ctf_arc_import_parent (arc, ret);
593 return ret;
596 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
598 if (errp)
599 *errp = ECTF_ARNNAME;
600 return NULL;
602 arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
604 /* Bump the refcount so that the user can ctf_dict_close() it. */
605 arc->ctfi_dict->ctf_refcnt++;
606 return arc->ctfi_dict;
609 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
610 non-NULL. A name of NULL means to open the default file.
612 Public entry point. */
613 ctf_dict_t *
614 ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
616 const ctf_sect_t *symsect = &arc->ctfi_symsect;
617 const ctf_sect_t *strsect = &arc->ctfi_strsect;
619 if (symsect->cts_name == NULL)
620 symsect = NULL;
621 if (strsect->cts_name == NULL)
622 strsect = NULL;
624 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
627 static void
628 ctf_cached_dict_close (void *fp)
630 ctf_dict_close ((ctf_dict_t *) fp);
633 /* Return the ctf_dict_t with the given name and cache it in the
634 archive's ctfi_dicts. */
635 static ctf_dict_t *
636 ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
638 ctf_dict_t *fp;
639 char *dupname;
641 /* Just return from the cache if possible. */
642 if (arc->ctfi_dicts
643 && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
645 fp->ctf_refcnt++;
646 return fp;
649 /* Not yet cached: open it. */
650 fp = ctf_dict_open (arc, name, errp);
651 dupname = strdup (name);
653 if (!fp || !dupname)
654 goto oom;
656 if (arc->ctfi_dicts == NULL)
657 if ((arc->ctfi_dicts
658 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
659 free, ctf_cached_dict_close)) == NULL)
660 goto oom;
662 if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
663 goto oom;
664 fp->ctf_refcnt++;
666 return fp;
668 oom:
669 ctf_dict_close (fp);
670 free (dupname);
671 if (errp)
672 *errp = ENOMEM;
673 return NULL;
676 /* Flush any caches the CTF archive may have open. */
677 void
678 ctf_arc_flush_caches (ctf_archive_t *wrapper)
680 free (wrapper->ctfi_symdicts);
681 free (wrapper->ctfi_syms);
682 ctf_dynhash_destroy (wrapper->ctfi_dicts);
683 wrapper->ctfi_symdicts = NULL;
684 wrapper->ctfi_syms = NULL;
685 wrapper->ctfi_dicts = NULL;
688 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
689 none, setting 'err' if non-NULL. */
690 static ctf_dict_t *
691 ctf_dict_open_by_offset (const struct ctf_archive *arc,
692 const ctf_sect_t *symsect,
693 const ctf_sect_t *strsect, size_t offset,
694 int *errp)
696 ctf_sect_t ctfsect;
697 ctf_dict_t *fp;
699 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
701 memset (&ctfsect, 0, sizeof (ctf_sect_t));
703 offset += le64toh (arc->ctfa_ctfs);
705 ctfsect.cts_name = _CTF_SECTION;
706 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
707 ctfsect.cts_entsize = 1;
708 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
709 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
710 if (fp)
711 ctf_setmodel (fp, le64toh (arc->ctfa_model));
712 return fp;
715 /* Backward compatibility. */
716 ctf_dict_t *
717 ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
718 int *errp)
720 return ctf_dict_open (arc, name, errp);
723 ctf_dict_t *
724 ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
725 const ctf_sect_t *symsect,
726 const ctf_sect_t *strsect,
727 const char *name,
728 int *errp)
730 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
733 /* Import the parent into a ctf archive, if this is a child, the parent is not
734 already set, and a suitable archive member exists. No error is raised if
735 this is not possible: this is just a best-effort helper operation to give
736 people useful dicts to start with. */
737 static void
738 ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp)
740 if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
742 ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
743 fp->ctf_parname, NULL);
744 if (parent)
746 ctf_import (fp, parent);
747 ctf_dict_close (parent);
752 /* Return the number of members in an archive. */
753 size_t
754 ctf_archive_count (const ctf_archive_t *wrapper)
756 if (!wrapper->ctfi_is_archive)
757 return 1;
759 return wrapper->ctfi_archive->ctfa_ndicts;
762 /* Look up a symbol in an archive. Return the dict in the archive that the
763 symbol is found in, and (optionally) the ctf_id_t of the symbol in that dict
764 (so you don't have to look it up yourself). The dict and mapping are both
765 cached, so repeated lookups are nearly free.
767 As usual, you should ctf_dict_close() the returned dict once you are done
768 with it.
770 Returns NULL on error, and an error in errp (if set). */
772 ctf_dict_t *
773 ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
774 ctf_id_t *typep, int *errp)
776 ctf_dict_t *fp;
777 ctf_id_t type;
779 /* The usual non-archive-transparent-wrapper special case. */
780 if (!wrapper->ctfi_is_archive)
782 if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
784 if (errp)
785 *errp = ctf_errno (wrapper->ctfi_dict);
786 return NULL;
788 if (typep)
789 *typep = type;
790 wrapper->ctfi_dict->ctf_refcnt++;
791 return wrapper->ctfi_dict;
794 if (wrapper->ctfi_symsect.cts_name == NULL
795 || wrapper->ctfi_symsect.cts_data == NULL
796 || wrapper->ctfi_symsect.cts_size == 0
797 || wrapper->ctfi_symsect.cts_entsize == 0)
799 if (errp)
800 *errp = ECTF_NOSYMTAB;
801 return NULL;
804 /* Make enough space for all possible symbols, if not already done.
805 We cache both the ctf_id_t and the originating dictionary of all symbols.
806 The dict links are weak, to the dictionaries cached in ctfi_dicts: their
807 refcnts are *not* bumped. */
809 if (!wrapper->ctfi_syms)
811 if ((wrapper->ctfi_syms = calloc (wrapper->ctfi_symsect.cts_size
812 / wrapper->ctfi_symsect.cts_entsize,
813 sizeof (ctf_id_t))) == NULL)
815 if (errp)
816 *errp = ENOMEM;
817 return NULL;
820 if (!wrapper->ctfi_symdicts)
822 if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
823 / wrapper->ctfi_symsect.cts_entsize,
824 sizeof (ctf_dict_t *))) == NULL)
826 if (errp)
827 *errp = ENOMEM;
828 return NULL;
832 /* Perhaps it's cached. */
833 if (wrapper->ctfi_symdicts[symidx] != NULL)
835 if (wrapper->ctfi_symdicts[symidx] == &enosym)
837 if (errp)
838 *errp = ECTF_NOTYPEDAT;
839 if (typep)
840 *typep = CTF_ERR;
841 return NULL;
844 if (typep)
845 *typep = wrapper->ctfi_syms[symidx];
846 wrapper->ctfi_symdicts[symidx]->ctf_refcnt++;
847 return wrapper->ctfi_symdicts[symidx];
850 /* Not cached: find it and cache it. We must track open errors ourselves even
851 if our caller doesn't, to be able to distinguish no-error end-of-iteration
852 from open errors. */
854 int local_err;
855 int *local_errp;
856 ctf_next_t *i = NULL;
857 const char *name;
859 if (errp)
860 local_errp = errp;
861 else
862 local_errp = &local_err;
864 while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
866 if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
868 wrapper->ctfi_syms[symidx] = type;
869 wrapper->ctfi_symdicts[symidx] = fp;
870 ctf_next_destroy (i);
872 if (typep)
873 *typep = type;
874 return fp;
876 ctf_dict_close (fp);
878 if (*local_errp != ECTF_NEXT_END)
880 ctf_next_destroy (i);
881 return NULL;
883 /* Don't leak end-of-iteration to the caller. */
884 *local_errp = 0;
886 wrapper->ctfi_symdicts[symidx] = &enosym;
888 if (errp)
889 *errp = ECTF_NOTYPEDAT;
890 if (typep)
891 *typep = CTF_ERR;
892 return NULL;
895 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
896 CTF files in turn to the specified callback function. */
897 static int
898 ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
899 ctf_archive_raw_member_f *func, void *data)
901 int rc;
902 size_t i;
903 struct ctf_archive_modent *modent;
904 const char *nametbl;
906 modent = (ctf_archive_modent_t *) ((char *) arc
907 + sizeof (struct ctf_archive));
908 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
910 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
912 const char *name;
913 char *fp;
915 name = &nametbl[le64toh (modent[i].name_offset)];
916 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
917 + le64toh (modent[i].ctf_offset));
919 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
920 le64toh (*((uint64_t *) fp)), data)) != 0)
921 return rc;
923 return 0;
926 /* Raw iteration over all CTF files in an archive: public entry point.
928 Returns -EINVAL if not supported for this sort of archive. */
930 ctf_archive_raw_iter (const ctf_archive_t *arc,
931 ctf_archive_raw_member_f * func, void *data)
933 if (arc->ctfi_is_archive)
934 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
936 return -EINVAL; /* Not supported. */
939 /* Iterate over all CTF files in an archive. We pass all CTF files in turn to
940 the specified callback function. */
941 static int
942 ctf_archive_iter_internal (const ctf_archive_t *wrapper,
943 const struct ctf_archive *arc,
944 const ctf_sect_t *symsect,
945 const ctf_sect_t *strsect,
946 ctf_archive_member_f *func, void *data)
948 int rc;
949 size_t i;
950 ctf_dict_t *f;
951 struct ctf_archive_modent *modent;
952 const char *nametbl;
954 modent = (ctf_archive_modent_t *) ((char *) arc
955 + sizeof (struct ctf_archive));
956 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
958 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
960 const char *name;
962 name = &nametbl[le64toh (modent[i].name_offset)];
963 if ((f = ctf_dict_open_internal (arc, symsect, strsect,
964 name, &rc)) == NULL)
965 return rc;
967 f->ctf_archive = (ctf_archive_t *) wrapper;
968 ctf_arc_import_parent (wrapper, f);
969 if ((rc = func (f, name, data)) != 0)
971 ctf_dict_close (f);
972 return rc;
975 ctf_dict_close (f);
977 return 0;
980 /* Iterate over all CTF files in an archive: public entry point. We pass all
981 CTF files in turn to the specified callback function. */
983 ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
984 void *data)
986 const ctf_sect_t *symsect = &arc->ctfi_symsect;
987 const ctf_sect_t *strsect = &arc->ctfi_strsect;
989 if (symsect->cts_name == NULL)
990 symsect = NULL;
991 if (strsect->cts_name == NULL)
992 strsect = NULL;
994 if (arc->ctfi_is_archive)
995 return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect,
996 func, data);
998 return func (arc->ctfi_dict, _CTF_SECTION, data);
1001 /* Iterate over all CTF files in an archive, returning each dict in turn as a
1002 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
1003 responsibility to close it. Parent dicts may be skipped. Regardless of
1004 whether they are skipped or not, the caller must ctf_import the parent if
1005 need be.
1007 The archive member is cached for rapid return on future calls.
1009 We identify parents by name rather than by flag value: for now, with the
1010 linker only emitting parents named _CTF_SECTION, this works well enough. */
1012 ctf_dict_t *
1013 ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1014 int skip_parent, int *errp)
1016 ctf_dict_t *f;
1017 ctf_next_t *i = *it;
1018 struct ctf_archive *arc;
1019 struct ctf_archive_modent *modent;
1020 const char *nametbl;
1021 const char *name_;
1023 if (!i)
1025 if ((i = ctf_next_create()) == NULL)
1027 if (errp)
1028 *errp = ENOMEM;
1029 return NULL;
1031 i->cu.ctn_arc = wrapper;
1032 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1033 *it = i;
1036 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1038 if (errp)
1039 *errp = ECTF_NEXT_WRONGFUN;
1040 return NULL;
1043 if (wrapper != i->cu.ctn_arc)
1045 if (errp)
1046 *errp = ECTF_NEXT_WRONGFP;
1047 return NULL;
1050 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1051 transparently wrapped in a single-member archive. These are parents: if
1052 skip_parent is on, they are skipped and the iterator terminates
1053 immediately. */
1055 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1057 i->ctn_n++;
1058 if (!skip_parent)
1060 wrapper->ctfi_dict->ctf_refcnt++;
1061 return wrapper->ctfi_dict;
1065 arc = wrapper->ctfi_archive;
1067 /* The loop keeps going when skip_parent is on as long as the member we find
1068 is the parent (i.e. at most two iterations, but possibly an early return if
1069 *all* we have is a parent). */
1073 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1075 ctf_next_destroy (i);
1076 *it = NULL;
1077 if (errp)
1078 *errp = ECTF_NEXT_END;
1079 return NULL;
1082 modent = (ctf_archive_modent_t *) ((char *) arc
1083 + sizeof (struct ctf_archive));
1084 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1086 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1087 i->ctn_n++;
1088 } while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1090 if (name)
1091 *name = name_;
1093 f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1094 return f;
1097 #ifdef HAVE_MMAP
1098 /* Map the header in. Only used on new, empty files. */
1099 static void *arc_mmap_header (int fd, size_t headersz)
1101 void *hdr;
1102 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1103 0)) == MAP_FAILED)
1104 return NULL;
1105 return hdr;
1108 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
1109 need to modify the region, but don't need anyone else to see the
1110 modifications.) */
1111 static void *arc_mmap_file (int fd, size_t size)
1113 void *arc;
1114 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1115 fd, 0)) == MAP_FAILED)
1116 return NULL;
1117 return arc;
1120 /* Persist the header to disk. */
1121 static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1122 size_t headersz, const char **errmsg)
1124 if (msync (header, headersz, MS_ASYNC) < 0)
1126 if (errmsg)
1127 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1128 "to %s: %s");
1129 return -1;
1131 return 0;
1134 /* Unmap the region. */
1135 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1137 if (munmap (header, headersz) < 0)
1139 if (errmsg)
1140 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1141 "to %s: %s");
1142 return -1;
1144 return 0;
1146 #else
1147 /* Map the header in. Only used on new, empty files. */
1148 static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1150 void *hdr;
1151 if ((hdr = malloc (headersz)) == NULL)
1152 return NULL;
1153 return hdr;
1156 /* Pull in the whole file, for reading only. We assume the current file
1157 position is at the start of the file. */
1158 static void *arc_mmap_file (int fd, size_t size)
1160 char *data;
1162 if ((data = malloc (size)) == NULL)
1163 return NULL;
1165 if (ctf_pread (fd, data, size, 0) < 0)
1167 free (data);
1168 return NULL;
1170 return data;
1173 /* Persist the header to disk. */
1174 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1175 const char **errmsg)
1177 ssize_t len;
1178 size_t acc = 0;
1179 char *data = (char *) header;
1180 ssize_t count = headersz;
1182 if ((lseek (fd, 0, SEEK_SET)) < 0)
1184 if (errmsg)
1185 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1186 "%s: %s");
1187 return -1;
1190 while (headersz > 0)
1192 if ((len = write (fd, data, count)) < 0)
1194 if (errmsg)
1195 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1196 return len;
1198 if (len == EINTR)
1199 continue;
1201 acc += len;
1202 if (len == 0) /* EOF. */
1203 break;
1205 count -= len;
1206 data += len;
1208 return 0;
1211 /* Unmap the region. */
1212 static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1213 const char **errmsg _libctf_unused_)
1215 free (header);
1216 return 0;
1218 #endif