]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-archive.c
[Morello] Teach gdb about additional CHERI auxv entries
[thirdparty/binutils-gdb.git] / libctf / ctf-archive.c
CommitLineData
9402cc59 1/* CTF archive files.
b3adc24a 2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
9402cc59
NA
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>
a0486bac 24#include "ctf-endian.h"
9402cc59
NA
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
35static off_t arc_write_one_ctf (ctf_file_t * f, int fd, size_t threshold);
36static ctf_file_t *ctf_arc_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);
40static int sort_modent_by_name (const void *one, const void *two, void *n);
41static void *arc_mmap_header (int fd, size_t headersz);
42static void *arc_mmap_file (int fd, size_t size);
43static int arc_mmap_writeout (int fd, void *header, size_t headersz,
44 const char **errmsg);
45static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
46
5537f9b9
NA
47/* Write out a CTF archive to the start of the file referenced by the passed-in
48 fd. The entries in CTF_FILES are referenced by name: the names are passed in
49 the names array, which must have CTF_FILES entries.
9402cc59
NA
50
51 Returns 0 on success, or an errno, or an ECTF_* value. */
52int
5537f9b9
NA
53ctf_arc_write_fd (int fd, ctf_file_t **ctf_files, size_t ctf_file_cnt,
54 const char **names, size_t threshold)
9402cc59
NA
55{
56 const char *errmsg;
57 struct ctf_archive *archdr;
9402cc59
NA
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
5537f9b9 68 ctf_dprintf ("Writing CTF archive with %lu files\n",
62d8e3b7 69 (unsigned long) ctf_file_cnt);
9402cc59 70
9402cc59
NA
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_file_cnt * sizeof (uint64_t) * 2);
62d8e3b7 77 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
9402cc59
NA
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 {
926c9e76 85 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 86 goto err;
9402cc59
NA
87 }
88
89 if (write (fd, &dummy, 1) < 0)
90 {
926c9e76 91 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 92 goto err;
9402cc59
NA
93 }
94
95 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
96 {
926c9e76 97 errmsg = N_("ctf_arc_write(): cannot mmap");
5537f9b9 98 goto err;
9402cc59
NA
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_nfiles = htole64 (ctf_file_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_file_cnt > 0)
116 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_files[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_nfiles); i++)
126 namesz += strlen (names[i]) + 1;
127
128 nametbl = malloc (namesz);
129 if (nametbl == NULL)
130 {
926c9e76 131 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
9402cc59
NA
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_nfiles); i++)
139 {
140 off_t off;
141
142 strcpy (&nametbl[namesz], names[i]);
143
144 off = arc_write_one_ctf (ctf_files[i], fd, threshold);
9402cc59
NA
145 if ((off < 0) && (off > -ECTF_BASE))
146 {
926c9e76
NA
147 errmsg = N_("ctf_arc_write(): cannot determine file "
148 "position while writing to archive");
9402cc59
NA
149 goto err_free;
150 }
151 if (off < 0)
152 {
926c9e76 153 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
9402cc59
NA
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
6b22174f
NA
164 ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
165 + sizeof (struct ctf_archive)),
166 le64toh (archdr->ctfa_nfiles),
167 sizeof (struct ctf_archive_modent), sort_modent_by_name,
168 nametbl);
9402cc59
NA
169
170 /* Now the name table. */
171
172 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
173 {
926c9e76
NA
174 errmsg = N_("ctf_arc_write(): cannot get current file position "
175 "in archive");
9402cc59
NA
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 {
926c9e76 185 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
9402cc59
NA
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)
5537f9b9 196 goto err;
9402cc59
NA
197 return 0;
198
199err_free:
200 free (nametbl);
201err_unmap:
202 arc_mmap_unmap (archdr, headersz, NULL);
9402cc59 203err:
926c9e76
NA
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_file_cnt > 0 ? ctf_files[0] : NULL, 0, errno, "%s",
208 gettext (errmsg));
9402cc59
NA
209 return errno;
210}
211
5537f9b9
NA
212/* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
213 the names are passed in the names array, which must have CTF_FILES 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. */
218int
926c9e76 219ctf_arc_write (const char *file, ctf_file_t **ctf_files, size_t ctf_file_cnt,
5537f9b9
NA
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 {
926c9e76
NA
227 ctf_err_warn (ctf_file_cnt > 0 ? ctf_files[0] : NULL, 0, errno,
228 _("ctf_arc_write(): cannot create %s"), file);
5537f9b9
NA
229 return errno;
230 }
231
232 err = ctf_arc_write_fd (fd, ctf_files, ctf_file_cnt, names, threshold);
233 if (err)
df16e041 234 goto err_close;
5537f9b9
NA
235
236 if ((err = close (fd)) < 0)
926c9e76
NA
237 ctf_err_warn (ctf_file_cnt > 0 ? ctf_files[0] : NULL, 0, errno,
238 _("ctf_arc_write(): cannot close after writing to archive"));
df16e041 239 goto err;
5537f9b9
NA
240
241 err_close:
df16e041
NC
242 (void) close (fd);
243 err:
5537f9b9
NA
244 if (err < 0)
245 unlink (file);
246
247 return err;
248}
249
9402cc59
NA
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. */
254static off_t
255arc_write_one_ctf (ctf_file_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_file_t * fp, int fd);
262
676c3ecb
NA
263 if (ctf_serialize (f) < 0)
264 return f->ctf_errno * -1;
265
9402cc59
NA
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. */
317static int
318sort_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
2e428e74 328/* bsearch_r() function to search for a given name in the sorted array of struct
9402cc59
NA
329 ctf_archive_modents. */
330static int
2e428e74 331search_modent_by_name (const void *key, const void *ent, void *arg)
9402cc59
NA
332{
333 const char *k = key;
334 const struct ctf_archive_modent *v = ent;
2e428e74 335 const char *search_nametbl = arg;
9402cc59
NA
336
337 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
338}
339
2f6ecaed
NA
340/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
341 ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
601e455b 342 STRSECT, as needed, on close. Possibly do not unmap on close. */
2f6ecaed
NA
343
344struct ctf_archive_internal *
601e455b
NA
345ctf_new_archive_internal (int is_archive, int unmap_on_close,
346 struct ctf_archive *arc,
2f6ecaed
NA
347 ctf_file_t *fp, const ctf_sect_t *symsect,
348 const ctf_sect_t *strsect,
349 int *errp)
9402cc59 350{
2f6ecaed 351 struct ctf_archive_internal *arci;
9402cc59 352
2f6ecaed 353 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
9402cc59 354 {
2f6ecaed 355 if (is_archive)
601e455b
NA
356 {
357 if (unmap_on_close)
358 ctf_arc_close_internal (arc);
359 }
2f6ecaed
NA
360 else
361 ctf_file_close (fp);
362 return (ctf_set_open_errno (errp, errno));
9402cc59 363 }
2f6ecaed
NA
364 arci->ctfi_is_archive = is_archive;
365 if (is_archive)
366 arci->ctfi_archive = arc;
367 else
368 arci->ctfi_file = 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;
d50c0802 374 arci->ctfi_free_strsect = 0;
601e455b 375 arci->ctfi_unmap_on_close = unmap_on_close;
2f6ecaed
NA
376
377 return arci;
378}
379
380/* Open a CTF archive or dictionary from data in a buffer (which the caller must
381 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
382 error in *err (if not NULL). */
383ctf_archive_t *
384ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
385 const ctf_sect_t *strsect, int *errp)
386{
387 struct ctf_archive *arc = NULL;
388 int is_archive;
389 ctf_file_t *fp = NULL;
390
391 if (ctfsect->cts_size > sizeof (uint64_t) &&
4533ed56 392 (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
2f6ecaed 393 {
601e455b
NA
394 /* The archive is mmappable, so this operation is trivial.
395
396 This buffer is nonmodifiable, so the trick involving mmapping only part
397 of it and storing the length in the magic number is not applicable: so
398 record this fact in the archive-wrapper header. (We cannot record it
399 in the archive, because the archive may very well be a read-only
400 mapping.) */
2f6ecaed
NA
401
402 is_archive = 1;
403 arc = (struct ctf_archive *) ctfsect->cts_data;
404 }
405 else
406 {
407 is_archive = 0;
408 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
409 {
926c9e76 410 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
2f6ecaed
NA
411 return NULL;
412 }
413 }
601e455b 414 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
2f6ecaed 415 errp);
9402cc59
NA
416}
417
418/* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
419 not NULL). */
420struct ctf_archive *
421ctf_arc_open_internal (const char *filename, int *errp)
422{
423 const char *errmsg;
424 int fd;
425 struct stat s;
426 struct ctf_archive *arc; /* (Actually the whole file.) */
427
428 libctf_init_debug();
429 if ((fd = open (filename, O_RDONLY)) < 0)
430 {
926c9e76 431 errmsg = N_("ctf_arc_open(): cannot open %s");
9402cc59
NA
432 goto err;
433 }
434 if (fstat (fd, &s) < 0)
435 {
926c9e76 436 errmsg = N_("ctf_arc_open(): cannot stat %s");
9402cc59
NA
437 goto err_close;
438 }
439
440 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
441 {
926c9e76 442 errmsg = N_("ctf_arc_open(): cannot read in %s");
9402cc59
NA
443 goto err_close;
444 }
445
446 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
447 {
926c9e76 448 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
9402cc59
NA
449 errno = ECTF_FMT;
450 goto err_unmap;
451 }
452
453 /* This horrible hack lets us know how much to unmap when the file is
454 closed. (We no longer need the magic number, and the mapping
455 is private.) */
456 arc->ctfa_magic = s.st_size;
457 close (fd);
458 return arc;
459
460err_unmap:
461 arc_mmap_unmap (arc, s.st_size, NULL);
462err_close:
463 close (fd);
464err:
465 if (errp)
466 *errp = errno;
926c9e76 467 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
9402cc59
NA
468 return NULL;
469}
470
471/* Close an archive. */
472void
473ctf_arc_close_internal (struct ctf_archive *arc)
474{
475 if (arc == NULL)
476 return;
477
478 /* See the comment in ctf_arc_open(). */
479 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
480}
481
482/* Public entry point: close an archive, or CTF file. */
483void
484ctf_arc_close (ctf_archive_t *arc)
485{
486 if (arc == NULL)
487 return;
488
489 if (arc->ctfi_is_archive)
601e455b
NA
490 {
491 if (arc->ctfi_unmap_on_close)
492 ctf_arc_close_internal (arc->ctfi_archive);
493 }
9402cc59
NA
494 else
495 ctf_file_close (arc->ctfi_file);
2f6ecaed
NA
496 if (arc->ctfi_free_symsect)
497 free ((void *) arc->ctfi_symsect.cts_data);
d50c0802
NA
498 if (arc->ctfi_free_strsect)
499 free ((void *) arc->ctfi_strsect.cts_data);
9402cc59 500 free (arc->ctfi_data);
f046147d
NA
501 if (arc->ctfi_bfd_close)
502 arc->ctfi_bfd_close (arc);
9402cc59
NA
503 free (arc);
504}
505
506/* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
507 non-NULL. A name of NULL means to open the default file. */
508static ctf_file_t *
509ctf_arc_open_by_name_internal (const struct ctf_archive *arc,
510 const ctf_sect_t *symsect,
511 const ctf_sect_t *strsect,
512 const char *name, int *errp)
513{
514 struct ctf_archive_modent *modent;
2e428e74 515 const char *search_nametbl;
9402cc59
NA
516
517 if (name == NULL)
518 name = _CTF_SECTION; /* The default name. */
519
520 ctf_dprintf ("ctf_arc_open_by_name(%s): opening\n", name);
521
522 modent = (ctf_archive_modent_t *) ((char *) arc
523 + sizeof (struct ctf_archive));
524
2e428e74
NA
525 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
526 modent = bsearch_r (name, modent, le64toh (arc->ctfa_nfiles),
527 sizeof (struct ctf_archive_modent),
528 search_modent_by_name, (void *) search_nametbl);
9402cc59
NA
529
530 /* This is actually a common case and normal operation: no error
531 debug output. */
532 if (modent == NULL)
533 {
534 if (errp)
535 *errp = ECTF_ARNNAME;
536 return NULL;
537 }
538
539 return ctf_arc_open_by_offset (arc, symsect, strsect,
540 le64toh (modent->ctf_offset), errp);
541}
542
543/* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
544 non-NULL. A name of NULL means to open the default file.
545
546 Use the specified string and symbol table sections.
547
548 Public entry point. */
549ctf_file_t *
550ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
551 const ctf_sect_t *symsect,
552 const ctf_sect_t *strsect,
553 const char *name,
554 int *errp)
555{
556 if (arc->ctfi_is_archive)
557 {
558 ctf_file_t *ret;
559 ret = ctf_arc_open_by_name_internal (arc->ctfi_archive, symsect, strsect,
560 name, errp);
561 if (ret)
562 ret->ctf_archive = (ctf_archive_t *) arc;
563 return ret;
564 }
565
566 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
567 {
568 if (errp)
569 *errp = ECTF_ARNNAME;
570 return NULL;
571 }
572 arc->ctfi_file->ctf_archive = (ctf_archive_t *) arc;
573
574 /* Bump the refcount so that the user can ctf_file_close() it. */
575 arc->ctfi_file->ctf_refcnt++;
576 return arc->ctfi_file;
577}
578
579/* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
580 non-NULL. A name of NULL means to open the default file.
581
582 Public entry point. */
583ctf_file_t *
584ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name, int *errp)
585{
586 const ctf_sect_t *symsect = &arc->ctfi_symsect;
587 const ctf_sect_t *strsect = &arc->ctfi_strsect;
588
589 if (symsect->cts_name == NULL)
590 symsect = NULL;
591 if (strsect->cts_name == NULL)
592 strsect = NULL;
593
594 return ctf_arc_open_by_name_sections (arc, symsect, strsect, name, errp);
595}
596
597/* Return the ctf_file_t at the given ctfa_ctfs-relative offset, or NULL if
598 none, setting 'err' if non-NULL. */
599static ctf_file_t *
600ctf_arc_open_by_offset (const struct ctf_archive *arc,
601 const ctf_sect_t *symsect,
602 const ctf_sect_t *strsect, size_t offset,
603 int *errp)
604{
605 ctf_sect_t ctfsect;
606 ctf_file_t *fp;
607
62d8e3b7 608 ctf_dprintf ("ctf_arc_open_by_offset(%lu): opening\n", (unsigned long) offset);
9402cc59 609
a0486bac 610 memset (&ctfsect, 0, sizeof (ctf_sect_t));
9402cc59
NA
611
612 offset += le64toh (arc->ctfa_ctfs);
613
614 ctfsect.cts_name = _CTF_SECTION;
9402cc59
NA
615 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
616 ctfsect.cts_entsize = 1;
9402cc59
NA
617 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
618 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
619 if (fp)
620 ctf_setmodel (fp, le64toh (arc->ctfa_model));
621 return fp;
622}
623
9c23dfa5
NA
624/* Return the number of members in an archive. */
625size_t
626ctf_archive_count (const ctf_archive_t *wrapper)
627{
628 if (!wrapper->ctfi_is_archive)
629 return 1;
630
631 return wrapper->ctfi_archive->ctfa_nfiles;
632}
633
9402cc59
NA
634/* Raw iteration over all CTF files in an archive. We pass the raw data for all
635 CTF files in turn to the specified callback function. */
636static int
637ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
638 ctf_archive_raw_member_f *func, void *data)
639{
640 int rc;
641 size_t i;
642 struct ctf_archive_modent *modent;
643 const char *nametbl;
644
645 modent = (ctf_archive_modent_t *) ((char *) arc
646 + sizeof (struct ctf_archive));
647 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
648
649 for (i = 0; i < le64toh (arc->ctfa_nfiles); i++)
650 {
651 const char *name;
652 char *fp;
653
654 name = &nametbl[le64toh (modent[i].name_offset)];
655 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
656 + le64toh (modent[i].ctf_offset));
657
658 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
659 le64toh (*((uint64_t *) fp)), data)) != 0)
660 return rc;
661 }
662 return 0;
663}
664
665/* Raw iteration over all CTF files in an archive: public entry point.
666
667 Returns -EINVAL if not supported for this sort of archive. */
668int
669ctf_archive_raw_iter (const ctf_archive_t *arc,
670 ctf_archive_raw_member_f * func, void *data)
671{
672 if (arc->ctfi_is_archive)
673 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
674
675 return -EINVAL; /* Not supported. */
676}
677
678/* Iterate over all CTF files in an archive. We pass all CTF files in turn to
679 the specified callback function. */
680static int
681ctf_archive_iter_internal (const ctf_archive_t *wrapper,
682 const struct ctf_archive *arc,
683 const ctf_sect_t *symsect,
684 const ctf_sect_t *strsect,
685 ctf_archive_member_f *func, void *data)
686{
687 int rc;
688 size_t i;
689 ctf_file_t *f;
690 struct ctf_archive_modent *modent;
691 const char *nametbl;
692
693 modent = (ctf_archive_modent_t *) ((char *) arc
694 + sizeof (struct ctf_archive));
695 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
696
697 for (i = 0; i < le64toh (arc->ctfa_nfiles); i++)
698 {
699 const char *name;
700
701 name = &nametbl[le64toh (modent[i].name_offset)];
702 if ((f = ctf_arc_open_by_name_internal (arc, symsect, strsect,
703 name, &rc)) == NULL)
704 return rc;
705
706 f->ctf_archive = (ctf_archive_t *) wrapper;
707 if ((rc = func (f, name, data)) != 0)
708 {
709 ctf_file_close (f);
710 return rc;
711 }
712
713 ctf_file_close (f);
714 }
715 return 0;
716}
717
718/* Iterate over all CTF files in an archive: public entry point. We pass all
719 CTF files in turn to the specified callback function. */
720int
721ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
722 void *data)
723{
724 const ctf_sect_t *symsect = &arc->ctfi_symsect;
725 const ctf_sect_t *strsect = &arc->ctfi_strsect;
726
727 if (symsect->cts_name == NULL)
728 symsect = NULL;
729 if (strsect->cts_name == NULL)
730 strsect = NULL;
731
732 if (arc->ctfi_is_archive)
733 return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect,
734 func, data);
735
736 return func (arc->ctfi_file, _CTF_SECTION, data);
737}
738
688d28f6
NA
739/* Iterate over all CTF files in an archive, returning each dict in turn as a
740 ctf_file_t, and NULL on error or end of iteration. It is the caller's
741 responsibility to close it. Parent dicts may be skipped. Regardless of
742 whether they are skipped or not, the caller must ctf_import the parent if
743 need be.
744
745 We identify parents by name rather than by flag value: for now, with the
746 linker only emitting parents named _CTF_SECTION, this works well enough. */
747
748ctf_file_t *
749ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
750 int skip_parent, int *errp)
751{
752 ctf_file_t *f;
753 ctf_next_t *i = *it;
754 struct ctf_archive *arc;
755 struct ctf_archive_modent *modent;
756 const char *nametbl;
757 const char *name_;
758
759 if (!i)
760 {
761 if ((i = ctf_next_create()) == NULL)
762 {
763 if (errp)
764 *errp = ENOMEM;
765 return NULL;
766 }
767 i->cu.ctn_arc = wrapper;
768 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
769 *it = i;
770 }
771
772 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
773 {
774 if (errp)
775 *errp = ECTF_NEXT_WRONGFUN;
776 return NULL;
777 }
778
779 if (wrapper != i->cu.ctn_arc)
780 {
781 if (errp)
782 *errp = ECTF_NEXT_WRONGFP;
783 return NULL;
784 }
785
786 /* Iteration is made a bit more complex by the need to handle ctf_file_t's
787 transparently wrapped in a single-member archive. These are parents: if
788 skip_parent is on, they are skipped and the iterator terminates
789 immediately. */
790
791 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
792 {
793 i->ctn_n++;
794 if (!skip_parent)
795 {
796 wrapper->ctfi_file->ctf_refcnt++;
797 return wrapper->ctfi_file;
798 }
799 }
800
801 arc = wrapper->ctfi_archive;
802
803 /* The loop keeps going when skip_parent is on as long as the member we find
804 is the parent (i.e. at most two iterations, but possibly an early return if
805 *all* we have is a parent). */
806
807 const ctf_sect_t *symsect;
808 const ctf_sect_t *strsect;
809
810 do
811 {
812 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_nfiles)))
813 {
814 ctf_next_destroy (i);
815 *it = NULL;
816 if (errp)
817 *errp = ECTF_NEXT_END;
818 return NULL;
819 }
820
821 symsect = &wrapper->ctfi_symsect;
822 strsect = &wrapper->ctfi_strsect;
823
824 if (symsect->cts_name == NULL)
825 symsect = NULL;
826 if (strsect->cts_name == NULL)
827 strsect = NULL;
828
829 modent = (ctf_archive_modent_t *) ((char *) arc
830 + sizeof (struct ctf_archive));
831 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
832
833 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
834 i->ctn_n++;
835 } while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
836
837 if (name)
838 *name = name_;
839
840 f = ctf_arc_open_by_name_internal (arc, symsect, strsect,
841 name_, errp);
842 f->ctf_archive = (ctf_archive_t *) wrapper;
843 return f;
844}
845
9402cc59
NA
846#ifdef HAVE_MMAP
847/* Map the header in. Only used on new, empty files. */
848static void *arc_mmap_header (int fd, size_t headersz)
849{
850 void *hdr;
851 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
852 0)) == MAP_FAILED)
853 return NULL;
854 return hdr;
855}
856
857/* mmap() the whole file, for reading only. (Map it writably, but privately: we
858 need to modify the region, but don't need anyone else to see the
859 modifications.) */
860static void *arc_mmap_file (int fd, size_t size)
861{
862 void *arc;
863 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
864 fd, 0)) == MAP_FAILED)
865 return NULL;
866 return arc;
867}
868
869/* Persist the header to disk. */
870static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
871 size_t headersz, const char **errmsg)
872{
873 if (msync (header, headersz, MS_ASYNC) < 0)
874 {
875 if (errmsg)
926c9e76
NA
876 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
877 "to %s: %s");
9402cc59
NA
878 return -1;
879 }
880 return 0;
881}
882
883/* Unmap the region. */
884static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
885{
886 if (munmap (header, headersz) < 0)
887 {
888 if (errmsg)
926c9e76
NA
889 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
890 "to %s: %s");
9402cc59
NA
891 return -1;
892 }
893 return 0;
894}
895#else
896/* Map the header in. Only used on new, empty files. */
f5e73be1 897static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
9402cc59
NA
898{
899 void *hdr;
900 if ((hdr = malloc (headersz)) == NULL)
901 return NULL;
902 return hdr;
903}
904
905/* Pull in the whole file, for reading only. We assume the current file
906 position is at the start of the file. */
907static void *arc_mmap_file (int fd, size_t size)
908{
909 char *data;
910
911 if ((data = malloc (size)) == NULL)
912 return NULL;
913
914 if (ctf_pread (fd, data, size, 0) < 0)
915 {
916 free (data);
917 return NULL;
918 }
919 return data;
920}
921
922/* Persist the header to disk. */
923static int arc_mmap_writeout (int fd, void *header, size_t headersz,
924 const char **errmsg)
925{
926 ssize_t len;
927 size_t acc = 0;
928 char *data = (char *) header;
929 ssize_t count = headersz;
930
931 if ((lseek (fd, 0, SEEK_SET)) < 0)
932 {
933 if (errmsg)
926c9e76
NA
934 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
935 "%s: %s");
9402cc59
NA
936 return -1;
937 }
938
939 while (headersz > 0)
940 {
941 if ((len = write (fd, data, count)) < 0)
942 {
943 if (errmsg)
926c9e76 944 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
9402cc59
NA
945 return len;
946 }
947 if (len == EINTR)
948 continue;
949
950 acc += len;
951 if (len == 0) /* EOF. */
952 break;
953
954 count -= len;
955 data += len;
956 }
957 return 0;
958}
959
960/* Unmap the region. */
961static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
962 const char **errmsg _libctf_unused_)
963{
964 free (header);
965 return 0;
966}
967#endif