2 Copyright (C) 2019-2022 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
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/>. */
21 #include <sys/types.h>
24 #include "ctf-endian.h"
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
,
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
,
46 static int arc_mmap_unmap (void *header
, size_t headersz
, const char **errmsg
);
47 static void ctf_arc_import_parent (const ctf_archive_t
*arc
, ctf_dict_t
*fp
);
49 /* Flag to indicate "symbol not present" in ctf_archive_internal.ctfi_symdicts
50 and ctfi_symnamedicts. Never initialized. */
51 static ctf_dict_t enosym
;
53 /* Write out a CTF archive to the start of the file referenced by the passed-in
54 fd. The entries in CTF_DICTS are referenced by name: the names are passed in
55 the names array, which must have CTF_DICTS entries.
57 Returns 0 on success, or an errno, or an ECTF_* value. */
59 ctf_arc_write_fd (int fd
, ctf_dict_t
**ctf_dicts
, size_t ctf_dict_cnt
,
60 const char **names
, size_t threshold
)
63 struct ctf_archive
*archdr
;
68 size_t ctf_startoffs
; /* Start of the section we are working over. */
69 char *nametbl
= NULL
; /* The name table. */
72 struct ctf_archive_modent
*modent
;
74 ctf_dprintf ("Writing CTF archive with %lu files\n",
75 (unsigned long) ctf_dict_cnt
);
77 /* Figure out the size of the mmap()ed header, including the
78 ctf_archive_modent array. We assume that all of this needs no
79 padding: a likely assumption, given that it's all made up of
81 headersz
= sizeof (struct ctf_archive
)
82 + (ctf_dict_cnt
* sizeof (uint64_t) * 2);
83 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz
);
85 /* From now on we work in two pieces: an mmap()ed region from zero up to the
86 headersz, and a region updated via write() starting after that, containing
87 all the tables. Platforms that do not support mmap() just use write(). */
88 ctf_startoffs
= headersz
;
89 if (lseek (fd
, ctf_startoffs
- 1, SEEK_SET
) < 0)
91 errmsg
= N_("ctf_arc_write(): cannot extend file while writing");
95 if (write (fd
, &dummy
, 1) < 0)
97 errmsg
= N_("ctf_arc_write(): cannot extend file while writing");
101 if ((archdr
= arc_mmap_header (fd
, headersz
)) == NULL
)
103 errmsg
= N_("ctf_arc_write(): cannot mmap");
107 /* Fill in everything we can, which is everything other than the name
109 archdr
->ctfa_magic
= htole64 (CTFA_MAGIC
);
110 archdr
->ctfa_ndicts
= htole64 (ctf_dict_cnt
);
111 archdr
->ctfa_ctfs
= htole64 (ctf_startoffs
);
113 /* We could validate that all CTF files have the same data model, but
114 since any reasonable construction process will be building things of
115 only one bitness anyway, this is pretty pointless, so just use the
116 model of the first CTF file for all of them. (It *is* valid to
117 create an empty archive: the value of ctfa_model is irrelevant in
118 this case, but we must be sure not to dereference uninitialized
121 if (ctf_dict_cnt
> 0)
122 archdr
->ctfa_model
= htole64 (ctf_getmodel (ctf_dicts
[0]));
124 /* Now write out the CTFs: ctf_archive_modent array via the mapping,
125 ctfs via write(). The names themselves have not been written yet: we
126 track them in a local strtab until the time is right, and sort the
127 modents array after construction.
129 The name table is not sorted. */
131 for (i
= 0, namesz
= 0; i
< le64toh (archdr
->ctfa_ndicts
); i
++)
132 namesz
+= strlen (names
[i
]) + 1;
134 nametbl
= malloc (namesz
);
137 errmsg
= N_("ctf_arc_write(): error writing named CTF to archive");
141 for (i
= 0, namesz
= 0,
142 modent
= (ctf_archive_modent_t
*) ((char *) archdr
143 + sizeof (struct ctf_archive
));
144 i
< le64toh (archdr
->ctfa_ndicts
); i
++)
148 strcpy (&nametbl
[namesz
], names
[i
]);
150 off
= arc_write_one_ctf (ctf_dicts
[i
], fd
, threshold
);
151 if ((off
< 0) && (off
> -ECTF_BASE
))
153 errmsg
= N_("ctf_arc_write(): cannot determine file "
154 "position while writing to archive");
159 errmsg
= N_("ctf_arc_write(): cannot write CTF file to archive");
164 modent
->name_offset
= htole64 (namesz
);
165 modent
->ctf_offset
= htole64 (off
- ctf_startoffs
);
166 namesz
+= strlen (names
[i
]) + 1;
170 ctf_qsort_r ((ctf_archive_modent_t
*) ((char *) archdr
171 + sizeof (struct ctf_archive
)),
172 le64toh (archdr
->ctfa_ndicts
),
173 sizeof (struct ctf_archive_modent
), sort_modent_by_name
,
176 /* Now the name table. */
178 if ((nameoffs
= lseek (fd
, 0, SEEK_CUR
)) < 0)
180 errmsg
= N_("ctf_arc_write(): cannot get current file position "
184 archdr
->ctfa_names
= htole64 (nameoffs
);
189 if ((len
= write (fd
, np
, namesz
)) < 0)
191 errmsg
= N_("ctf_arc_write(): cannot write name table to archive");
199 if (arc_mmap_writeout (fd
, archdr
, headersz
, &errmsg
) < 0)
201 if (arc_mmap_unmap (archdr
, headersz
, &errmsg
) < 0)
208 arc_mmap_unmap (archdr
, headersz
, NULL
);
210 /* We report errors into the first file in the archive, if any: if this is a
211 zero-file archive, put it in the open-errors stream for lack of anywhere
212 else for it to go. */
213 ctf_err_warn (ctf_dict_cnt
> 0 ? ctf_dicts
[0] : NULL
, 0, errno
, "%s",
218 /* Write out a CTF archive. The entries in CTF_DICTS are referenced by name:
219 the names are passed in the names array, which must have CTF_DICTS entries.
221 If the filename is NULL, create a temporary file and return a pointer to it.
223 Returns 0 on success, or an errno, or an ECTF_* value. */
225 ctf_arc_write (const char *file
, ctf_dict_t
**ctf_dicts
, size_t ctf_dict_cnt
,
226 const char **names
, size_t threshold
)
231 if ((fd
= open (file
, O_RDWR
| O_CREAT
| O_TRUNC
| O_CLOEXEC
, 0666)) < 0)
233 ctf_err_warn (ctf_dict_cnt
> 0 ? ctf_dicts
[0] : NULL
, 0, errno
,
234 _("ctf_arc_write(): cannot create %s"), file
);
238 err
= ctf_arc_write_fd (fd
, ctf_dicts
, ctf_dict_cnt
, names
, threshold
);
242 if ((err
= close (fd
)) < 0)
243 ctf_err_warn (ctf_dict_cnt
> 0 ? ctf_dicts
[0] : NULL
, 0, errno
,
244 _("ctf_arc_write(): cannot close after writing to archive"));
256 /* Write one CTF file out. Return the file position of the written file (or
257 rather, of the file-size uint64_t that precedes it): negative return is a
258 negative errno or ctf_errno value. On error, the file position may no longer
259 be at the end of the file. */
261 arc_write_one_ctf (ctf_dict_t
* f
, int fd
, size_t threshold
)
267 int (*writefn
) (ctf_dict_t
* fp
, int fd
);
269 if (ctf_serialize (f
) < 0)
270 return f
->ctf_errno
* -1;
272 if ((off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
275 if (f
->ctf_size
> threshold
)
276 writefn
= ctf_compress_write
;
280 /* This zero-write turns into the size in a moment. */
281 ctfsz_len
= sizeof (ctfsz
);
282 ctfszp
= (char *) &ctfsz
;
283 while (ctfsz_len
> 0)
285 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
288 ctfsz_len
-= writelen
;
292 if (writefn (f
, fd
) != 0)
293 return f
->ctf_errno
* -1;
295 if ((end_off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
297 ctfsz
= htole64 (end_off
- off
);
299 if ((lseek (fd
, off
, SEEK_SET
)) < 0)
303 ctfsz_len
= sizeof (ctfsz
);
304 ctfszp
= (char *) &ctfsz
;
305 while (ctfsz_len
> 0)
307 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
310 ctfsz_len
-= writelen
;
314 end_off
= LCTF_ALIGN_OFFS (end_off
, 8);
315 if ((lseek (fd
, end_off
, SEEK_SET
)) < 0)
321 /* qsort() function to sort the array of struct ctf_archive_modents into
322 ascending name order. */
324 sort_modent_by_name (const void *one
, const void *two
, void *n
)
326 const struct ctf_archive_modent
*a
= one
;
327 const struct ctf_archive_modent
*b
= two
;
330 return strcmp (&nametbl
[le64toh (a
->name_offset
)],
331 &nametbl
[le64toh (b
->name_offset
)]);
334 /* bsearch_r() function to search for a given name in the sorted array of struct
335 ctf_archive_modents. */
337 search_modent_by_name (const void *key
, const void *ent
, void *arg
)
340 const struct ctf_archive_modent
*v
= ent
;
341 const char *search_nametbl
= arg
;
343 return strcmp (k
, &search_nametbl
[le64toh (v
->name_offset
)]);
346 /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
347 ctf_dict. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
348 STRSECT, as needed, on close. Possibly do not unmap on close. */
350 struct ctf_archive_internal
*
351 ctf_new_archive_internal (int is_archive
, int unmap_on_close
,
352 struct ctf_archive
*arc
,
353 ctf_dict_t
*fp
, const ctf_sect_t
*symsect
,
354 const ctf_sect_t
*strsect
,
357 struct ctf_archive_internal
*arci
;
359 if ((arci
= calloc (1, sizeof (struct ctf_archive_internal
))) == NULL
)
364 ctf_arc_close_internal (arc
);
368 return (ctf_set_open_errno (errp
, errno
));
370 arci
->ctfi_is_archive
= is_archive
;
372 arci
->ctfi_archive
= arc
;
374 arci
->ctfi_dict
= fp
;
376 memcpy (&arci
->ctfi_symsect
, symsect
, sizeof (struct ctf_sect
));
378 memcpy (&arci
->ctfi_strsect
, strsect
, sizeof (struct ctf_sect
));
379 arci
->ctfi_free_symsect
= 0;
380 arci
->ctfi_free_strsect
= 0;
381 arci
->ctfi_unmap_on_close
= unmap_on_close
;
382 arci
->ctfi_symsect_little_endian
= -1;
387 /* Set the symbol-table endianness of an archive (defaulting the symtab
388 endianness of all ctf_file_t's opened from that archive). */
390 ctf_arc_symsect_endianness (ctf_archive_t
*arc
, int little_endian
)
392 arc
->ctfi_symsect_little_endian
= !!little_endian
;
393 if (!arc
->ctfi_is_archive
)
394 ctf_symsect_endianness (arc
->ctfi_dict
, arc
->ctfi_symsect_little_endian
);
397 /* Get the CTF preamble from data in a buffer, which may be either an archive or
398 a CTF dict. If multiple dicts are present in an archive, the preamble comes
399 from an arbitrary dict. The preamble is a pointer into the ctfsect passed
402 const ctf_preamble_t
*
403 ctf_arc_bufpreamble (const ctf_sect_t
*ctfsect
)
405 if (ctfsect
->cts_size
> sizeof (uint64_t) &&
406 (le64toh ((*(uint64_t *) ctfsect
->cts_data
)) == CTFA_MAGIC
))
408 struct ctf_archive
*arc
= (struct ctf_archive
*) ctfsect
->cts_data
;
409 return (const ctf_preamble_t
*) ((char *) arc
+ le64toh (arc
->ctfa_ctfs
)
410 + sizeof (uint64_t));
413 return (const ctf_preamble_t
*) ctfsect
->cts_data
;
416 /* Open a CTF archive or dictionary from data in a buffer (which the caller must
417 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
418 error in *err (if not NULL). */
420 ctf_arc_bufopen (const ctf_sect_t
*ctfsect
, const ctf_sect_t
*symsect
,
421 const ctf_sect_t
*strsect
, int *errp
)
423 struct ctf_archive
*arc
= NULL
;
425 ctf_dict_t
*fp
= NULL
;
427 if (ctfsect
->cts_size
> sizeof (uint64_t) &&
428 (le64toh ((*(uint64_t *) ctfsect
->cts_data
)) == CTFA_MAGIC
))
430 /* The archive is mmappable, so this operation is trivial.
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
439 arc
= (struct ctf_archive
*) ctfsect
->cts_data
;
444 if ((fp
= ctf_bufopen (ctfsect
, symsect
, strsect
, errp
)) == NULL
)
446 ctf_err_warn (NULL
, 0, *errp
, _("ctf_arc_bufopen(): cannot open CTF"));
450 return ctf_new_archive_internal (is_archive
, 0, arc
, fp
, symsect
, strsect
,
454 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
457 ctf_arc_open_internal (const char *filename
, int *errp
)
462 struct ctf_archive
*arc
; /* (Actually the whole file.) */
465 if ((fd
= open (filename
, O_RDONLY
)) < 0)
467 errmsg
= N_("ctf_arc_open(): cannot open %s");
470 if (fstat (fd
, &s
) < 0)
472 errmsg
= N_("ctf_arc_open(): cannot stat %s");
476 if ((arc
= arc_mmap_file (fd
, s
.st_size
)) == NULL
)
478 errmsg
= N_("ctf_arc_open(): cannot read in %s");
482 if (le64toh (arc
->ctfa_magic
) != CTFA_MAGIC
)
484 errmsg
= N_("ctf_arc_open(): %s: invalid magic number");
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
492 arc
->ctfa_magic
= s
.st_size
;
497 arc_mmap_unmap (arc
, s
.st_size
, NULL
);
503 ctf_err_warn (NULL
, 0, errno
, gettext (errmsg
), filename
);
507 /* Close an archive. */
509 ctf_arc_close_internal (struct ctf_archive
*arc
)
514 /* See the comment in ctf_arc_open(). */
515 arc_mmap_unmap (arc
, arc
->ctfa_magic
, NULL
);
518 /* Public entry point: close an archive, or CTF file. */
520 ctf_arc_close (ctf_archive_t
*arc
)
525 if (arc
->ctfi_is_archive
)
527 if (arc
->ctfi_unmap_on_close
)
528 ctf_arc_close_internal (arc
->ctfi_archive
);
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
);
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. */
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
,
554 struct ctf_archive_modent
*modent
;
555 const char *search_nametbl
;
558 name
= _CTF_SECTION
; /* The default name. */
560 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name
);
562 modent
= (ctf_archive_modent_t
*) ((char *) arc
563 + sizeof (struct ctf_archive
));
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
);
570 /* This is actually a common case and normal operation: no error
575 *errp
= ECTF_ARNNAME
;
579 return ctf_dict_open_by_offset (arc
, symsect
, strsect
,
580 le64toh (modent
->ctf_offset
),
581 little_endian
, errp
);
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.
587 Use the specified string and symbol table sections.
589 Public entry point. */
591 ctf_dict_open_sections (const ctf_archive_t
*arc
,
592 const ctf_sect_t
*symsect
,
593 const ctf_sect_t
*strsect
,
597 if (arc
->ctfi_is_archive
)
600 ret
= ctf_dict_open_internal (arc
->ctfi_archive
, symsect
, strsect
,
601 name
, arc
->ctfi_symsect_little_endian
,
605 ret
->ctf_archive
= (ctf_archive_t
*) arc
;
606 ctf_arc_import_parent (arc
, ret
);
611 if ((name
!= NULL
) && (strcmp (name
, _CTF_SECTION
) != 0))
614 *errp
= ECTF_ARNNAME
;
617 arc
->ctfi_dict
->ctf_archive
= (ctf_archive_t
*) arc
;
619 /* Bump the refcount so that the user can ctf_dict_close() it. */
620 arc
->ctfi_dict
->ctf_refcnt
++;
621 return arc
->ctfi_dict
;
624 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
625 non-NULL. A name of NULL means to open the default file.
627 Public entry point. */
629 ctf_dict_open (const ctf_archive_t
*arc
, const char *name
, int *errp
)
631 const ctf_sect_t
*symsect
= &arc
->ctfi_symsect
;
632 const ctf_sect_t
*strsect
= &arc
->ctfi_strsect
;
634 if (symsect
->cts_name
== NULL
)
636 if (strsect
->cts_name
== NULL
)
639 return ctf_dict_open_sections (arc
, symsect
, strsect
, name
, errp
);
643 ctf_cached_dict_close (void *fp
)
645 ctf_dict_close ((ctf_dict_t
*) fp
);
648 /* Return the ctf_dict_t with the given name and cache it in the archive's
649 ctfi_dicts. If this is the first cached dict, designate it the
652 ctf_dict_open_cached (ctf_archive_t
*arc
, const char *name
, int *errp
)
657 /* Just return from the cache if possible. */
659 && ((fp
= ctf_dynhash_lookup (arc
->ctfi_dicts
, name
)) != NULL
))
665 /* Not yet cached: open it. */
666 fp
= ctf_dict_open (arc
, name
, errp
);
667 dupname
= strdup (name
);
672 if (arc
->ctfi_dicts
== NULL
)
674 = ctf_dynhash_create (ctf_hash_string
, ctf_hash_eq_string
,
675 free
, ctf_cached_dict_close
)) == NULL
)
678 if (ctf_dynhash_insert (arc
->ctfi_dicts
, dupname
, fp
) < 0)
682 if (arc
->ctfi_crossdict_cache
== NULL
)
683 arc
->ctfi_crossdict_cache
= fp
;
695 /* Flush any caches the CTF archive may have open. */
697 ctf_arc_flush_caches (ctf_archive_t
*wrapper
)
699 free (wrapper
->ctfi_symdicts
);
700 free (wrapper
->ctfi_symnamedicts
);
701 ctf_dynhash_destroy (wrapper
->ctfi_dicts
);
702 wrapper
->ctfi_symdicts
= NULL
;
703 wrapper
->ctfi_symnamedicts
= NULL
;
704 wrapper
->ctfi_dicts
= NULL
;
705 wrapper
->ctfi_crossdict_cache
= NULL
;
708 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
709 none, setting 'err' if non-NULL. */
711 ctf_dict_open_by_offset (const struct ctf_archive
*arc
,
712 const ctf_sect_t
*symsect
,
713 const ctf_sect_t
*strsect
, size_t offset
,
714 int little_endian
, int *errp
)
719 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset
);
721 memset (&ctfsect
, 0, sizeof (ctf_sect_t
));
723 offset
+= le64toh (arc
->ctfa_ctfs
);
725 ctfsect
.cts_name
= _CTF_SECTION
;
726 ctfsect
.cts_size
= le64toh (*((uint64_t *) ((char *) arc
+ offset
)));
727 ctfsect
.cts_entsize
= 1;
728 ctfsect
.cts_data
= (void *) ((char *) arc
+ offset
+ sizeof (uint64_t));
729 fp
= ctf_bufopen (&ctfsect
, symsect
, strsect
, errp
);
732 ctf_setmodel (fp
, le64toh (arc
->ctfa_model
));
733 if (little_endian
>= 0)
734 ctf_symsect_endianness (fp
, little_endian
);
739 /* Backward compatibility. */
741 ctf_arc_open_by_name (const ctf_archive_t
*arc
, const char *name
,
744 return ctf_dict_open (arc
, name
, errp
);
748 ctf_arc_open_by_name_sections (const ctf_archive_t
*arc
,
749 const ctf_sect_t
*symsect
,
750 const ctf_sect_t
*strsect
,
754 return ctf_dict_open_sections (arc
, symsect
, strsect
, name
, errp
);
757 /* Import the parent into a ctf archive, if this is a child, the parent is not
758 already set, and a suitable archive member exists. No error is raised if
759 this is not possible: this is just a best-effort helper operation to give
760 people useful dicts to start with. */
762 ctf_arc_import_parent (const ctf_archive_t
*arc
, ctf_dict_t
*fp
)
764 if ((fp
->ctf_flags
& LCTF_CHILD
) && fp
->ctf_parname
&& !fp
->ctf_parent
)
766 ctf_dict_t
*parent
= ctf_dict_open_cached ((ctf_archive_t
*) arc
,
767 fp
->ctf_parname
, NULL
);
770 ctf_import (fp
, parent
);
771 ctf_dict_close (parent
);
776 /* Return the number of members in an archive. */
778 ctf_archive_count (const ctf_archive_t
*wrapper
)
780 if (!wrapper
->ctfi_is_archive
)
783 return wrapper
->ctfi_archive
->ctfa_ndicts
;
786 /* Look up a symbol in an archive by name or index (if the name is set, a lookup
787 by name is done). Return the dict in the archive that the symbol is found
788 in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
789 have to look it up yourself). The dict is cached, so repeated lookups are
792 As usual, you should ctf_dict_close() the returned dict once you are done
795 Returns NULL on error, and an error in errp (if set). */
798 ctf_arc_lookup_sym_or_name (ctf_archive_t
*wrapper
, unsigned long symidx
,
799 const char *symname
, ctf_id_t
*typep
, int *errp
)
805 /* The usual non-archive-transparent-wrapper special case. */
806 if (!wrapper
->ctfi_is_archive
)
810 if ((type
= ctf_lookup_by_symbol (wrapper
->ctfi_dict
, symidx
)) == CTF_ERR
)
813 *errp
= ctf_errno (wrapper
->ctfi_dict
);
819 if ((type
= ctf_lookup_by_symbol_name (wrapper
->ctfi_dict
,
820 symname
)) == CTF_ERR
)
823 *errp
= ctf_errno (wrapper
->ctfi_dict
);
829 wrapper
->ctfi_dict
->ctf_refcnt
++;
830 return wrapper
->ctfi_dict
;
833 if (wrapper
->ctfi_symsect
.cts_name
== NULL
834 || wrapper
->ctfi_symsect
.cts_data
== NULL
835 || wrapper
->ctfi_symsect
.cts_size
== 0
836 || wrapper
->ctfi_symsect
.cts_entsize
== 0)
839 *errp
= ECTF_NOSYMTAB
;
843 /* Make enough space for all possible symbol indexes, if not already done. We
844 cache the originating dictionary of all symbols. The dict links are weak,
845 to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
846 We also cache similar mappings for symbol names: these are ordinary
847 dynhashes, with weak links to dicts. */
849 if (!wrapper
->ctfi_symdicts
)
851 if ((wrapper
->ctfi_symdicts
= calloc (wrapper
->ctfi_symsect
.cts_size
852 / wrapper
->ctfi_symsect
.cts_entsize
,
853 sizeof (ctf_dict_t
*))) == NULL
)
860 if (!wrapper
->ctfi_symnamedicts
)
862 if ((wrapper
->ctfi_symnamedicts
= ctf_dynhash_create (ctf_hash_string
,
864 free
, NULL
)) == NULL
)
872 /* Perhaps the dict in which we found a previous lookup is cached. If it's
873 supposed to be cached but we don't find it, pretend it was always not
874 found: this should never happen, but shouldn't be allowed to cause trouble
877 if ((symname
&& ctf_dynhash_lookup_kv (wrapper
->ctfi_symnamedicts
,
878 symname
, NULL
, &fpkey
))
879 || (!symname
&& wrapper
->ctfi_symdicts
[symidx
] != NULL
))
882 fp
= (ctf_dict_t
*) fpkey
;
884 fp
= wrapper
->ctfi_symdicts
[symidx
];
891 if ((type
= ctf_lookup_by_symbol_name (fp
, symname
)) == CTF_ERR
)
896 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) == CTF_ERR
)
906 /* Not cached: find it and cache it. We must track open errors ourselves even
907 if our caller doesn't, to be able to distinguish no-error end-of-iteration
912 ctf_next_t
*i
= NULL
;
918 local_errp
= &local_err
;
920 while ((fp
= ctf_archive_next (wrapper
, &i
, &name
, 0, local_errp
)) != NULL
)
924 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) != CTF_ERR
)
925 wrapper
->ctfi_symdicts
[symidx
] = fp
;
929 if ((type
= ctf_lookup_by_symbol_name (fp
, symname
)) != CTF_ERR
)
932 /* No error checking, as above. */
933 if ((tmp
= strdup (symname
)) != NULL
)
934 ctf_dynhash_insert (wrapper
->ctfi_symnamedicts
, tmp
, fp
);
942 ctf_next_destroy (i
);
945 if (ctf_errno (fp
) != ECTF_NOTYPEDAT
)
948 *errp
= ctf_errno (fp
);
949 ctf_next_destroy (i
);
950 return NULL
; /* errno is set for us. */
954 if (*local_errp
!= ECTF_NEXT_END
)
956 ctf_next_destroy (i
);
960 /* Don't leak end-of-iteration to the caller. */
965 wrapper
->ctfi_symdicts
[symidx
] = &enosym
;
970 /* No error checking: if caching fails, there is only a slight performance
972 if ((tmp
= strdup (symname
)) != NULL
)
973 if (ctf_dynhash_insert (wrapper
->ctfi_symnamedicts
, tmp
, &enosym
) < 0)
979 *errp
= ECTF_NOTYPEDAT
;
985 /* The public API for looking up a symbol by index. */
987 ctf_arc_lookup_symbol (ctf_archive_t
*wrapper
, unsigned long symidx
,
988 ctf_id_t
*typep
, int *errp
)
990 return ctf_arc_lookup_sym_or_name (wrapper
, symidx
, NULL
, typep
, errp
);
993 /* The public API for looking up a symbol by name. */
996 ctf_arc_lookup_symbol_name (ctf_archive_t
*wrapper
, const char *symname
,
997 ctf_id_t
*typep
, int *errp
)
999 return ctf_arc_lookup_sym_or_name (wrapper
, 0, symname
, typep
, errp
);
1002 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
1003 CTF files in turn to the specified callback function. */
1005 ctf_archive_raw_iter_internal (const struct ctf_archive
*arc
,
1006 ctf_archive_raw_member_f
*func
, void *data
)
1010 struct ctf_archive_modent
*modent
;
1011 const char *nametbl
;
1013 modent
= (ctf_archive_modent_t
*) ((char *) arc
1014 + sizeof (struct ctf_archive
));
1015 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
1017 for (i
= 0; i
< le64toh (arc
->ctfa_ndicts
); i
++)
1022 name
= &nametbl
[le64toh (modent
[i
].name_offset
)];
1023 fp
= ((char *) arc
+ le64toh (arc
->ctfa_ctfs
)
1024 + le64toh (modent
[i
].ctf_offset
));
1026 if ((rc
= func (name
, (void *) (fp
+ sizeof (uint64_t)),
1027 le64toh (*((uint64_t *) fp
)), data
)) != 0)
1033 /* Raw iteration over all CTF files in an archive: public entry point.
1035 Returns -EINVAL if not supported for this sort of archive. */
1037 ctf_archive_raw_iter (const ctf_archive_t
*arc
,
1038 ctf_archive_raw_member_f
* func
, void *data
)
1040 if (arc
->ctfi_is_archive
)
1041 return ctf_archive_raw_iter_internal (arc
->ctfi_archive
, func
, data
);
1043 return -EINVAL
; /* Not supported. */
1046 /* Iterate over all CTF files in an archive: public entry point. We pass all
1047 CTF files in turn to the specified callback function. */
1049 ctf_archive_iter (const ctf_archive_t
*arc
, ctf_archive_member_f
*func
,
1052 ctf_next_t
*i
= NULL
;
1057 while ((fp
= ctf_archive_next (arc
, &i
, &name
, 0, &err
)) != NULL
)
1061 if ((rc
= func (fp
, name
, data
)) != 0)
1063 ctf_dict_close (fp
);
1064 ctf_next_destroy (i
);
1067 ctf_dict_close (fp
);
1072 /* Iterate over all CTF files in an archive, returning each dict in turn as a
1073 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
1074 responsibility to close it. Parent dicts may be skipped.
1076 The archive member is cached for rapid return on future calls.
1078 We identify parents by name rather than by flag value: for now, with the
1079 linker only emitting parents named _CTF_SECTION, this works well enough. */
1082 ctf_archive_next (const ctf_archive_t
*wrapper
, ctf_next_t
**it
, const char **name
,
1083 int skip_parent
, int *errp
)
1086 ctf_next_t
*i
= *it
;
1087 struct ctf_archive
*arc
;
1088 struct ctf_archive_modent
*modent
;
1089 const char *nametbl
;
1094 if ((i
= ctf_next_create()) == NULL
)
1100 i
->cu
.ctn_arc
= wrapper
;
1101 i
->ctn_iter_fun
= (void (*) (void)) ctf_archive_next
;
1105 if ((void (*) (void)) ctf_archive_next
!= i
->ctn_iter_fun
)
1108 *errp
= ECTF_NEXT_WRONGFUN
;
1112 if (wrapper
!= i
->cu
.ctn_arc
)
1115 *errp
= ECTF_NEXT_WRONGFP
;
1119 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1120 transparently wrapped in a single-member archive. These are parents: if
1121 skip_parent is on, they are skipped and the iterator terminates
1124 if (!wrapper
->ctfi_is_archive
&& i
->ctn_n
== 0)
1129 wrapper
->ctfi_dict
->ctf_refcnt
++;
1131 *name
= _CTF_SECTION
;
1132 return wrapper
->ctfi_dict
;
1136 arc
= wrapper
->ctfi_archive
;
1138 /* The loop keeps going when skip_parent is on as long as the member we find
1139 is the parent (i.e. at most two iterations, but possibly an early return if
1140 *all* we have is a parent). */
1144 if ((!wrapper
->ctfi_is_archive
) || (i
->ctn_n
>= le64toh (arc
->ctfa_ndicts
)))
1146 ctf_next_destroy (i
);
1149 *errp
= ECTF_NEXT_END
;
1153 modent
= (ctf_archive_modent_t
*) ((char *) arc
1154 + sizeof (struct ctf_archive
));
1155 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
1157 name_
= &nametbl
[le64toh (modent
[i
->ctn_n
].name_offset
)];
1160 while (skip_parent
&& strcmp (name_
, _CTF_SECTION
) == 0);
1165 f
= ctf_dict_open_cached ((ctf_archive_t
*) wrapper
, name_
, errp
);
1170 /* Map the header in. Only used on new, empty files. */
1171 static void *arc_mmap_header (int fd
, size_t headersz
)
1174 if ((hdr
= mmap (NULL
, headersz
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
,
1180 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
1181 need to modify the region, but don't need anyone else to see the
1183 static void *arc_mmap_file (int fd
, size_t size
)
1186 if ((arc
= mmap (NULL
, size
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
,
1187 fd
, 0)) == MAP_FAILED
)
1192 /* Persist the header to disk. */
1193 static int arc_mmap_writeout (int fd _libctf_unused_
, void *header
,
1194 size_t headersz
, const char **errmsg
)
1196 if (msync (header
, headersz
, MS_ASYNC
) < 0)
1199 *errmsg
= N_("arc_mmap_writeout(): cannot sync after writing "
1206 /* Unmap the region. */
1207 static int arc_mmap_unmap (void *header
, size_t headersz
, const char **errmsg
)
1209 if (munmap (header
, headersz
) < 0)
1212 *errmsg
= N_("arc_mmap_munmap(): cannot unmap after writing "
1219 /* Map the header in. Only used on new, empty files. */
1220 static void *arc_mmap_header (int fd _libctf_unused_
, size_t headersz
)
1223 if ((hdr
= malloc (headersz
)) == NULL
)
1228 /* Pull in the whole file, for reading only. We assume the current file
1229 position is at the start of the file. */
1230 static void *arc_mmap_file (int fd
, size_t size
)
1234 if ((data
= malloc (size
)) == NULL
)
1237 if (ctf_pread (fd
, data
, size
, 0) < 0)
1245 /* Persist the header to disk. */
1246 static int arc_mmap_writeout (int fd
, void *header
, size_t headersz
,
1247 const char **errmsg
)
1251 char *data
= (char *) header
;
1252 ssize_t count
= headersz
;
1254 if ((lseek (fd
, 0, SEEK_SET
)) < 0)
1257 *errmsg
= N_("arc_mmap_writeout(): cannot seek while writing header to "
1262 while (headersz
> 0)
1264 if ((len
= write (fd
, data
, count
)) < 0)
1267 *errmsg
= N_("arc_mmap_writeout(): cannot write header to %s: %s");
1274 if (len
== 0) /* EOF. */
1283 /* Unmap the region. */
1284 static int arc_mmap_unmap (void *header
, size_t headersz _libctf_unused_
,
1285 const char **errmsg _libctf_unused_
)