bfd, include, ld, binutils, libctf: CTF should use the dynstr/sym
[binutils-gdb.git] / libctf / ctf-archive.c
1 /* CTF archive files.
2 Copyright (C) 2019-2020 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 *errp);
40 static int sort_modent_by_name (const void *one, const void *two, void *n);
41 static void *arc_mmap_header (int fd, size_t headersz);
42 static void *arc_mmap_file (int fd, size_t size);
43 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
44 const char **errmsg);
45 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
46
47 /* Write out a CTF archive to the start of the file referenced by the passed-in
48 fd. The entries in CTF_DICTS are referenced by name: the names are passed in
49 the names array, which must have CTF_DICTS entries.
50
51 Returns 0 on success, or an errno, or an ECTF_* value. */
52 int
53 ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
54 const char **names, size_t threshold)
55 {
56 const char *errmsg;
57 struct ctf_archive *archdr;
58 size_t i;
59 char dummy = 0;
60 size_t headersz;
61 ssize_t namesz;
62 size_t ctf_startoffs; /* Start of the section we are working over. */
63 char *nametbl = NULL; /* The name table. */
64 char *np;
65 off_t nameoffs;
66 struct ctf_archive_modent *modent;
67
68 ctf_dprintf ("Writing CTF archive with %lu files\n",
69 (unsigned long) ctf_dict_cnt);
70
71 /* Figure out the size of the mmap()ed header, including the
72 ctf_archive_modent array. We assume that all of this needs no
73 padding: a likely assumption, given that it's all made up of
74 uint64_t's. */
75 headersz = sizeof (struct ctf_archive)
76 + (ctf_dict_cnt * sizeof (uint64_t) * 2);
77 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
78
79 /* From now on we work in two pieces: an mmap()ed region from zero up to the
80 headersz, and a region updated via write() starting after that, containing
81 all the tables. Platforms that do not support mmap() just use write(). */
82 ctf_startoffs = headersz;
83 if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
84 {
85 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
86 goto err;
87 }
88
89 if (write (fd, &dummy, 1) < 0)
90 {
91 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
92 goto err;
93 }
94
95 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
96 {
97 errmsg = N_("ctf_arc_write(): cannot mmap");
98 goto err;
99 }
100
101 /* Fill in everything we can, which is everything other than the name
102 table offset. */
103 archdr->ctfa_magic = htole64 (CTFA_MAGIC);
104 archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
105 archdr->ctfa_ctfs = htole64 (ctf_startoffs);
106
107 /* We could validate that all CTF files have the same data model, but
108 since any reasonable construction process will be building things of
109 only one bitness anyway, this is pretty pointless, so just use the
110 model of the first CTF file for all of them. (It *is* valid to
111 create an empty archive: the value of ctfa_model is irrelevant in
112 this case, but we must be sure not to dereference uninitialized
113 memory.) */
114
115 if (ctf_dict_cnt > 0)
116 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
117
118 /* Now write out the CTFs: ctf_archive_modent array via the mapping,
119 ctfs via write(). The names themselves have not been written yet: we
120 track them in a local strtab until the time is right, and sort the
121 modents array after construction.
122
123 The name table is not sorted. */
124
125 for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
126 namesz += strlen (names[i]) + 1;
127
128 nametbl = malloc (namesz);
129 if (nametbl == NULL)
130 {
131 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
132 goto err_unmap;
133 }
134
135 for (i = 0, namesz = 0,
136 modent = (ctf_archive_modent_t *) ((char *) archdr
137 + sizeof (struct ctf_archive));
138 i < le64toh (archdr->ctfa_ndicts); i++)
139 {
140 off_t off;
141
142 strcpy (&nametbl[namesz], names[i]);
143
144 off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
145 if ((off < 0) && (off > -ECTF_BASE))
146 {
147 errmsg = N_("ctf_arc_write(): cannot determine file "
148 "position while writing to archive");
149 goto err_free;
150 }
151 if (off < 0)
152 {
153 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
154 errno = off * -1;
155 goto err_free;
156 }
157
158 modent->name_offset = htole64 (namesz);
159 modent->ctf_offset = htole64 (off - ctf_startoffs);
160 namesz += strlen (names[i]) + 1;
161 modent++;
162 }
163
164 ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
165 + sizeof (struct ctf_archive)),
166 le64toh (archdr->ctfa_ndicts),
167 sizeof (struct ctf_archive_modent), sort_modent_by_name,
168 nametbl);
169
170 /* Now the name table. */
171
172 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
173 {
174 errmsg = N_("ctf_arc_write(): cannot get current file position "
175 "in archive");
176 goto err_free;
177 }
178 archdr->ctfa_names = htole64 (nameoffs);
179 np = nametbl;
180 while (namesz > 0)
181 {
182 ssize_t len;
183 if ((len = write (fd, np, namesz)) < 0)
184 {
185 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
186 goto err_free;
187 }
188 namesz -= len;
189 np += len;
190 }
191 free (nametbl);
192
193 if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
194 goto err_unmap;
195 if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
196 goto err;
197 return 0;
198
199 err_free:
200 free (nametbl);
201 err_unmap:
202 arc_mmap_unmap (archdr, headersz, NULL);
203 err:
204 /* We report errors into the first file in the archive, if any: if this is a
205 zero-file archive, put it in the open-errors stream for lack of anywhere
206 else for it to go. */
207 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
208 gettext (errmsg));
209 return errno;
210 }
211
212 /* Write out a CTF archive. The entries in CTF_DICTS are referenced by name:
213 the names are passed in the names array, which must have CTF_DICTS entries.
214
215 If the filename is NULL, create a temporary file and return a pointer to it.
216
217 Returns 0 on success, or an errno, or an ECTF_* value. */
218 int
219 ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
220 const char **names, size_t threshold)
221 {
222 int err;
223 int fd;
224
225 if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
226 {
227 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
228 _("ctf_arc_write(): cannot create %s"), file);
229 return errno;
230 }
231
232 err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
233 if (err)
234 goto err_close;
235
236 if ((err = close (fd)) < 0)
237 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
238 _("ctf_arc_write(): cannot close after writing to archive"));
239 goto err;
240
241 err_close:
242 (void) close (fd);
243 err:
244 if (err < 0)
245 unlink (file);
246
247 return err;
248 }
249
250 /* Write one CTF file out. Return the file position of the written file (or
251 rather, of the file-size uint64_t that precedes it): negative return is a
252 negative errno or ctf_errno value. On error, the file position may no longer
253 be at the end of the file. */
254 static off_t
255 arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold)
256 {
257 off_t off, end_off;
258 uint64_t ctfsz = 0;
259 char *ctfszp;
260 size_t ctfsz_len;
261 int (*writefn) (ctf_dict_t * fp, int fd);
262
263 if (ctf_serialize (f) < 0)
264 return f->ctf_errno * -1;
265
266 if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
267 return errno * -1;
268
269 if (f->ctf_size > threshold)
270 writefn = ctf_compress_write;
271 else
272 writefn = ctf_write;
273
274 /* This zero-write turns into the size in a moment. */
275 ctfsz_len = sizeof (ctfsz);
276 ctfszp = (char *) &ctfsz;
277 while (ctfsz_len > 0)
278 {
279 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
280 if (writelen < 0)
281 return errno * -1;
282 ctfsz_len -= writelen;
283 ctfszp += writelen;
284 }
285
286 if (writefn (f, fd) != 0)
287 return f->ctf_errno * -1;
288
289 if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
290 return errno * -1;
291 ctfsz = htole64 (end_off - off);
292
293 if ((lseek (fd, off, SEEK_SET)) < 0)
294 return errno * -1;
295
296 /* ... here. */
297 ctfsz_len = sizeof (ctfsz);
298 ctfszp = (char *) &ctfsz;
299 while (ctfsz_len > 0)
300 {
301 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
302 if (writelen < 0)
303 return errno * -1;
304 ctfsz_len -= writelen;
305 ctfszp += writelen;
306 }
307
308 end_off = LCTF_ALIGN_OFFS (end_off, 8);
309 if ((lseek (fd, end_off, SEEK_SET)) < 0)
310 return errno * -1;
311
312 return off;
313 }
314
315 /* qsort() function to sort the array of struct ctf_archive_modents into
316 ascending name order. */
317 static int
318 sort_modent_by_name (const void *one, const void *two, void *n)
319 {
320 const struct ctf_archive_modent *a = one;
321 const struct ctf_archive_modent *b = two;
322 char *nametbl = n;
323
324 return strcmp (&nametbl[le64toh (a->name_offset)],
325 &nametbl[le64toh (b->name_offset)]);
326 }
327
328 /* bsearch_r() function to search for a given name in the sorted array of struct
329 ctf_archive_modents. */
330 static int
331 search_modent_by_name (const void *key, const void *ent, void *arg)
332 {
333 const char *k = key;
334 const struct ctf_archive_modent *v = ent;
335 const char *search_nametbl = arg;
336
337 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
338 }
339
340 /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
341 ctf_dict. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
342 STRSECT, as needed, on close. Possibly do not unmap on close. */
343
344 struct ctf_archive_internal *
345 ctf_new_archive_internal (int is_archive, int unmap_on_close,
346 struct ctf_archive *arc,
347 ctf_dict_t *fp, const ctf_sect_t *symsect,
348 const ctf_sect_t *strsect,
349 int *errp)
350 {
351 struct ctf_archive_internal *arci;
352
353 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
354 {
355 if (is_archive)
356 {
357 if (unmap_on_close)
358 ctf_arc_close_internal (arc);
359 }
360 else
361 ctf_dict_close (fp);
362 return (ctf_set_open_errno (errp, errno));
363 }
364 arci->ctfi_is_archive = is_archive;
365 if (is_archive)
366 arci->ctfi_archive = arc;
367 else
368 arci->ctfi_dict = fp;
369 if (symsect)
370 memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
371 if (strsect)
372 memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
373 arci->ctfi_free_symsect = 0;
374 arci->ctfi_free_strsect = 0;
375 arci->ctfi_unmap_on_close = unmap_on_close;
376
377 return arci;
378 }
379
380 /* Get the CTF preamble from data in a buffer, which may be either an archive or
381 a CTF dict. If multiple dicts are present in an archive, the preamble comes
382 from an arbitrary dict. The preamble is a pointer into the ctfsect passed
383 in. */
384
385 const ctf_preamble_t *
386 ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
387 {
388 if (ctfsect->cts_size > sizeof (uint64_t) &&
389 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
390 {
391 struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
392 return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
393 + sizeof (uint64_t));
394 }
395 else
396 return (const ctf_preamble_t *) ctfsect->cts_data;
397 }
398
399 /* Open a CTF archive or dictionary from data in a buffer (which the caller must
400 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
401 error in *err (if not NULL). */
402 ctf_archive_t *
403 ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
404 const ctf_sect_t *strsect, int *errp)
405 {
406 struct ctf_archive *arc = NULL;
407 int is_archive;
408 ctf_dict_t *fp = NULL;
409
410 if (ctfsect->cts_size > sizeof (uint64_t) &&
411 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
412 {
413 /* The archive is mmappable, so this operation is trivial.
414
415 This buffer is nonmodifiable, so the trick involving mmapping only part
416 of it and storing the length in the magic number is not applicable: so
417 record this fact in the archive-wrapper header. (We cannot record it
418 in the archive, because the archive may very well be a read-only
419 mapping.) */
420
421 is_archive = 1;
422 arc = (struct ctf_archive *) ctfsect->cts_data;
423 }
424 else
425 {
426 is_archive = 0;
427 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
428 {
429 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
430 return NULL;
431 }
432 }
433 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
434 errp);
435 }
436
437 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
438 not NULL). */
439 struct ctf_archive *
440 ctf_arc_open_internal (const char *filename, int *errp)
441 {
442 const char *errmsg;
443 int fd;
444 struct stat s;
445 struct ctf_archive *arc; /* (Actually the whole file.) */
446
447 libctf_init_debug();
448 if ((fd = open (filename, O_RDONLY)) < 0)
449 {
450 errmsg = N_("ctf_arc_open(): cannot open %s");
451 goto err;
452 }
453 if (fstat (fd, &s) < 0)
454 {
455 errmsg = N_("ctf_arc_open(): cannot stat %s");
456 goto err_close;
457 }
458
459 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
460 {
461 errmsg = N_("ctf_arc_open(): cannot read in %s");
462 goto err_close;
463 }
464
465 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
466 {
467 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
468 errno = ECTF_FMT;
469 goto err_unmap;
470 }
471
472 /* This horrible hack lets us know how much to unmap when the file is
473 closed. (We no longer need the magic number, and the mapping
474 is private.) */
475 arc->ctfa_magic = s.st_size;
476 close (fd);
477 return arc;
478
479 err_unmap:
480 arc_mmap_unmap (arc, s.st_size, NULL);
481 err_close:
482 close (fd);
483 err:
484 if (errp)
485 *errp = errno;
486 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
487 return NULL;
488 }
489
490 /* Close an archive. */
491 void
492 ctf_arc_close_internal (struct ctf_archive *arc)
493 {
494 if (arc == NULL)
495 return;
496
497 /* See the comment in ctf_arc_open(). */
498 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
499 }
500
501 /* Public entry point: close an archive, or CTF file. */
502 void
503 ctf_arc_close (ctf_archive_t *arc)
504 {
505 if (arc == NULL)
506 return;
507
508 if (arc->ctfi_is_archive)
509 {
510 if (arc->ctfi_unmap_on_close)
511 ctf_arc_close_internal (arc->ctfi_archive);
512 }
513 else
514 ctf_dict_close (arc->ctfi_dict);
515 if (arc->ctfi_free_symsect)
516 free ((void *) arc->ctfi_symsect.cts_data);
517 if (arc->ctfi_free_strsect)
518 free ((void *) arc->ctfi_strsect.cts_data);
519 free (arc->ctfi_data);
520 if (arc->ctfi_bfd_close)
521 arc->ctfi_bfd_close (arc);
522 free (arc);
523 }
524
525 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
526 non-NULL. A name of NULL means to open the default file. */
527 static ctf_dict_t *
528 ctf_dict_open_internal (const struct ctf_archive *arc,
529 const ctf_sect_t *symsect,
530 const ctf_sect_t *strsect,
531 const char *name, int *errp)
532 {
533 struct ctf_archive_modent *modent;
534 const char *search_nametbl;
535
536 if (name == NULL)
537 name = _CTF_SECTION; /* The default name. */
538
539 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
540
541 modent = (ctf_archive_modent_t *) ((char *) arc
542 + sizeof (struct ctf_archive));
543
544 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
545 modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
546 sizeof (struct ctf_archive_modent),
547 search_modent_by_name, (void *) search_nametbl);
548
549 /* This is actually a common case and normal operation: no error
550 debug output. */
551 if (modent == NULL)
552 {
553 if (errp)
554 *errp = ECTF_ARNNAME;
555 return NULL;
556 }
557
558 return ctf_dict_open_by_offset (arc, symsect, strsect,
559 le64toh (modent->ctf_offset), errp);
560 }
561
562 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
563 non-NULL. A name of NULL means to open the default file.
564
565 Use the specified string and symbol table sections.
566
567 Public entry point. */
568 ctf_dict_t *
569 ctf_dict_open_sections (const ctf_archive_t *arc,
570 const ctf_sect_t *symsect,
571 const ctf_sect_t *strsect,
572 const char *name,
573 int *errp)
574 {
575 if (arc->ctfi_is_archive)
576 {
577 ctf_dict_t *ret;
578 ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
579 name, errp);
580 if (ret)
581 ret->ctf_archive = (ctf_archive_t *) arc;
582 return ret;
583 }
584
585 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
586 {
587 if (errp)
588 *errp = ECTF_ARNNAME;
589 return NULL;
590 }
591 arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
592
593 /* Bump the refcount so that the user can ctf_dict_close() it. */
594 arc->ctfi_dict->ctf_refcnt++;
595 return arc->ctfi_dict;
596 }
597
598 /* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
599 non-NULL. A name of NULL means to open the default file.
600
601 Public entry point. */
602 ctf_dict_t *
603 ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
604 {
605 const ctf_sect_t *symsect = &arc->ctfi_symsect;
606 const ctf_sect_t *strsect = &arc->ctfi_strsect;
607
608 if (symsect->cts_name == NULL)
609 symsect = NULL;
610 if (strsect->cts_name == NULL)
611 strsect = NULL;
612
613 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
614 }
615
616 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
617 none, setting 'err' if non-NULL. */
618 static ctf_dict_t *
619 ctf_dict_open_by_offset (const struct ctf_archive *arc,
620 const ctf_sect_t *symsect,
621 const ctf_sect_t *strsect, size_t offset,
622 int *errp)
623 {
624 ctf_sect_t ctfsect;
625 ctf_dict_t *fp;
626
627 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
628
629 memset (&ctfsect, 0, sizeof (ctf_sect_t));
630
631 offset += le64toh (arc->ctfa_ctfs);
632
633 ctfsect.cts_name = _CTF_SECTION;
634 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
635 ctfsect.cts_entsize = 1;
636 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
637 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
638 if (fp)
639 ctf_setmodel (fp, le64toh (arc->ctfa_model));
640 return fp;
641 }
642
643 /* Backward compatibility. */
644 ctf_dict_t *
645 ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
646 int *errp)
647 {
648 return ctf_dict_open (arc, name, errp);
649 }
650
651 ctf_dict_t *
652 ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
653 const ctf_sect_t *symsect,
654 const ctf_sect_t *strsect,
655 const char *name,
656 int *errp)
657 {
658 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
659 }
660
661 /* Return the number of members in an archive. */
662 size_t
663 ctf_archive_count (const ctf_archive_t *wrapper)
664 {
665 if (!wrapper->ctfi_is_archive)
666 return 1;
667
668 return wrapper->ctfi_archive->ctfa_ndicts;
669 }
670
671 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
672 CTF files in turn to the specified callback function. */
673 static int
674 ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
675 ctf_archive_raw_member_f *func, void *data)
676 {
677 int rc;
678 size_t i;
679 struct ctf_archive_modent *modent;
680 const char *nametbl;
681
682 modent = (ctf_archive_modent_t *) ((char *) arc
683 + sizeof (struct ctf_archive));
684 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
685
686 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
687 {
688 const char *name;
689 char *fp;
690
691 name = &nametbl[le64toh (modent[i].name_offset)];
692 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
693 + le64toh (modent[i].ctf_offset));
694
695 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
696 le64toh (*((uint64_t *) fp)), data)) != 0)
697 return rc;
698 }
699 return 0;
700 }
701
702 /* Raw iteration over all CTF files in an archive: public entry point.
703
704 Returns -EINVAL if not supported for this sort of archive. */
705 int
706 ctf_archive_raw_iter (const ctf_archive_t *arc,
707 ctf_archive_raw_member_f * func, void *data)
708 {
709 if (arc->ctfi_is_archive)
710 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
711
712 return -EINVAL; /* Not supported. */
713 }
714
715 /* Iterate over all CTF files in an archive. We pass all CTF files in turn to
716 the specified callback function. */
717 static int
718 ctf_archive_iter_internal (const ctf_archive_t *wrapper,
719 const struct ctf_archive *arc,
720 const ctf_sect_t *symsect,
721 const ctf_sect_t *strsect,
722 ctf_archive_member_f *func, void *data)
723 {
724 int rc;
725 size_t i;
726 ctf_dict_t *f;
727 struct ctf_archive_modent *modent;
728 const char *nametbl;
729
730 modent = (ctf_archive_modent_t *) ((char *) arc
731 + sizeof (struct ctf_archive));
732 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
733
734 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
735 {
736 const char *name;
737
738 name = &nametbl[le64toh (modent[i].name_offset)];
739 if ((f = ctf_dict_open_internal (arc, symsect, strsect,
740 name, &rc)) == NULL)
741 return rc;
742
743 f->ctf_archive = (ctf_archive_t *) wrapper;
744 if ((rc = func (f, name, data)) != 0)
745 {
746 ctf_dict_close (f);
747 return rc;
748 }
749
750 ctf_dict_close (f);
751 }
752 return 0;
753 }
754
755 /* Iterate over all CTF files in an archive: public entry point. We pass all
756 CTF files in turn to the specified callback function. */
757 int
758 ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
759 void *data)
760 {
761 const ctf_sect_t *symsect = &arc->ctfi_symsect;
762 const ctf_sect_t *strsect = &arc->ctfi_strsect;
763
764 if (symsect->cts_name == NULL)
765 symsect = NULL;
766 if (strsect->cts_name == NULL)
767 strsect = NULL;
768
769 if (arc->ctfi_is_archive)
770 return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect,
771 func, data);
772
773 return func (arc->ctfi_dict, _CTF_SECTION, data);
774 }
775
776 /* Iterate over all CTF files in an archive, returning each dict in turn as a
777 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
778 responsibility to close it. Parent dicts may be skipped. Regardless of
779 whether they are skipped or not, the caller must ctf_import the parent if
780 need be.
781
782 We identify parents by name rather than by flag value: for now, with the
783 linker only emitting parents named _CTF_SECTION, this works well enough. */
784
785 ctf_dict_t *
786 ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
787 int skip_parent, int *errp)
788 {
789 ctf_dict_t *f;
790 ctf_next_t *i = *it;
791 struct ctf_archive *arc;
792 struct ctf_archive_modent *modent;
793 const char *nametbl;
794 const char *name_;
795
796 if (!i)
797 {
798 if ((i = ctf_next_create()) == NULL)
799 {
800 if (errp)
801 *errp = ENOMEM;
802 return NULL;
803 }
804 i->cu.ctn_arc = wrapper;
805 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
806 *it = i;
807 }
808
809 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
810 {
811 if (errp)
812 *errp = ECTF_NEXT_WRONGFUN;
813 return NULL;
814 }
815
816 if (wrapper != i->cu.ctn_arc)
817 {
818 if (errp)
819 *errp = ECTF_NEXT_WRONGFP;
820 return NULL;
821 }
822
823 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
824 transparently wrapped in a single-member archive. These are parents: if
825 skip_parent is on, they are skipped and the iterator terminates
826 immediately. */
827
828 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
829 {
830 i->ctn_n++;
831 if (!skip_parent)
832 {
833 wrapper->ctfi_dict->ctf_refcnt++;
834 return wrapper->ctfi_dict;
835 }
836 }
837
838 arc = wrapper->ctfi_archive;
839
840 /* The loop keeps going when skip_parent is on as long as the member we find
841 is the parent (i.e. at most two iterations, but possibly an early return if
842 *all* we have is a parent). */
843
844 const ctf_sect_t *symsect;
845 const ctf_sect_t *strsect;
846
847 do
848 {
849 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
850 {
851 ctf_next_destroy (i);
852 *it = NULL;
853 if (errp)
854 *errp = ECTF_NEXT_END;
855 return NULL;
856 }
857
858 symsect = &wrapper->ctfi_symsect;
859 strsect = &wrapper->ctfi_strsect;
860
861 if (symsect->cts_name == NULL)
862 symsect = NULL;
863 if (strsect->cts_name == NULL)
864 strsect = NULL;
865
866 modent = (ctf_archive_modent_t *) ((char *) arc
867 + sizeof (struct ctf_archive));
868 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
869
870 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
871 i->ctn_n++;
872 } while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
873
874 if (name)
875 *name = name_;
876
877 f = ctf_dict_open_internal (arc, symsect, strsect, name_, errp);
878 f->ctf_archive = (ctf_archive_t *) wrapper;
879 return f;
880 }
881
882 #ifdef HAVE_MMAP
883 /* Map the header in. Only used on new, empty files. */
884 static void *arc_mmap_header (int fd, size_t headersz)
885 {
886 void *hdr;
887 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
888 0)) == MAP_FAILED)
889 return NULL;
890 return hdr;
891 }
892
893 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
894 need to modify the region, but don't need anyone else to see the
895 modifications.) */
896 static void *arc_mmap_file (int fd, size_t size)
897 {
898 void *arc;
899 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
900 fd, 0)) == MAP_FAILED)
901 return NULL;
902 return arc;
903 }
904
905 /* Persist the header to disk. */
906 static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
907 size_t headersz, const char **errmsg)
908 {
909 if (msync (header, headersz, MS_ASYNC) < 0)
910 {
911 if (errmsg)
912 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
913 "to %s: %s");
914 return -1;
915 }
916 return 0;
917 }
918
919 /* Unmap the region. */
920 static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
921 {
922 if (munmap (header, headersz) < 0)
923 {
924 if (errmsg)
925 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
926 "to %s: %s");
927 return -1;
928 }
929 return 0;
930 }
931 #else
932 /* Map the header in. Only used on new, empty files. */
933 static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
934 {
935 void *hdr;
936 if ((hdr = malloc (headersz)) == NULL)
937 return NULL;
938 return hdr;
939 }
940
941 /* Pull in the whole file, for reading only. We assume the current file
942 position is at the start of the file. */
943 static void *arc_mmap_file (int fd, size_t size)
944 {
945 char *data;
946
947 if ((data = malloc (size)) == NULL)
948 return NULL;
949
950 if (ctf_pread (fd, data, size, 0) < 0)
951 {
952 free (data);
953 return NULL;
954 }
955 return data;
956 }
957
958 /* Persist the header to disk. */
959 static int arc_mmap_writeout (int fd, void *header, size_t headersz,
960 const char **errmsg)
961 {
962 ssize_t len;
963 size_t acc = 0;
964 char *data = (char *) header;
965 ssize_t count = headersz;
966
967 if ((lseek (fd, 0, SEEK_SET)) < 0)
968 {
969 if (errmsg)
970 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
971 "%s: %s");
972 return -1;
973 }
974
975 while (headersz > 0)
976 {
977 if ((len = write (fd, data, count)) < 0)
978 {
979 if (errmsg)
980 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
981 return len;
982 }
983 if (len == EINTR)
984 continue;
985
986 acc += len;
987 if (len == 0) /* EOF. */
988 break;
989
990 count -= len;
991 data += len;
992 }
993 return 0;
994 }
995
996 /* Unmap the region. */
997 static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
998 const char **errmsg _libctf_unused_)
999 {
1000 free (header);
1001 return 0;
1002 }
1003 #endif