]> Git Repo - binutils.git/blob - libctf/ctf-archive.c
libctf: fix comment above ctf_dict_t
[binutils.git] / libctf / ctf-archive.c
1 /* CTF archive files.
2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
3
4    This file is part of libctf.
5
6    libctf is free software; you can redistribute it and/or modify it under
7    the terms of the GNU General Public License as published by the Free
8    Software Foundation; either version 3, or (at your option) any later
9    version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14    See the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; see the file COPYING.  If not see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <ctf-impl.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <elf.h>
24 #include "ctf-endian.h"
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #ifdef HAVE_MMAP
32 #include <sys/mman.h>
33 #endif
34
35 static off_t arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold);
36 static ctf_dict_t *ctf_dict_open_by_offset (const struct ctf_archive *arc,
37                                             const ctf_sect_t *symsect,
38                                             const ctf_sect_t *strsect,
39                                             size_t offset, int little_endian,
40                                             int *errp);
41 static int sort_modent_by_name (const void *one, const void *two, void *n);
42 static void *arc_mmap_header (int fd, size_t headersz);
43 static void *arc_mmap_file (int fd, size_t size);
44 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
45                               const char **errmsg);
46 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
47 static void ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp);
48
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;
52
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.
56
57    Returns 0 on success, or an errno, or an ECTF_* value.  */
58 int
59 ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
60                   const char **names, size_t threshold)
61 {
62   const char *errmsg;
63   struct ctf_archive *archdr;
64   size_t i;
65   char dummy = 0;
66   size_t headersz;
67   ssize_t namesz;
68   size_t ctf_startoffs;         /* Start of the section we are working over.  */
69   char *nametbl = NULL;         /* The name table.  */
70   char *np;
71   off_t nameoffs;
72   struct ctf_archive_modent *modent;
73
74   ctf_dprintf ("Writing CTF archive with %lu files\n",
75                (unsigned long) ctf_dict_cnt);
76
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
80      uint64_t's.  */
81   headersz = sizeof (struct ctf_archive)
82     + (ctf_dict_cnt * sizeof (uint64_t) * 2);
83   ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
84
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)
90     {
91       errmsg = N_("ctf_arc_write(): cannot extend file while writing");
92       goto err;
93     }
94
95   if (write (fd, &dummy, 1) < 0)
96     {
97       errmsg = N_("ctf_arc_write(): cannot extend file while writing");
98       goto err;
99     }
100
101   if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
102     {
103       errmsg = N_("ctf_arc_write(): cannot mmap");
104       goto err;
105     }
106
107   /* Fill in everything we can, which is everything other than the name
108      table offset.  */
109   archdr->ctfa_magic = htole64 (CTFA_MAGIC);
110   archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
111   archdr->ctfa_ctfs = htole64 (ctf_startoffs);
112
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
119      memory.)  */
120
121   if (ctf_dict_cnt > 0)
122     archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
123
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.
128
129     The name table is not sorted.  */
130
131   for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
132     namesz += strlen (names[i]) + 1;
133
134   nametbl = malloc (namesz);
135   if (nametbl == NULL)
136     {
137       errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
138       goto err_unmap;
139     }
140
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++)
145     {
146       off_t off;
147
148       strcpy (&nametbl[namesz], names[i]);
149
150       off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
151       if ((off < 0) && (off > -ECTF_BASE))
152         {
153           errmsg = N_("ctf_arc_write(): cannot determine file "
154                       "position while writing to archive");
155           goto err_free;
156         }
157       if (off < 0)
158         {
159           errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
160           errno = off * -1;
161           goto err_free;
162         }
163
164       modent->name_offset = htole64 (namesz);
165       modent->ctf_offset = htole64 (off - ctf_startoffs);
166       namesz += strlen (names[i]) + 1;
167       modent++;
168     }
169
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,
174                nametbl);
175
176    /* Now the name table.  */
177
178   if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
179     {
180       errmsg = N_("ctf_arc_write(): cannot get current file position "
181                   "in archive");
182       goto err_free;
183     }
184   archdr->ctfa_names = htole64 (nameoffs);
185   np = nametbl;
186   while (namesz > 0)
187     {
188       ssize_t len;
189       if ((len = write (fd, np, namesz)) < 0)
190         {
191           errmsg = N_("ctf_arc_write(): cannot write name table to archive");
192           goto err_free;
193         }
194       namesz -= len;
195       np += len;
196     }
197   free (nametbl);
198
199   if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
200     goto err_unmap;
201   if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
202     goto err;
203   return 0;
204
205 err_free:
206   free (nametbl);
207 err_unmap:
208   arc_mmap_unmap (archdr, headersz, NULL);
209 err:
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",
214                 gettext (errmsg));
215   return errno;
216 }
217
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.
220
221    If the filename is NULL, create a temporary file and return a pointer to it.
222
223    Returns 0 on success, or an errno, or an ECTF_* value.  */
224 int
225 ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
226                const char **names, size_t threshold)
227 {
228   int err;
229   int fd;
230
231   if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
232     {
233       ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
234                     _("ctf_arc_write(): cannot create %s"), file);
235       return errno;
236     }
237
238   err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
239   if (err)
240     goto err_close;
241
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"));
245   goto err;
246
247  err_close:
248   (void) close (fd);
249  err:
250   if (err < 0)
251     unlink (file);
252
253   return err;
254 }
255
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.  */
260 static off_t
261 arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold)
262 {
263   off_t off, end_off;
264   uint64_t ctfsz = 0;
265   char *ctfszp;
266   size_t ctfsz_len;
267   int (*writefn) (ctf_dict_t * fp, int fd);
268
269   if (ctf_serialize (f) < 0)
270     return f->ctf_errno * -1;
271
272   if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
273     return errno * -1;
274
275   if (f->ctf_size > threshold)
276     writefn = ctf_compress_write;
277   else
278     writefn = ctf_write;
279
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)
284     {
285       ssize_t writelen = write (fd, ctfszp, ctfsz_len);
286       if (writelen < 0)
287         return errno * -1;
288       ctfsz_len -= writelen;
289       ctfszp += writelen;
290     }
291
292   if (writefn (f, fd) != 0)
293     return f->ctf_errno * -1;
294
295   if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
296     return errno * -1;
297   ctfsz = htole64 (end_off - off);
298
299   if ((lseek (fd, off, SEEK_SET)) < 0)
300     return errno * -1;
301
302   /* ... here.  */
303   ctfsz_len = sizeof (ctfsz);
304   ctfszp = (char *) &ctfsz;
305   while (ctfsz_len > 0)
306     {
307       ssize_t writelen = write (fd, ctfszp, ctfsz_len);
308       if (writelen < 0)
309         return errno * -1;
310       ctfsz_len -= writelen;
311       ctfszp += writelen;
312     }
313
314   end_off = LCTF_ALIGN_OFFS (end_off, 8);
315   if ((lseek (fd, end_off, SEEK_SET)) < 0)
316     return errno * -1;
317
318   return off;
319 }
320
321 /* qsort() function to sort the array of struct ctf_archive_modents into
322    ascending name order.  */
323 static int
324 sort_modent_by_name (const void *one, const void *two, void *n)
325 {
326   const struct ctf_archive_modent *a = one;
327   const struct ctf_archive_modent *b = two;
328   char *nametbl = n;
329
330   return strcmp (&nametbl[le64toh (a->name_offset)],
331                  &nametbl[le64toh (b->name_offset)]);
332 }
333
334 /* bsearch_r() function to search for a given name in the sorted array of struct
335    ctf_archive_modents.  */
336 static int
337 search_modent_by_name (const void *key, const void *ent, void *arg)
338 {
339   const char *k = key;
340   const struct ctf_archive_modent *v = ent;
341   const char *search_nametbl = arg;
342
343   return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
344 }
345
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.  */
349
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,
355                           int *errp)
356 {
357   struct ctf_archive_internal *arci;
358
359   if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
360     {
361       if (is_archive)
362         {
363           if (unmap_on_close)
364             ctf_arc_close_internal (arc);
365         }
366       else
367         ctf_dict_close (fp);
368       return (ctf_set_open_errno (errp, errno));
369     }
370   arci->ctfi_is_archive = is_archive;
371   if (is_archive)
372     arci->ctfi_archive = arc;
373   else
374     arci->ctfi_dict = fp;
375   if (symsect)
376      memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
377   if (strsect)
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;
383
384   return arci;
385 }
386
387 /* Set the symbol-table endianness of an archive (defaulting the symtab
388    endianness of all ctf_file_t's opened from that archive).  */
389 void
390 ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
391 {
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);
395 }
396
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
400    in.  */
401
402 const ctf_preamble_t *
403 ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
404 {
405   if (ctfsect->cts_size > sizeof (uint64_t) &&
406       (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
407     {
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));
411     }
412   else
413     return (const ctf_preamble_t *) ctfsect->cts_data;
414 }
415
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).  */
419 ctf_archive_t *
420 ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
421                  const ctf_sect_t *strsect, int *errp)
422 {
423   struct ctf_archive *arc = NULL;
424   int is_archive;
425   ctf_dict_t *fp = NULL;
426
427   if (ctfsect->cts_size > sizeof (uint64_t) &&
428       (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
429     {
430       /* The archive is mmappable, so this operation is trivial.
431
432          This buffer is nonmodifiable, so the trick involving mmapping only part
433          of it and storing the length in the magic number is not applicable: so
434          record this fact in the archive-wrapper header.  (We cannot record it
435          in the archive, because the archive may very well be a read-only
436          mapping.)  */
437
438       is_archive = 1;
439       arc = (struct ctf_archive *) ctfsect->cts_data;
440     }
441   else
442     {
443       is_archive = 0;
444       if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
445         {
446           ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
447           return NULL;
448         }
449     }
450   return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
451                                    errp);
452 }
453
454 /* Open a CTF archive.  Returns the archive, or NULL and an error in *err (if
455    not NULL).  */
456 struct ctf_archive *
457 ctf_arc_open_internal (const char *filename, int *errp)
458 {
459   const char *errmsg;
460   int fd;
461   struct stat s;
462   struct ctf_archive *arc;              /* (Actually the whole file.)  */
463
464   libctf_init_debug();
465   if ((fd = open (filename, O_RDONLY)) < 0)
466     {
467       errmsg = N_("ctf_arc_open(): cannot open %s");
468       goto err;
469     }
470   if (fstat (fd, &s) < 0)
471     {
472       errmsg = N_("ctf_arc_open(): cannot stat %s");
473       goto err_close;
474     }
475
476   if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
477     {
478       errmsg = N_("ctf_arc_open(): cannot read in %s");
479       goto err_close;
480     }
481
482   if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
483     {
484       errmsg = N_("ctf_arc_open(): %s: invalid magic number");
485       errno = ECTF_FMT;
486       goto err_unmap;
487     }
488
489   /* This horrible hack lets us know how much to unmap when the file is
490      closed.  (We no longer need the magic number, and the mapping
491      is private.)  */
492   arc->ctfa_magic = s.st_size;
493   close (fd);
494   return arc;
495
496 err_unmap:
497   arc_mmap_unmap (arc, s.st_size, NULL);
498 err_close:
499   close (fd);
500 err:
501   if (errp)
502     *errp = errno;
503   ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
504   return NULL;
505 }
506
507 /* Close an archive.  */
508 void
509 ctf_arc_close_internal (struct ctf_archive *arc)
510 {
511   if (arc == NULL)
512     return;
513
514   /* See the comment in ctf_arc_open().  */
515   arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
516 }
517
518 /* Public entry point: close an archive, or CTF file.  */
519 void
520 ctf_arc_close (ctf_archive_t *arc)
521 {
522   if (arc == NULL)
523     return;
524
525   if (arc->ctfi_is_archive)
526     {
527       if (arc->ctfi_unmap_on_close)
528         ctf_arc_close_internal (arc->ctfi_archive);
529     }
530   else
531     ctf_dict_close (arc->ctfi_dict);
532   free (arc->ctfi_symdicts);
533   free (arc->ctfi_symnamedicts);
534   ctf_dynhash_destroy (arc->ctfi_dicts);
535   if (arc->ctfi_free_symsect)
536     free ((void *) arc->ctfi_symsect.cts_data);
537   if (arc->ctfi_free_strsect)
538     free ((void *) arc->ctfi_strsect.cts_data);
539   free (arc->ctfi_data);
540   if (arc->ctfi_bfd_close)
541     arc->ctfi_bfd_close (arc);
542   free (arc);
543 }
544
545 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
546    non-NULL.  A name of NULL means to open the default file.  */
547 static ctf_dict_t *
548 ctf_dict_open_internal (const struct ctf_archive *arc,
549                         const ctf_sect_t *symsect,
550                         const ctf_sect_t *strsect,
551                         const char *name, int little_endian,
552                         int *errp)
553 {
554   struct ctf_archive_modent *modent;
555   const char *search_nametbl;
556
557   if (name == NULL)
558     name = _CTF_SECTION;                 /* The default name.  */
559
560   ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
561
562   modent = (ctf_archive_modent_t *) ((char *) arc
563                                      + sizeof (struct ctf_archive));
564
565   search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
566   modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
567                       sizeof (struct ctf_archive_modent),
568                       search_modent_by_name, (void *) search_nametbl);
569
570   /* This is actually a common case and normal operation: no error
571      debug output.  */
572   if (modent == NULL)
573     {
574       if (errp)
575         *errp = ECTF_ARNNAME;
576       return NULL;
577     }
578
579   return ctf_dict_open_by_offset (arc, symsect, strsect,
580                                   le64toh (modent->ctf_offset),
581                                   little_endian, errp);
582 }
583
584 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
585    non-NULL.  A name of NULL means to open the default file.
586
587    Use the specified string and symbol table sections.
588
589    Public entry point.  */
590 ctf_dict_t *
591 ctf_dict_open_sections (const ctf_archive_t *arc,
592                         const ctf_sect_t *symsect,
593                         const ctf_sect_t *strsect,
594                         const char *name,
595                         int *errp)
596 {
597   if (arc->ctfi_is_archive)
598     {
599       ctf_dict_t *ret;
600       ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
601                                     name, arc->ctfi_symsect_little_endian,
602                                     errp);
603       if (ret)
604         {
605           ret->ctf_archive = (ctf_archive_t *) arc;
606           ctf_arc_import_parent (arc, ret);
607         }
608       return ret;
609     }
610
611   if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
612     {
613       if (errp)
614         *errp = ECTF_ARNNAME;
615       return NULL;
616     }
617   arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
618
619   /* Bump the refcount so that the user can ctf_dict_close() it.  */
620   arc->ctfi_dict->ctf_refcnt++;
621   return arc->ctfi_dict;
622 }
623
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.
626
627    Public entry point.  */
628 ctf_dict_t *
629 ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
630 {
631   const ctf_sect_t *symsect = &arc->ctfi_symsect;
632   const ctf_sect_t *strsect = &arc->ctfi_strsect;
633
634   if (symsect->cts_name == NULL)
635     symsect = NULL;
636   if (strsect->cts_name == NULL)
637     strsect = NULL;
638
639   return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
640 }
641
642 static void
643 ctf_cached_dict_close (void *fp)
644 {
645   ctf_dict_close ((ctf_dict_t *) fp);
646 }
647
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
650    crossdict_cache.  */
651 static ctf_dict_t *
652 ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
653 {
654   ctf_dict_t *fp;
655   char *dupname;
656
657   /* Just return from the cache if possible.  */
658   if (arc->ctfi_dicts
659       && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
660     {
661       fp->ctf_refcnt++;
662       return fp;
663     }
664
665   /* Not yet cached: open it.  */
666   fp = ctf_dict_open (arc, name, errp);
667   dupname = strdup (name);
668
669   if (!fp || !dupname)
670     goto oom;
671
672   if (arc->ctfi_dicts == NULL)
673     if ((arc->ctfi_dicts
674          = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
675                                free, ctf_cached_dict_close)) == NULL)
676       goto oom;
677
678   if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
679     goto oom;
680   fp->ctf_refcnt++;
681
682   if (arc->ctfi_crossdict_cache == NULL)
683     arc->ctfi_crossdict_cache = fp;
684
685   return fp;
686
687  oom:
688   ctf_dict_close (fp);
689   free (dupname);
690   if (errp)
691     *errp = ENOMEM;
692   return NULL;
693 }
694
695 /* Flush any caches the CTF archive may have open.  */
696 void
697 ctf_arc_flush_caches (ctf_archive_t *wrapper)
698 {
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;
706 }
707
708 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
709    none, setting 'err' if non-NULL.  */
710 static ctf_dict_t *
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)
715 {
716   ctf_sect_t ctfsect;
717   ctf_dict_t *fp;
718
719   ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
720
721   memset (&ctfsect, 0, sizeof (ctf_sect_t));
722
723   offset += le64toh (arc->ctfa_ctfs);
724
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);
730   if (fp)
731     {
732       ctf_setmodel (fp, le64toh (arc->ctfa_model));
733       if (little_endian >= 0)
734         ctf_symsect_endianness (fp, little_endian);
735     }
736   return fp;
737 }
738
739 /* Backward compatibility.  */
740 ctf_dict_t *
741 ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
742                       int *errp)
743 {
744   return ctf_dict_open (arc, name, errp);
745 }
746
747 ctf_dict_t *
748 ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
749                                const ctf_sect_t *symsect,
750                                const ctf_sect_t *strsect,
751                                const char *name,
752                                int *errp)
753 {
754   return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
755 }
756
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.  */
761 static void
762 ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp)
763 {
764   if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
765     {
766       ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
767                                                  fp->ctf_parname, NULL);
768       if (parent)
769         {
770           ctf_import (fp, parent);
771           ctf_dict_close (parent);
772         }
773     }
774 }
775
776 /* Return the number of members in an archive.  */
777 size_t
778 ctf_archive_count (const ctf_archive_t *wrapper)
779 {
780   if (!wrapper->ctfi_is_archive)
781     return 1;
782
783   return wrapper->ctfi_archive->ctfa_ndicts;
784 }
785
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
790    nearly free.
791
792    As usual, you should ctf_dict_close() the returned dict once you are done
793    with it.
794
795    Returns NULL on error, and an error in errp (if set).  */
796
797 static ctf_dict_t *
798 ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
799                             const char *symname, ctf_id_t *typep, int *errp)
800 {
801   ctf_dict_t *fp;
802   void *fpkey;
803   ctf_id_t type;
804
805   /* The usual non-archive-transparent-wrapper special case.  */
806   if (!wrapper->ctfi_is_archive)
807     {
808       if (!symname)
809         {
810           if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
811             {
812               if (errp)
813                 *errp = ctf_errno (wrapper->ctfi_dict);
814               return NULL;
815             }
816         }
817       else
818         {
819           if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
820                                                  symname)) == CTF_ERR)
821             {
822               if (errp)
823                 *errp = ctf_errno (wrapper->ctfi_dict);
824               return NULL;
825             }
826         }
827       if (typep)
828         *typep = type;
829       wrapper->ctfi_dict->ctf_refcnt++;
830       return wrapper->ctfi_dict;
831     }
832
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)
837     {
838       if (errp)
839         *errp = ECTF_NOSYMTAB;
840       return NULL;
841     }
842
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.  */
848
849   if (!wrapper->ctfi_symdicts)
850     {
851       if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
852                                             / wrapper->ctfi_symsect.cts_entsize,
853                                             sizeof (ctf_dict_t *))) == NULL)
854         {
855           if (errp)
856             *errp = ENOMEM;
857           return NULL;
858         }
859     }
860   if (!wrapper->ctfi_symnamedicts)
861     {
862       if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
863                                                             ctf_hash_eq_string,
864                                                             free, NULL)) == NULL)
865         {
866           if (errp)
867             *errp = ENOMEM;
868           return NULL;
869         }
870     }
871
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
875      if it does.  */
876
877   if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
878                                          symname, NULL, &fpkey))
879       || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
880     {
881       if (symname)
882         fp = (ctf_dict_t *) fpkey;
883       else
884         fp = wrapper->ctfi_symdicts[symidx];
885
886       if (fp == &enosym)
887         goto no_sym;
888
889       if (symname)
890         {
891           if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
892             goto cache_no_sym;
893         }
894       else
895         {
896           if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
897             goto cache_no_sym;
898         }
899
900       if (typep)
901         *typep = type;
902       fp->ctf_refcnt++;
903       return fp;
904     }
905
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
908      from open errors.  */
909
910   int local_err;
911   int *local_errp;
912   ctf_next_t *i = NULL;
913   const char *name;
914
915   if (errp)
916     local_errp = errp;
917   else
918     local_errp = &local_err;
919
920   while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
921     {
922       if (!symname)
923         {
924           if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
925             wrapper->ctfi_symdicts[symidx] = fp;
926         }
927       else
928         {
929           if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
930             {
931               char *tmp;
932               /* No error checking, as above.  */
933               if ((tmp = strdup (symname)) != NULL)
934                 ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
935             }
936         }
937
938       if (type != CTF_ERR)
939         {
940           if (typep)
941             *typep = type;
942           ctf_next_destroy (i);
943           return fp;
944         }
945       if (ctf_errno (fp) != ECTF_NOTYPEDAT)
946         {
947           if (errp)
948             *errp = ctf_errno (fp);
949           ctf_next_destroy (i);
950           return NULL;                          /* errno is set for us.  */
951         }
952       ctf_dict_close (fp);
953     }
954   if (*local_errp != ECTF_NEXT_END)
955     {
956       ctf_next_destroy (i);
957       return NULL;
958     }
959
960   /* Don't leak end-of-iteration to the caller.  */
961   *local_errp = 0;
962
963  cache_no_sym:
964   if (!symname)
965     wrapper->ctfi_symdicts[symidx] = &enosym;
966   else
967     {
968       char *tmp;
969
970       /* No error checking: if caching fails, there is only a slight performance
971          impact.  */
972       if ((tmp = strdup (symname)) != NULL)
973         if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
974           free (tmp);
975     }
976
977  no_sym:
978   if (errp)
979     *errp = ECTF_NOTYPEDAT;
980   if (typep)
981     *typep = CTF_ERR;
982   return NULL;
983 }
984
985 /* The public API for looking up a symbol by index.  */
986 ctf_dict_t *
987 ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
988                        ctf_id_t *typep, int *errp)
989 {
990   return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
991 }
992
993 /* The public API for looking up a symbol by name. */
994
995 ctf_dict_t *
996 ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
997                             ctf_id_t *typep, int *errp)
998 {
999   return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1000 }
1001
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.  */
1004 static int
1005 ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1006                                ctf_archive_raw_member_f *func, void *data)
1007 {
1008   int rc;
1009   size_t i;
1010   struct ctf_archive_modent *modent;
1011   const char *nametbl;
1012
1013   modent = (ctf_archive_modent_t *) ((char *) arc
1014                                      + sizeof (struct ctf_archive));
1015   nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1016
1017   for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
1018     {
1019       const char *name;
1020       char *fp;
1021
1022       name = &nametbl[le64toh (modent[i].name_offset)];
1023       fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1024             + le64toh (modent[i].ctf_offset));
1025
1026       if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1027                       le64toh (*((uint64_t *) fp)), data)) != 0)
1028         return rc;
1029     }
1030   return 0;
1031 }
1032
1033 /* Raw iteration over all CTF files in an archive: public entry point.
1034
1035    Returns -EINVAL if not supported for this sort of archive.  */
1036 int
1037 ctf_archive_raw_iter (const ctf_archive_t *arc,
1038                       ctf_archive_raw_member_f * func, void *data)
1039 {
1040   if (arc->ctfi_is_archive)
1041     return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1042
1043   return -EINVAL;                        /* Not supported. */
1044 }
1045
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.  */
1048 int
1049 ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1050                   void *data)
1051 {
1052   ctf_next_t *i = NULL;
1053   ctf_dict_t *fp;
1054   const char *name;
1055   int err;
1056
1057   while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
1058     {
1059       int rc;
1060
1061       if ((rc = func (fp, name, data)) != 0)
1062         {
1063           ctf_dict_close (fp);
1064           ctf_next_destroy (i);
1065           return rc;
1066         }
1067       ctf_dict_close (fp);
1068     }
1069   return 0;
1070 }
1071
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.
1075
1076    The archive member is cached for rapid return on future calls.
1077
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.  */
1080
1081 ctf_dict_t *
1082 ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1083                   int skip_parent, int *errp)
1084 {
1085   ctf_dict_t *f;
1086   ctf_next_t *i = *it;
1087   struct ctf_archive *arc;
1088   struct ctf_archive_modent *modent;
1089   const char *nametbl;
1090   const char *name_;
1091
1092   if (!i)
1093     {
1094       if ((i = ctf_next_create()) == NULL)
1095         {
1096           if (errp)
1097             *errp = ENOMEM;
1098           return NULL;
1099         }
1100       i->cu.ctn_arc = wrapper;
1101       i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1102       *it = i;
1103     }
1104
1105   if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1106     {
1107       if (errp)
1108         *errp = ECTF_NEXT_WRONGFUN;
1109       return NULL;
1110     }
1111
1112   if (wrapper != i->cu.ctn_arc)
1113     {
1114       if (errp)
1115         *errp = ECTF_NEXT_WRONGFP;
1116       return NULL;
1117     }
1118
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
1122      immediately.  */
1123
1124   if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1125     {
1126       i->ctn_n++;
1127       if (!skip_parent)
1128         {
1129           wrapper->ctfi_dict->ctf_refcnt++;
1130           if (name)
1131             *name = _CTF_SECTION;
1132           return wrapper->ctfi_dict;
1133         }
1134     }
1135
1136   arc = wrapper->ctfi_archive;
1137
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).  */
1141
1142   do
1143     {
1144       if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1145         {
1146           ctf_next_destroy (i);
1147           *it = NULL;
1148           if (errp)
1149             *errp = ECTF_NEXT_END;
1150           return NULL;
1151         }
1152
1153       modent = (ctf_archive_modent_t *) ((char *) arc
1154                                          + sizeof (struct ctf_archive));
1155       nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1156
1157       name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1158       i->ctn_n++;
1159     } while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1160
1161   if (name)
1162     *name = name_;
1163
1164   f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1165   return f;
1166 }
1167
1168 #ifdef HAVE_MMAP
1169 /* Map the header in.  Only used on new, empty files.  */
1170 static void *arc_mmap_header (int fd, size_t headersz)
1171 {
1172   void *hdr;
1173   if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1174                    0)) == MAP_FAILED)
1175     return NULL;
1176   return hdr;
1177 }
1178
1179 /* mmap() the whole file, for reading only.  (Map it writably, but privately: we
1180    need to modify the region, but don't need anyone else to see the
1181    modifications.)  */
1182 static void *arc_mmap_file (int fd, size_t size)
1183 {
1184   void *arc;
1185   if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1186                    fd, 0)) == MAP_FAILED)
1187     return NULL;
1188   return arc;
1189 }
1190
1191 /* Persist the header to disk.  */
1192 static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1193                               size_t headersz, const char **errmsg)
1194 {
1195     if (msync (header, headersz, MS_ASYNC) < 0)
1196     {
1197       if (errmsg)
1198         *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1199                      "to %s: %s");
1200       return -1;
1201     }
1202     return 0;
1203 }
1204
1205 /* Unmap the region.  */
1206 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1207 {
1208   if (munmap (header, headersz) < 0)
1209     {
1210       if (errmsg)
1211         *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1212                      "to %s: %s");
1213       return -1;
1214     }
1215     return 0;
1216 }
1217 #else
1218 /* Map the header in.  Only used on new, empty files.  */
1219 static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1220 {
1221   void *hdr;
1222   if ((hdr = malloc (headersz)) == NULL)
1223     return NULL;
1224   return hdr;
1225 }
1226
1227 /* Pull in the whole file, for reading only.  We assume the current file
1228    position is at the start of the file.  */
1229 static void *arc_mmap_file (int fd, size_t size)
1230 {
1231   char *data;
1232
1233   if ((data = malloc (size)) == NULL)
1234     return NULL;
1235
1236   if (ctf_pread (fd, data, size, 0) < 0)
1237     {
1238       free (data);
1239       return NULL;
1240     }
1241   return data;
1242 }
1243
1244 /* Persist the header to disk.  */
1245 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1246                               const char **errmsg)
1247 {
1248   ssize_t len;
1249   size_t acc = 0;
1250   char *data = (char *) header;
1251   ssize_t count = headersz;
1252
1253   if ((lseek (fd, 0, SEEK_SET)) < 0)
1254     {
1255       if (errmsg)
1256         *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1257                      "%s: %s");
1258       return -1;
1259     }
1260
1261   while (headersz > 0)
1262     {
1263       if ((len = write (fd, data, count)) < 0)
1264         {
1265           if (errmsg)
1266             *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1267           return len;
1268         }
1269       if (len == EINTR)
1270         continue;
1271
1272       acc += len;
1273       if (len == 0)                             /* EOF.  */
1274         break;
1275
1276       count -= len;
1277       data += len;
1278     }
1279   return 0;
1280 }
1281
1282 /* Unmap the region.  */
1283 static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1284                            const char **errmsg _libctf_unused_)
1285 {
1286   free (header);
1287   return 0;
1288 }
1289 #endif
This page took 0.095018 seconds and 4 git commands to generate.