]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libctf/ctf-archive.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.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
50 ctf_archive_internal.ctfi_symdicts. 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_syms);
533 free (arc->ctfi_symdicts);
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
649 archive's ctfi_dicts. */
650 static ctf_dict_t *
651 ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
652 {
653 ctf_dict_t *fp;
654 char *dupname;
655
656 /* Just return from the cache if possible. */
657 if (arc->ctfi_dicts
658 && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
659 {
660 fp->ctf_refcnt++;
661 return fp;
662 }
663
664 /* Not yet cached: open it. */
665 fp = ctf_dict_open (arc, name, errp);
666 dupname = strdup (name);
667
668 if (!fp || !dupname)
669 goto oom;
670
671 if (arc->ctfi_dicts == NULL)
672 if ((arc->ctfi_dicts
673 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
674 free, ctf_cached_dict_close)) == NULL)
675 goto oom;
676
677 if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
678 goto oom;
679 fp->ctf_refcnt++;
680
681 return fp;
682
683 oom:
684 ctf_dict_close (fp);
685 free (dupname);
686 if (errp)
687 *errp = ENOMEM;
688 return NULL;
689 }
690
691 /* Flush any caches the CTF archive may have open. */
692 void
693 ctf_arc_flush_caches (ctf_archive_t *wrapper)
694 {
695 free (wrapper->ctfi_symdicts);
696 free (wrapper->ctfi_syms);
697 ctf_dynhash_destroy (wrapper->ctfi_dicts);
698 wrapper->ctfi_symdicts = NULL;
699 wrapper->ctfi_syms = NULL;
700 wrapper->ctfi_dicts = NULL;
701 }
702
703 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
704 none, setting 'err' if non-NULL. */
705 static ctf_dict_t *
706 ctf_dict_open_by_offset (const struct ctf_archive *arc,
707 const ctf_sect_t *symsect,
708 const ctf_sect_t *strsect, size_t offset,
709 int little_endian, int *errp)
710 {
711 ctf_sect_t ctfsect;
712 ctf_dict_t *fp;
713
714 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
715
716 memset (&ctfsect, 0, sizeof (ctf_sect_t));
717
718 offset += le64toh (arc->ctfa_ctfs);
719
720 ctfsect.cts_name = _CTF_SECTION;
721 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
722 ctfsect.cts_entsize = 1;
723 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
724 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
725 if (fp)
726 {
727 ctf_setmodel (fp, le64toh (arc->ctfa_model));
728 if (little_endian >= 0)
729 ctf_symsect_endianness (fp, little_endian);
730 }
731 return fp;
732 }
733
734 /* Backward compatibility. */
735 ctf_dict_t *
736 ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
737 int *errp)
738 {
739 return ctf_dict_open (arc, name, errp);
740 }
741
742 ctf_dict_t *
743 ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
744 const ctf_sect_t *symsect,
745 const ctf_sect_t *strsect,
746 const char *name,
747 int *errp)
748 {
749 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
750 }
751
752 /* Import the parent into a ctf archive, if this is a child, the parent is not
753 already set, and a suitable archive member exists. No error is raised if
754 this is not possible: this is just a best-effort helper operation to give
755 people useful dicts to start with. */
756 static void
757 ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp)
758 {
759 if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
760 {
761 ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
762 fp->ctf_parname, NULL);
763 if (parent)
764 {
765 ctf_import (fp, parent);
766 ctf_dict_close (parent);
767 }
768 }
769 }
770
771 /* Return the number of members in an archive. */
772 size_t
773 ctf_archive_count (const ctf_archive_t *wrapper)
774 {
775 if (!wrapper->ctfi_is_archive)
776 return 1;
777
778 return wrapper->ctfi_archive->ctfa_ndicts;
779 }
780
781 /* Look up a symbol in an archive. Return the dict in the archive that the
782 symbol is found in, and (optionally) the ctf_id_t of the symbol in that dict
783 (so you don't have to look it up yourself). The dict and mapping are both
784 cached, so repeated lookups are nearly free.
785
786 As usual, you should ctf_dict_close() the returned dict once you are done
787 with it.
788
789 Returns NULL on error, and an error in errp (if set). */
790
791 ctf_dict_t *
792 ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
793 ctf_id_t *typep, int *errp)
794 {
795 ctf_dict_t *fp;
796 ctf_id_t type;
797
798 /* The usual non-archive-transparent-wrapper special case. */
799 if (!wrapper->ctfi_is_archive)
800 {
801 if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
802 {
803 if (errp)
804 *errp = ctf_errno (wrapper->ctfi_dict);
805 return NULL;
806 }
807 if (typep)
808 *typep = type;
809 wrapper->ctfi_dict->ctf_refcnt++;
810 return wrapper->ctfi_dict;
811 }
812
813 if (wrapper->ctfi_symsect.cts_name == NULL
814 || wrapper->ctfi_symsect.cts_data == NULL
815 || wrapper->ctfi_symsect.cts_size == 0
816 || wrapper->ctfi_symsect.cts_entsize == 0)
817 {
818 if (errp)
819 *errp = ECTF_NOSYMTAB;
820 return NULL;
821 }
822
823 /* Make enough space for all possible symbols, if not already done.
824 We cache both the ctf_id_t and the originating dictionary of all symbols.
825 The dict links are weak, to the dictionaries cached in ctfi_dicts: their
826 refcnts are *not* bumped. */
827
828 if (!wrapper->ctfi_syms)
829 {
830 if ((wrapper->ctfi_syms = calloc (wrapper->ctfi_symsect.cts_size
831 / wrapper->ctfi_symsect.cts_entsize,
832 sizeof (ctf_id_t))) == NULL)
833 {
834 if (errp)
835 *errp = ENOMEM;
836 return NULL;
837 }
838 }
839 if (!wrapper->ctfi_symdicts)
840 {
841 if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
842 / wrapper->ctfi_symsect.cts_entsize,
843 sizeof (ctf_dict_t *))) == NULL)
844 {
845 if (errp)
846 *errp = ENOMEM;
847 return NULL;
848 }
849 }
850
851 /* Perhaps it's cached. */
852 if (wrapper->ctfi_symdicts[symidx] != NULL)
853 {
854 if (wrapper->ctfi_symdicts[symidx] == &enosym)
855 {
856 if (errp)
857 *errp = ECTF_NOTYPEDAT;
858 if (typep)
859 *typep = CTF_ERR;
860 return NULL;
861 }
862
863 if (typep)
864 *typep = wrapper->ctfi_syms[symidx];
865 wrapper->ctfi_symdicts[symidx]->ctf_refcnt++;
866 return wrapper->ctfi_symdicts[symidx];
867 }
868
869 /* Not cached: find it and cache it. We must track open errors ourselves even
870 if our caller doesn't, to be able to distinguish no-error end-of-iteration
871 from open errors. */
872
873 int local_err;
874 int *local_errp;
875 ctf_next_t *i = NULL;
876 const char *name;
877
878 if (errp)
879 local_errp = errp;
880 else
881 local_errp = &local_err;
882
883 while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
884 {
885 if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
886 {
887 wrapper->ctfi_syms[symidx] = type;
888 wrapper->ctfi_symdicts[symidx] = fp;
889 ctf_next_destroy (i);
890
891 if (typep)
892 *typep = type;
893 return fp;
894 }
895 ctf_dict_close (fp);
896 }
897 if (*local_errp != ECTF_NEXT_END)
898 {
899 ctf_next_destroy (i);
900 return NULL;
901 }
902 /* Don't leak end-of-iteration to the caller. */
903 *local_errp = 0;
904
905 wrapper->ctfi_symdicts[symidx] = &enosym;
906
907 if (errp)
908 *errp = ECTF_NOTYPEDAT;
909 if (typep)
910 *typep = CTF_ERR;
911 return NULL;
912 }
913
914 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
915 CTF files in turn to the specified callback function. */
916 static int
917 ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
918 ctf_archive_raw_member_f *func, void *data)
919 {
920 int rc;
921 size_t i;
922 struct ctf_archive_modent *modent;
923 const char *nametbl;
924
925 modent = (ctf_archive_modent_t *) ((char *) arc
926 + sizeof (struct ctf_archive));
927 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
928
929 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
930 {
931 const char *name;
932 char *fp;
933
934 name = &nametbl[le64toh (modent[i].name_offset)];
935 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
936 + le64toh (modent[i].ctf_offset));
937
938 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
939 le64toh (*((uint64_t *) fp)), data)) != 0)
940 return rc;
941 }
942 return 0;
943 }
944
945 /* Raw iteration over all CTF files in an archive: public entry point.
946
947 Returns -EINVAL if not supported for this sort of archive. */
948 int
949 ctf_archive_raw_iter (const ctf_archive_t *arc,
950 ctf_archive_raw_member_f * func, void *data)
951 {
952 if (arc->ctfi_is_archive)
953 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
954
955 return -EINVAL; /* Not supported. */
956 }
957
958 /* Iterate over all CTF files in an archive. We pass all CTF files in turn to
959 the specified callback function. */
960 static int
961 ctf_archive_iter_internal (const ctf_archive_t *wrapper,
962 const struct ctf_archive *arc,
963 const ctf_sect_t *symsect,
964 const ctf_sect_t *strsect,
965 ctf_archive_member_f *func, void *data)
966 {
967 int rc;
968 size_t i;
969 ctf_dict_t *f;
970 struct ctf_archive_modent *modent;
971 const char *nametbl;
972
973 modent = (ctf_archive_modent_t *) ((char *) arc
974 + sizeof (struct ctf_archive));
975 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
976
977 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
978 {
979 const char *name;
980
981 name = &nametbl[le64toh (modent[i].name_offset)];
982 if ((f = ctf_dict_open_internal (arc, symsect, strsect,
983 name,
984 wrapper->ctfi_symsect_little_endian,
985 &rc)) == NULL)
986 return rc;
987
988 f->ctf_archive = (ctf_archive_t *) wrapper;
989 ctf_arc_import_parent (wrapper, f);
990 if ((rc = func (f, name, data)) != 0)
991 {
992 ctf_dict_close (f);
993 return rc;
994 }
995
996 ctf_dict_close (f);
997 }
998 return 0;
999 }
1000
1001 /* Iterate over all CTF files in an archive: public entry point. We pass all
1002 CTF files in turn to the specified callback function. */
1003 int
1004 ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1005 void *data)
1006 {
1007 const ctf_sect_t *symsect = &arc->ctfi_symsect;
1008 const ctf_sect_t *strsect = &arc->ctfi_strsect;
1009
1010 if (symsect->cts_name == NULL)
1011 symsect = NULL;
1012 if (strsect->cts_name == NULL)
1013 strsect = NULL;
1014
1015 if (arc->ctfi_is_archive)
1016 return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect,
1017 func, data);
1018
1019 return func (arc->ctfi_dict, _CTF_SECTION, data);
1020 }
1021
1022 /* Iterate over all CTF files in an archive, returning each dict in turn as a
1023 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
1024 responsibility to close it. Parent dicts may be skipped. Regardless of
1025 whether they are skipped or not, the caller must ctf_import the parent if
1026 need be.
1027
1028 The archive member is cached for rapid return on future calls.
1029
1030 We identify parents by name rather than by flag value: for now, with the
1031 linker only emitting parents named _CTF_SECTION, this works well enough. */
1032
1033 ctf_dict_t *
1034 ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1035 int skip_parent, int *errp)
1036 {
1037 ctf_dict_t *f;
1038 ctf_next_t *i = *it;
1039 struct ctf_archive *arc;
1040 struct ctf_archive_modent *modent;
1041 const char *nametbl;
1042 const char *name_;
1043
1044 if (!i)
1045 {
1046 if ((i = ctf_next_create()) == NULL)
1047 {
1048 if (errp)
1049 *errp = ENOMEM;
1050 return NULL;
1051 }
1052 i->cu.ctn_arc = wrapper;
1053 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1054 *it = i;
1055 }
1056
1057 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1058 {
1059 if (errp)
1060 *errp = ECTF_NEXT_WRONGFUN;
1061 return NULL;
1062 }
1063
1064 if (wrapper != i->cu.ctn_arc)
1065 {
1066 if (errp)
1067 *errp = ECTF_NEXT_WRONGFP;
1068 return NULL;
1069 }
1070
1071 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
1072 transparently wrapped in a single-member archive. These are parents: if
1073 skip_parent is on, they are skipped and the iterator terminates
1074 immediately. */
1075
1076 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1077 {
1078 i->ctn_n++;
1079 if (!skip_parent)
1080 {
1081 wrapper->ctfi_dict->ctf_refcnt++;
1082 return wrapper->ctfi_dict;
1083 }
1084 }
1085
1086 arc = wrapper->ctfi_archive;
1087
1088 /* The loop keeps going when skip_parent is on as long as the member we find
1089 is the parent (i.e. at most two iterations, but possibly an early return if
1090 *all* we have is a parent). */
1091
1092 do
1093 {
1094 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
1095 {
1096 ctf_next_destroy (i);
1097 *it = NULL;
1098 if (errp)
1099 *errp = ECTF_NEXT_END;
1100 return NULL;
1101 }
1102
1103 modent = (ctf_archive_modent_t *) ((char *) arc
1104 + sizeof (struct ctf_archive));
1105 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1106
1107 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1108 i->ctn_n++;
1109 } while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
1110
1111 if (name)
1112 *name = name_;
1113
1114 f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
1115 return f;
1116 }
1117
1118 #ifdef HAVE_MMAP
1119 /* Map the header in. Only used on new, empty files. */
1120 static void *arc_mmap_header (int fd, size_t headersz)
1121 {
1122 void *hdr;
1123 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1124 0)) == MAP_FAILED)
1125 return NULL;
1126 return hdr;
1127 }
1128
1129 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
1130 need to modify the region, but don't need anyone else to see the
1131 modifications.) */
1132 static void *arc_mmap_file (int fd, size_t size)
1133 {
1134 void *arc;
1135 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1136 fd, 0)) == MAP_FAILED)
1137 return NULL;
1138 return arc;
1139 }
1140
1141 /* Persist the header to disk. */
1142 static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1143 size_t headersz, const char **errmsg)
1144 {
1145 if (msync (header, headersz, MS_ASYNC) < 0)
1146 {
1147 if (errmsg)
1148 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1149 "to %s: %s");
1150 return -1;
1151 }
1152 return 0;
1153 }
1154
1155 /* Unmap the region. */
1156 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1157 {
1158 if (munmap (header, headersz) < 0)
1159 {
1160 if (errmsg)
1161 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1162 "to %s: %s");
1163 return -1;
1164 }
1165 return 0;
1166 }
1167 #else
1168 /* Map the header in. Only used on new, empty files. */
1169 static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
1170 {
1171 void *hdr;
1172 if ((hdr = malloc (headersz)) == NULL)
1173 return NULL;
1174 return hdr;
1175 }
1176
1177 /* Pull in the whole file, for reading only. We assume the current file
1178 position is at the start of the file. */
1179 static void *arc_mmap_file (int fd, size_t size)
1180 {
1181 char *data;
1182
1183 if ((data = malloc (size)) == NULL)
1184 return NULL;
1185
1186 if (ctf_pread (fd, data, size, 0) < 0)
1187 {
1188 free (data);
1189 return NULL;
1190 }
1191 return data;
1192 }
1193
1194 /* Persist the header to disk. */
1195 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1196 const char **errmsg)
1197 {
1198 ssize_t len;
1199 size_t acc = 0;
1200 char *data = (char *) header;
1201 ssize_t count = headersz;
1202
1203 if ((lseek (fd, 0, SEEK_SET)) < 0)
1204 {
1205 if (errmsg)
1206 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1207 "%s: %s");
1208 return -1;
1209 }
1210
1211 while (headersz > 0)
1212 {
1213 if ((len = write (fd, data, count)) < 0)
1214 {
1215 if (errmsg)
1216 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
1217 return len;
1218 }
1219 if (len == EINTR)
1220 continue;
1221
1222 acc += len;
1223 if (len == 0) /* EOF. */
1224 break;
1225
1226 count -= len;
1227 data += len;
1228 }
1229 return 0;
1230 }
1231
1232 /* Unmap the region. */
1233 static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1234 const char **errmsg _libctf_unused_)
1235 {
1236 free (header);
1237 return 0;
1238 }
1239 #endif