]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-archive.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / libctf / ctf-archive.c
CommitLineData
9402cc59 1/* CTF archive files.
e8e7cf2a 2 Copyright (C) 2019-2025 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
139633c3 35static off_t arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold);
ae41200b
NA
36static 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,
53651de8
NA
39 size_t offset, int little_endian,
40 int *errp);
9402cc59
NA
41static int sort_modent_by_name (const void *one, const void *two, void *n);
42static void *arc_mmap_header (int fd, size_t headersz);
43static void *arc_mmap_file (int fd, size_t size);
44static int arc_mmap_writeout (int fd, void *header, size_t headersz,
45 const char **errmsg);
46static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
61914bb6
NA
47static int ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp,
48 int *errp);
2c78e925 49
f4f60336
NA
50/* Flag to indicate "symbol not present" in ctf_archive_internal.ctfi_symdicts
51 and ctfi_symnamedicts. Never initialized. */
2c78e925 52static ctf_dict_t enosym;
9402cc59 53
5537f9b9 54/* Write out a CTF archive to the start of the file referenced by the passed-in
139633c3
NA
55 fd. The entries in CTF_DICTS are referenced by name: the names are passed in
56 the names array, which must have CTF_DICTS entries.
9402cc59
NA
57
58 Returns 0 on success, or an errno, or an ECTF_* value. */
59int
139633c3 60ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
5537f9b9 61 const char **names, size_t threshold)
9402cc59
NA
62{
63 const char *errmsg;
64 struct ctf_archive *archdr;
9402cc59
NA
65 size_t i;
66 char dummy = 0;
67 size_t headersz;
68 ssize_t namesz;
69 size_t ctf_startoffs; /* Start of the section we are working over. */
70 char *nametbl = NULL; /* The name table. */
71 char *np;
72 off_t nameoffs;
73 struct ctf_archive_modent *modent;
74
5537f9b9 75 ctf_dprintf ("Writing CTF archive with %lu files\n",
139633c3 76 (unsigned long) ctf_dict_cnt);
9402cc59 77
9402cc59
NA
78 /* Figure out the size of the mmap()ed header, including the
79 ctf_archive_modent array. We assume that all of this needs no
80 padding: a likely assumption, given that it's all made up of
81 uint64_t's. */
82 headersz = sizeof (struct ctf_archive)
139633c3 83 + (ctf_dict_cnt * sizeof (uint64_t) * 2);
62d8e3b7 84 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);
9402cc59
NA
85
86 /* From now on we work in two pieces: an mmap()ed region from zero up to the
87 headersz, and a region updated via write() starting after that, containing
88 all the tables. Platforms that do not support mmap() just use write(). */
89 ctf_startoffs = headersz;
90 if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
91 {
926c9e76 92 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 93 goto err;
9402cc59
NA
94 }
95
96 if (write (fd, &dummy, 1) < 0)
97 {
926c9e76 98 errmsg = N_("ctf_arc_write(): cannot extend file while writing");
5537f9b9 99 goto err;
9402cc59
NA
100 }
101
102 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
103 {
926c9e76 104 errmsg = N_("ctf_arc_write(): cannot mmap");
5537f9b9 105 goto err;
9402cc59
NA
106 }
107
108 /* Fill in everything we can, which is everything other than the name
109 table offset. */
110 archdr->ctfa_magic = htole64 (CTFA_MAGIC);
139633c3 111 archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
9402cc59
NA
112 archdr->ctfa_ctfs = htole64 (ctf_startoffs);
113
114 /* We could validate that all CTF files have the same data model, but
115 since any reasonable construction process will be building things of
116 only one bitness anyway, this is pretty pointless, so just use the
117 model of the first CTF file for all of them. (It *is* valid to
118 create an empty archive: the value of ctfa_model is irrelevant in
119 this case, but we must be sure not to dereference uninitialized
120 memory.) */
121
139633c3
NA
122 if (ctf_dict_cnt > 0)
123 archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));
9402cc59
NA
124
125 /* Now write out the CTFs: ctf_archive_modent array via the mapping,
126 ctfs via write(). The names themselves have not been written yet: we
127 track them in a local strtab until the time is right, and sort the
128 modents array after construction.
129
130 The name table is not sorted. */
131
139633c3 132 for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
9402cc59
NA
133 namesz += strlen (names[i]) + 1;
134
135 nametbl = malloc (namesz);
136 if (nametbl == NULL)
137 {
926c9e76 138 errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
9402cc59
NA
139 goto err_unmap;
140 }
141
142 for (i = 0, namesz = 0,
143 modent = (ctf_archive_modent_t *) ((char *) archdr
144 + sizeof (struct ctf_archive));
139633c3 145 i < le64toh (archdr->ctfa_ndicts); i++)
9402cc59
NA
146 {
147 off_t off;
148
149 strcpy (&nametbl[namesz], names[i]);
150
139633c3 151 off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
9402cc59
NA
152 if ((off < 0) && (off > -ECTF_BASE))
153 {
926c9e76
NA
154 errmsg = N_("ctf_arc_write(): cannot determine file "
155 "position while writing to archive");
9402cc59
NA
156 goto err_free;
157 }
158 if (off < 0)
159 {
926c9e76 160 errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
9402cc59
NA
161 errno = off * -1;
162 goto err_free;
163 }
164
165 modent->name_offset = htole64 (namesz);
166 modent->ctf_offset = htole64 (off - ctf_startoffs);
167 namesz += strlen (names[i]) + 1;
168 modent++;
169 }
170
6b22174f
NA
171 ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
172 + sizeof (struct ctf_archive)),
139633c3 173 le64toh (archdr->ctfa_ndicts),
6b22174f
NA
174 sizeof (struct ctf_archive_modent), sort_modent_by_name,
175 nametbl);
9402cc59
NA
176
177 /* Now the name table. */
178
179 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
180 {
926c9e76
NA
181 errmsg = N_("ctf_arc_write(): cannot get current file position "
182 "in archive");
9402cc59
NA
183 goto err_free;
184 }
185 archdr->ctfa_names = htole64 (nameoffs);
186 np = nametbl;
187 while (namesz > 0)
188 {
189 ssize_t len;
190 if ((len = write (fd, np, namesz)) < 0)
191 {
926c9e76 192 errmsg = N_("ctf_arc_write(): cannot write name table to archive");
9402cc59
NA
193 goto err_free;
194 }
195 namesz -= len;
196 np += len;
197 }
198 free (nametbl);
199
200 if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
201 goto err_unmap;
202 if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
5537f9b9 203 goto err;
9402cc59
NA
204 return 0;
205
206err_free:
207 free (nametbl);
208err_unmap:
209 arc_mmap_unmap (archdr, headersz, NULL);
9402cc59 210err:
926c9e76
NA
211 /* We report errors into the first file in the archive, if any: if this is a
212 zero-file archive, put it in the open-errors stream for lack of anywhere
213 else for it to go. */
139633c3 214 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
926c9e76 215 gettext (errmsg));
9402cc59
NA
216 return errno;
217}
218
139633c3
NA
219/* Write out a CTF archive. The entries in CTF_DICTS are referenced by name:
220 the names are passed in the names array, which must have CTF_DICTS entries.
5537f9b9
NA
221
222 If the filename is NULL, create a temporary file and return a pointer to it.
223
224 Returns 0 on success, or an errno, or an ECTF_* value. */
225int
139633c3 226ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
5537f9b9
NA
227 const char **names, size_t threshold)
228{
229 int err;
230 int fd;
231
232 if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
233 {
139633c3 234 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
926c9e76 235 _("ctf_arc_write(): cannot create %s"), file);
5537f9b9
NA
236 return errno;
237 }
238
139633c3 239 err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
5537f9b9 240 if (err)
df16e041 241 goto err_close;
5537f9b9
NA
242
243 if ((err = close (fd)) < 0)
139633c3 244 ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
926c9e76 245 _("ctf_arc_write(): cannot close after writing to archive"));
df16e041 246 goto err;
5537f9b9
NA
247
248 err_close:
df16e041
NC
249 (void) close (fd);
250 err:
5537f9b9
NA
251 if (err < 0)
252 unlink (file);
253
254 return err;
255}
256
483546ce 257/* Write one CTF dict out. Return the file position of the written file (or
9402cc59
NA
258 rather, of the file-size uint64_t that precedes it): negative return is a
259 negative errno or ctf_errno value. On error, the file position may no longer
260 be at the end of the file. */
261static off_t
483546ce 262arc_write_one_ctf (ctf_dict_t *f, int fd, size_t threshold)
9402cc59
NA
263{
264 off_t off, end_off;
265 uint64_t ctfsz = 0;
266 char *ctfszp;
267 size_t ctfsz_len;
9402cc59
NA
268
269 if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
270 return errno * -1;
271
9402cc59
NA
272 /* This zero-write turns into the size in a moment. */
273 ctfsz_len = sizeof (ctfsz);
274 ctfszp = (char *) &ctfsz;
275 while (ctfsz_len > 0)
276 {
277 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
278 if (writelen < 0)
279 return errno * -1;
280 ctfsz_len -= writelen;
281 ctfszp += writelen;
282 }
283
36c771b1 284 if (ctf_write_thresholded (f, fd, threshold) != 0)
9402cc59
NA
285 return f->ctf_errno * -1;
286
287 if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
288 return errno * -1;
289 ctfsz = htole64 (end_off - off);
290
291 if ((lseek (fd, off, SEEK_SET)) < 0)
292 return errno * -1;
293
294 /* ... here. */
295 ctfsz_len = sizeof (ctfsz);
296 ctfszp = (char *) &ctfsz;
297 while (ctfsz_len > 0)
298 {
299 ssize_t writelen = write (fd, ctfszp, ctfsz_len);
300 if (writelen < 0)
301 return errno * -1;
302 ctfsz_len -= writelen;
303 ctfszp += writelen;
304 }
305
306 end_off = LCTF_ALIGN_OFFS (end_off, 8);
307 if ((lseek (fd, end_off, SEEK_SET)) < 0)
308 return errno * -1;
309
310 return off;
311}
312
313/* qsort() function to sort the array of struct ctf_archive_modents into
314 ascending name order. */
315static int
316sort_modent_by_name (const void *one, const void *two, void *n)
317{
318 const struct ctf_archive_modent *a = one;
319 const struct ctf_archive_modent *b = two;
320 char *nametbl = n;
321
322 return strcmp (&nametbl[le64toh (a->name_offset)],
323 &nametbl[le64toh (b->name_offset)]);
324}
325
2e428e74 326/* bsearch_r() function to search for a given name in the sorted array of struct
9402cc59
NA
327 ctf_archive_modents. */
328static int
2e428e74 329search_modent_by_name (const void *key, const void *ent, void *arg)
9402cc59
NA
330{
331 const char *k = key;
332 const struct ctf_archive_modent *v = ent;
2e428e74 333 const char *search_nametbl = arg;
9402cc59
NA
334
335 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
336}
337
2f6ecaed 338/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
139633c3 339 ctf_dict. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
601e455b 340 STRSECT, as needed, on close. Possibly do not unmap on close. */
2f6ecaed
NA
341
342struct ctf_archive_internal *
601e455b
NA
343ctf_new_archive_internal (int is_archive, int unmap_on_close,
344 struct ctf_archive *arc,
139633c3 345 ctf_dict_t *fp, const ctf_sect_t *symsect,
2f6ecaed
NA
346 const ctf_sect_t *strsect,
347 int *errp)
9402cc59 348{
2f6ecaed 349 struct ctf_archive_internal *arci;
9402cc59 350
2f6ecaed 351 if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
9402cc59 352 {
2f6ecaed 353 if (is_archive)
601e455b
NA
354 {
355 if (unmap_on_close)
356 ctf_arc_close_internal (arc);
357 }
2f6ecaed 358 else
139633c3 359 ctf_dict_close (fp);
2f6ecaed 360 return (ctf_set_open_errno (errp, errno));
9402cc59 361 }
2f6ecaed
NA
362 arci->ctfi_is_archive = is_archive;
363 if (is_archive)
364 arci->ctfi_archive = arc;
365 else
139633c3 366 arci->ctfi_dict = fp;
2f6ecaed
NA
367 if (symsect)
368 memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
369 if (strsect)
370 memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
371 arci->ctfi_free_symsect = 0;
d50c0802 372 arci->ctfi_free_strsect = 0;
601e455b 373 arci->ctfi_unmap_on_close = unmap_on_close;
53651de8 374 arci->ctfi_symsect_little_endian = -1;
2f6ecaed
NA
375
376 return arci;
377}
378
53651de8
NA
379/* Set the symbol-table endianness of an archive (defaulting the symtab
380 endianness of all ctf_file_t's opened from that archive). */
381void
382ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
383{
384 arc->ctfi_symsect_little_endian = !!little_endian;
385 if (!arc->ctfi_is_archive)
386 ctf_symsect_endianness (arc->ctfi_dict, arc->ctfi_symsect_little_endian);
387}
388
3d16b64e
NA
389/* Get the CTF preamble from data in a buffer, which may be either an archive or
390 a CTF dict. If multiple dicts are present in an archive, the preamble comes
391 from an arbitrary dict. The preamble is a pointer into the ctfsect passed
392 in. */
393
394const ctf_preamble_t *
395ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
396{
027333da
AM
397 if (ctfsect->cts_data != NULL
398 && ctfsect->cts_size > sizeof (uint64_t)
399 && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
3d16b64e
NA
400 {
401 struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
402 return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
403 + sizeof (uint64_t));
404 }
405 else
406 return (const ctf_preamble_t *) ctfsect->cts_data;
407}
408
2f6ecaed
NA
409/* Open a CTF archive or dictionary from data in a buffer (which the caller must
410 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
411 error in *err (if not NULL). */
412ctf_archive_t *
413ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
414 const ctf_sect_t *strsect, int *errp)
415{
416 struct ctf_archive *arc = NULL;
417 int is_archive;
139633c3 418 ctf_dict_t *fp = NULL;
2f6ecaed 419
027333da
AM
420 if (ctfsect->cts_data != NULL
421 && ctfsect->cts_size > sizeof (uint64_t)
422 && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
2f6ecaed 423 {
601e455b
NA
424 /* The archive is mmappable, so this operation is trivial.
425
426 This buffer is nonmodifiable, so the trick involving mmapping only part
427 of it and storing the length in the magic number is not applicable: so
428 record this fact in the archive-wrapper header. (We cannot record it
429 in the archive, because the archive may very well be a read-only
430 mapping.) */
2f6ecaed
NA
431
432 is_archive = 1;
433 arc = (struct ctf_archive *) ctfsect->cts_data;
434 }
435 else
436 {
437 is_archive = 0;
438 if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
439 {
926c9e76 440 ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
2f6ecaed
NA
441 return NULL;
442 }
443 }
601e455b 444 return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
2f6ecaed 445 errp);
9402cc59
NA
446}
447
448/* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
449 not NULL). */
450struct ctf_archive *
451ctf_arc_open_internal (const char *filename, int *errp)
452{
453 const char *errmsg;
454 int fd;
455 struct stat s;
456 struct ctf_archive *arc; /* (Actually the whole file.) */
457
458 libctf_init_debug();
459 if ((fd = open (filename, O_RDONLY)) < 0)
460 {
926c9e76 461 errmsg = N_("ctf_arc_open(): cannot open %s");
9402cc59
NA
462 goto err;
463 }
464 if (fstat (fd, &s) < 0)
465 {
926c9e76 466 errmsg = N_("ctf_arc_open(): cannot stat %s");
9402cc59
NA
467 goto err_close;
468 }
469
470 if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
471 {
926c9e76 472 errmsg = N_("ctf_arc_open(): cannot read in %s");
9402cc59
NA
473 goto err_close;
474 }
475
476 if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
477 {
926c9e76 478 errmsg = N_("ctf_arc_open(): %s: invalid magic number");
9402cc59
NA
479 errno = ECTF_FMT;
480 goto err_unmap;
481 }
482
483 /* This horrible hack lets us know how much to unmap when the file is
484 closed. (We no longer need the magic number, and the mapping
485 is private.) */
486 arc->ctfa_magic = s.st_size;
487 close (fd);
14303d62
NA
488
489 if (errp)
490 *errp = 0;
491
9402cc59
NA
492 return arc;
493
494err_unmap:
495 arc_mmap_unmap (arc, s.st_size, NULL);
496err_close:
497 close (fd);
498err:
499 if (errp)
500 *errp = errno;
926c9e76 501 ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
9402cc59
NA
502 return NULL;
503}
504
505/* Close an archive. */
506void
507ctf_arc_close_internal (struct ctf_archive *arc)
508{
509 if (arc == NULL)
510 return;
511
512 /* See the comment in ctf_arc_open(). */
513 arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
514}
515
516/* Public entry point: close an archive, or CTF file. */
517void
518ctf_arc_close (ctf_archive_t *arc)
519{
520 if (arc == NULL)
521 return;
522
523 if (arc->ctfi_is_archive)
601e455b
NA
524 {
525 if (arc->ctfi_unmap_on_close)
526 ctf_arc_close_internal (arc->ctfi_archive);
527 }
9402cc59 528 else
139633c3 529 ctf_dict_close (arc->ctfi_dict);
2c78e925 530 free (arc->ctfi_symdicts);
f4f60336 531 free (arc->ctfi_symnamedicts);
2c78e925 532 ctf_dynhash_destroy (arc->ctfi_dicts);
2f6ecaed
NA
533 if (arc->ctfi_free_symsect)
534 free ((void *) arc->ctfi_symsect.cts_data);
d50c0802
NA
535 if (arc->ctfi_free_strsect)
536 free ((void *) arc->ctfi_strsect.cts_data);
9402cc59 537 free (arc->ctfi_data);
f046147d
NA
538 if (arc->ctfi_bfd_close)
539 arc->ctfi_bfd_close (arc);
9402cc59
NA
540 free (arc);
541}
542
139633c3 543/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59 544 non-NULL. A name of NULL means to open the default file. */
139633c3 545static ctf_dict_t *
ae41200b
NA
546ctf_dict_open_internal (const struct ctf_archive *arc,
547 const ctf_sect_t *symsect,
548 const ctf_sect_t *strsect,
53651de8
NA
549 const char *name, int little_endian,
550 int *errp)
9402cc59
NA
551{
552 struct ctf_archive_modent *modent;
2e428e74 553 const char *search_nametbl;
9402cc59
NA
554
555 if (name == NULL)
556 name = _CTF_SECTION; /* The default name. */
557
ae41200b 558 ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);
9402cc59
NA
559
560 modent = (ctf_archive_modent_t *) ((char *) arc
561 + sizeof (struct ctf_archive));
562
2e428e74 563 search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
139633c3 564 modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
2e428e74
NA
565 sizeof (struct ctf_archive_modent),
566 search_modent_by_name, (void *) search_nametbl);
9402cc59
NA
567
568 /* This is actually a common case and normal operation: no error
569 debug output. */
570 if (modent == NULL)
571 {
572 if (errp)
573 *errp = ECTF_ARNNAME;
574 return NULL;
575 }
576
ae41200b 577 return ctf_dict_open_by_offset (arc, symsect, strsect,
53651de8
NA
578 le64toh (modent->ctf_offset),
579 little_endian, errp);
9402cc59
NA
580}
581
139633c3 582/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59
NA
583 non-NULL. A name of NULL means to open the default file.
584
585 Use the specified string and symbol table sections.
586
587 Public entry point. */
139633c3 588ctf_dict_t *
ae41200b
NA
589ctf_dict_open_sections (const ctf_archive_t *arc,
590 const ctf_sect_t *symsect,
591 const ctf_sect_t *strsect,
592 const char *name,
593 int *errp)
9402cc59 594{
14303d62
NA
595 if (errp)
596 *errp = 0;
597
9402cc59
NA
598 if (arc->ctfi_is_archive)
599 {
139633c3 600 ctf_dict_t *ret;
ae41200b 601 ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
53651de8
NA
602 name, arc->ctfi_symsect_little_endian,
603 errp);
9402cc59 604 if (ret)
2c78e925
NA
605 {
606 ret->ctf_archive = (ctf_archive_t *) arc;
61914bb6
NA
607 if (ctf_arc_import_parent (arc, ret, errp) < 0)
608 {
609 ctf_dict_close (ret);
610 return NULL;
611 }
2c78e925 612 }
9402cc59
NA
613 return ret;
614 }
615
616 if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
617 {
618 if (errp)
619 *errp = ECTF_ARNNAME;
620 return NULL;
621 }
139633c3 622 arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;
9402cc59 623
139633c3
NA
624 /* Bump the refcount so that the user can ctf_dict_close() it. */
625 arc->ctfi_dict->ctf_refcnt++;
626 return arc->ctfi_dict;
9402cc59
NA
627}
628
139633c3 629/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
9402cc59
NA
630 non-NULL. A name of NULL means to open the default file.
631
632 Public entry point. */
139633c3 633ctf_dict_t *
ae41200b 634ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
9402cc59
NA
635{
636 const ctf_sect_t *symsect = &arc->ctfi_symsect;
637 const ctf_sect_t *strsect = &arc->ctfi_strsect;
638
639 if (symsect->cts_name == NULL)
640 symsect = NULL;
641 if (strsect->cts_name == NULL)
642 strsect = NULL;
643
ae41200b 644 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
9402cc59
NA
645}
646
2c78e925
NA
647static void
648ctf_cached_dict_close (void *fp)
649{
650 ctf_dict_close ((ctf_dict_t *) fp);
651}
652
f4f60336
NA
653/* Return the ctf_dict_t with the given name and cache it in the archive's
654 ctfi_dicts. If this is the first cached dict, designate it the
655 crossdict_cache. */
2c78e925
NA
656static ctf_dict_t *
657ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
658{
659 ctf_dict_t *fp;
660 char *dupname;
661
662 /* Just return from the cache if possible. */
663 if (arc->ctfi_dicts
664 && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
665 {
666 fp->ctf_refcnt++;
667 return fp;
668 }
669
670 /* Not yet cached: open it. */
671 fp = ctf_dict_open (arc, name, errp);
672 dupname = strdup (name);
673
674 if (!fp || !dupname)
675 goto oom;
676
677 if (arc->ctfi_dicts == NULL)
678 if ((arc->ctfi_dicts
679 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
680 free, ctf_cached_dict_close)) == NULL)
681 goto oom;
682
683 if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
684 goto oom;
685 fp->ctf_refcnt++;
686
f4f60336
NA
687 if (arc->ctfi_crossdict_cache == NULL)
688 arc->ctfi_crossdict_cache = fp;
689
2c78e925
NA
690 return fp;
691
692 oom:
693 ctf_dict_close (fp);
694 free (dupname);
695 if (errp)
696 *errp = ENOMEM;
697 return NULL;
698}
699
700/* Flush any caches the CTF archive may have open. */
701void
702ctf_arc_flush_caches (ctf_archive_t *wrapper)
703{
704 free (wrapper->ctfi_symdicts);
ca019227 705 ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
2c78e925
NA
706 ctf_dynhash_destroy (wrapper->ctfi_dicts);
707 wrapper->ctfi_symdicts = NULL;
f4f60336 708 wrapper->ctfi_symnamedicts = NULL;
2c78e925 709 wrapper->ctfi_dicts = NULL;
f4f60336 710 wrapper->ctfi_crossdict_cache = NULL;
2c78e925
NA
711}
712
139633c3 713/* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
9402cc59 714 none, setting 'err' if non-NULL. */
139633c3 715static ctf_dict_t *
ae41200b
NA
716ctf_dict_open_by_offset (const struct ctf_archive *arc,
717 const ctf_sect_t *symsect,
718 const ctf_sect_t *strsect, size_t offset,
53651de8 719 int little_endian, int *errp)
9402cc59
NA
720{
721 ctf_sect_t ctfsect;
139633c3 722 ctf_dict_t *fp;
9402cc59 723
ae41200b 724 ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);
9402cc59 725
a0486bac 726 memset (&ctfsect, 0, sizeof (ctf_sect_t));
9402cc59
NA
727
728 offset += le64toh (arc->ctfa_ctfs);
729
730 ctfsect.cts_name = _CTF_SECTION;
9402cc59
NA
731 ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
732 ctfsect.cts_entsize = 1;
9402cc59
NA
733 ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
734 fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
735 if (fp)
53651de8
NA
736 {
737 ctf_setmodel (fp, le64toh (arc->ctfa_model));
738 if (little_endian >= 0)
739 ctf_symsect_endianness (fp, little_endian);
740 }
9402cc59
NA
741 return fp;
742}
743
ae41200b
NA
744/* Backward compatibility. */
745ctf_dict_t *
746ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
747 int *errp)
748{
749 return ctf_dict_open (arc, name, errp);
750}
751
752ctf_dict_t *
753ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
754 const ctf_sect_t *symsect,
755 const ctf_sect_t *strsect,
756 const char *name,
757 int *errp)
758{
759 return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
760}
761
2c78e925
NA
762/* Import the parent into a ctf archive, if this is a child, the parent is not
763 already set, and a suitable archive member exists. No error is raised if
764 this is not possible: this is just a best-effort helper operation to give
765 people useful dicts to start with. */
61914bb6
NA
766static int
767ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
2c78e925
NA
768{
769 if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
770 {
14303d62 771 int err = 0;
2c78e925 772 ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
61914bb6
NA
773 fp->ctf_parname, &err);
774 if (errp)
775 *errp = err;
776
2c78e925
NA
777 if (parent)
778 {
779 ctf_import (fp, parent);
780 ctf_dict_close (parent);
781 }
61914bb6
NA
782 else if (err != ECTF_ARNNAME)
783 return -1; /* errno is set for us. */
2c78e925 784 }
61914bb6 785 return 0;
2c78e925
NA
786}
787
9c23dfa5
NA
788/* Return the number of members in an archive. */
789size_t
790ctf_archive_count (const ctf_archive_t *wrapper)
791{
792 if (!wrapper->ctfi_is_archive)
793 return 1;
794
86fd34fd 795 return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
9c23dfa5
NA
796}
797
f4f60336
NA
798/* Look up a symbol in an archive by name or index (if the name is set, a lookup
799 by name is done). Return the dict in the archive that the symbol is found
800 in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
801 have to look it up yourself). The dict is cached, so repeated lookups are
802 nearly free.
2c78e925
NA
803
804 As usual, you should ctf_dict_close() the returned dict once you are done
805 with it.
806
807 Returns NULL on error, and an error in errp (if set). */
808
f4f60336
NA
809static ctf_dict_t *
810ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
811 const char *symname, ctf_id_t *typep, int *errp)
2c78e925
NA
812{
813 ctf_dict_t *fp;
f4f60336 814 void *fpkey;
2c78e925
NA
815 ctf_id_t type;
816
817 /* The usual non-archive-transparent-wrapper special case. */
818 if (!wrapper->ctfi_is_archive)
819 {
f4f60336 820 if (!symname)
2c78e925 821 {
f4f60336
NA
822 if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
823 {
824 if (errp)
825 *errp = ctf_errno (wrapper->ctfi_dict);
826 return NULL;
827 }
828 }
829 else
830 {
831 if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
832 symname)) == CTF_ERR)
833 {
834 if (errp)
835 *errp = ctf_errno (wrapper->ctfi_dict);
836 return NULL;
837 }
2c78e925
NA
838 }
839 if (typep)
840 *typep = type;
841 wrapper->ctfi_dict->ctf_refcnt++;
842 return wrapper->ctfi_dict;
843 }
844
845 if (wrapper->ctfi_symsect.cts_name == NULL
846 || wrapper->ctfi_symsect.cts_data == NULL
847 || wrapper->ctfi_symsect.cts_size == 0
848 || wrapper->ctfi_symsect.cts_entsize == 0)
849 {
850 if (errp)
851 *errp = ECTF_NOSYMTAB;
852 return NULL;
853 }
854
f4f60336
NA
855 /* Make enough space for all possible symbol indexes, if not already done. We
856 cache the originating dictionary of all symbols. The dict links are weak,
857 to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
858 We also cache similar mappings for symbol names: these are ordinary
859 dynhashes, with weak links to dicts. */
2c78e925 860
f4f60336 861 if (!wrapper->ctfi_symdicts)
2c78e925 862 {
f4f60336
NA
863 if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
864 / wrapper->ctfi_symsect.cts_entsize,
865 sizeof (ctf_dict_t *))) == NULL)
2c78e925
NA
866 {
867 if (errp)
868 *errp = ENOMEM;
869 return NULL;
870 }
871 }
f4f60336 872 if (!wrapper->ctfi_symnamedicts)
2c78e925 873 {
f4f60336
NA
874 if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
875 ctf_hash_eq_string,
876 free, NULL)) == NULL)
2c78e925
NA
877 {
878 if (errp)
879 *errp = ENOMEM;
880 return NULL;
881 }
882 }
883
f4f60336
NA
884 /* Perhaps the dict in which we found a previous lookup is cached. If it's
885 supposed to be cached but we don't find it, pretend it was always not
886 found: this should never happen, but shouldn't be allowed to cause trouble
887 if it does. */
888
889 if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
890 symname, NULL, &fpkey))
891 || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
2c78e925 892 {
f4f60336
NA
893 if (symname)
894 fp = (ctf_dict_t *) fpkey;
895 else
896 fp = wrapper->ctfi_symdicts[symidx];
897
898 if (fp == &enosym)
899 goto no_sym;
900
901 if (symname)
2c78e925 902 {
f4f60336
NA
903 if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
904 goto cache_no_sym;
905 }
906 else
907 {
908 if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
909 goto cache_no_sym;
2c78e925
NA
910 }
911
912 if (typep)
f4f60336
NA
913 *typep = type;
914 fp->ctf_refcnt++;
915 return fp;
2c78e925
NA
916 }
917
918 /* Not cached: find it and cache it. We must track open errors ourselves even
919 if our caller doesn't, to be able to distinguish no-error end-of-iteration
920 from open errors. */
921
922 int local_err;
923 int *local_errp;
924 ctf_next_t *i = NULL;
925 const char *name;
926
927 if (errp)
928 local_errp = errp;
929 else
930 local_errp = &local_err;
931
932 while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
933 {
f4f60336 934 if (!symname)
2c78e925 935 {
f4f60336
NA
936 if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
937 wrapper->ctfi_symdicts[symidx] = fp;
938 }
939 else
940 {
941 if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
942 {
943 char *tmp;
944 /* No error checking, as above. */
945 if ((tmp = strdup (symname)) != NULL)
946 ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
947 }
948 }
2c78e925 949
f4f60336
NA
950 if (type != CTF_ERR)
951 {
2c78e925
NA
952 if (typep)
953 *typep = type;
f4f60336 954 ctf_next_destroy (i);
2c78e925
NA
955 return fp;
956 }
f4f60336
NA
957 if (ctf_errno (fp) != ECTF_NOTYPEDAT)
958 {
959 if (errp)
960 *errp = ctf_errno (fp);
e3cd5660 961 ctf_dict_close (fp);
f4f60336
NA
962 ctf_next_destroy (i);
963 return NULL; /* errno is set for us. */
964 }
2c78e925
NA
965 ctf_dict_close (fp);
966 }
967 if (*local_errp != ECTF_NEXT_END)
968 {
969 ctf_next_destroy (i);
970 return NULL;
971 }
f4f60336 972
2c78e925
NA
973 /* Don't leak end-of-iteration to the caller. */
974 *local_errp = 0;
975
f4f60336
NA
976 cache_no_sym:
977 if (!symname)
978 wrapper->ctfi_symdicts[symidx] = &enosym;
979 else
980 {
981 char *tmp;
982
983 /* No error checking: if caching fails, there is only a slight performance
984 impact. */
985 if ((tmp = strdup (symname)) != NULL)
986 if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
987 free (tmp);
988 }
2c78e925 989
f4f60336 990 no_sym:
2c78e925
NA
991 if (errp)
992 *errp = ECTF_NOTYPEDAT;
993 if (typep)
994 *typep = CTF_ERR;
995 return NULL;
996}
997
f4f60336
NA
998/* The public API for looking up a symbol by index. */
999ctf_dict_t *
1000ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
1001 ctf_id_t *typep, int *errp)
1002{
1003 return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
1004}
1005
1006/* The public API for looking up a symbol by name. */
1007
1008ctf_dict_t *
1009ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
1010 ctf_id_t *typep, int *errp)
1011{
1012 return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
1013}
1014
2fa4b6e6
NA
1015/* Return all enumeration constants with a given NAME across all dicts in an
1016 archive, similar to ctf_lookup_enumerator_next. The DICT is cached, so
1017 opening costs are paid only once, but (unlike ctf_arc_lookup_symbol*
1018 above) the results of the iterations are not cached. dict and errp are
1019 not optional. */
1020
1021ctf_id_t
1022ctf_arc_lookup_enumerator_next (ctf_archive_t *arc, const char *name,
1023 ctf_next_t **it, int64_t *enum_value,
1024 ctf_dict_t **dict, int *errp)
1025{
1026 ctf_next_t *i = *it;
1027 ctf_id_t type;
1028 int opened_this_time = 0;
1029 int err;
1030
1031 /* We have two nested iterators in here: ctn_next tracks archives, while
1032 within it ctn_next_inner tracks enumerators within an archive. We
1033 keep track of the dict by simply reusing the passed-in arg: if it's
1034 changed by the caller, the caller will get an ECTF_WRONGFP error,
1035 so this is quite safe and means we don't have to track the arc and fp
1036 simultaneously in the ctf_next_t. */
1037
1038 if (!i)
1039 {
1040 if ((i = ctf_next_create ()) == NULL)
1041 {
1042 err = ENOMEM;
1043 goto err;
1044 }
1045 i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
1046 i->cu.ctn_arc = arc;
1047 *it = i;
1048 }
1049
1050 if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
1051 {
1052 err = ECTF_NEXT_WRONGFUN;
1053 goto err;
1054 }
1055
1056 if (arc != i->cu.ctn_arc)
1057 {
1058 err = ECTF_NEXT_WRONGFP;
1059 goto err;
1060 }
1061
1062 /* Prevent any earlier end-of-iteration on this dict from confusing the
1063 test below. */
1064 if (i->ctn_next != NULL)
1065 ctf_set_errno (*dict, 0);
1066
1067 do
1068 {
1069 /* At end of one dict, or not started any iterations yet?
1070 Traverse to next dict. If we never returned this dict to the
1071 caller, close it ourselves: the caller will never see it and cannot
1072 do so. */
1073
1074 if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
1075 {
1076 if (opened_this_time)
1077 {
1078 ctf_dict_close (*dict);
1079 *dict = NULL;
1080 opened_this_time = 0;
1081 }
1082
1083 *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
1084 if (!*dict)
1085 goto err;
1086 opened_this_time = 1;
1087 }
1088
1089 type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
1090 enum_value);
1091 }
1092 while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);
1093
1094 if (type == CTF_ERR)
1095 {
1096 err = ctf_errno (*dict);
1097 goto err;
1098 }
1099
1100 /* If this dict is being reused from the previous iteration, bump its
1101 refcnt: the caller is going to close it and has no idea that we didn't
1102 open it this time round. */
1103 if (!opened_this_time)
1104 ctf_ref (*dict);
1105
1106 return type;
1107
1108 err: /* Also ECTF_NEXT_END. */
1109 if (opened_this_time)
1110 {
1111 ctf_dict_close (*dict);
1112 *dict = NULL;
1113 }
1114
1115 ctf_next_destroy (i);
1116 *it = NULL;
1117 if (errp)
1118 *errp = err;
1119 return CTF_ERR;
1120}
1121
9402cc59
NA
1122/* Raw iteration over all CTF files in an archive. We pass the raw data for all
1123 CTF files in turn to the specified callback function. */
1124static int
1125ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
1126 ctf_archive_raw_member_f *func, void *data)
1127{
1128 int rc;
1129 size_t i;
1130 struct ctf_archive_modent *modent;
1131 const char *nametbl;
1132
1133 modent = (ctf_archive_modent_t *) ((char *) arc
1134 + sizeof (struct ctf_archive));
1135 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1136
139633c3 1137 for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
9402cc59
NA
1138 {
1139 const char *name;
1140 char *fp;
1141
1142 name = &nametbl[le64toh (modent[i].name_offset)];
1143 fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
1144 + le64toh (modent[i].ctf_offset));
1145
1146 if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
1147 le64toh (*((uint64_t *) fp)), data)) != 0)
1148 return rc;
1149 }
1150 return 0;
1151}
1152
1153/* Raw iteration over all CTF files in an archive: public entry point.
1154
1155 Returns -EINVAL if not supported for this sort of archive. */
1156int
1157ctf_archive_raw_iter (const ctf_archive_t *arc,
1158 ctf_archive_raw_member_f * func, void *data)
1159{
1160 if (arc->ctfi_is_archive)
1161 return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);
1162
1163 return -EINVAL; /* Not supported. */
1164}
1165
ac36e134
NA
1166/* Iterate over all CTF files in an archive: public entry point. We pass all
1167 CTF files in turn to the specified callback function. */
1168int
1169ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
1170 void *data)
9402cc59 1171{
ac36e134
NA
1172 ctf_next_t *i = NULL;
1173 ctf_dict_t *fp;
1174 const char *name;
2dd3fd0d 1175 int err = 0;
9402cc59 1176
ac36e134 1177 while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
9402cc59 1178 {
ac36e134 1179 int rc;
9402cc59 1180
ac36e134 1181 if ((rc = func (fp, name, data)) != 0)
9402cc59 1182 {
ac36e134
NA
1183 ctf_dict_close (fp);
1184 ctf_next_destroy (i);
9402cc59
NA
1185 return rc;
1186 }
ac36e134 1187 ctf_dict_close (fp);
9402cc59 1188 }
2dd3fd0d
NA
1189 if (err != ECTF_NEXT_END && err != 0)
1190 {
1191 ctf_next_destroy (i);
1192 return -1;
1193 }
9402cc59
NA
1194 return 0;
1195}
1196
688d28f6 1197/* Iterate over all CTF files in an archive, returning each dict in turn as a
139633c3 1198 ctf_dict_t, and NULL on error or end of iteration. It is the caller's
8769046e 1199 responsibility to close it. Parent dicts may be skipped.
688d28f6 1200
2c78e925
NA
1201 The archive member is cached for rapid return on future calls.
1202
688d28f6
NA
1203 We identify parents by name rather than by flag value: for now, with the
1204 linker only emitting parents named _CTF_SECTION, this works well enough. */
1205
139633c3 1206ctf_dict_t *
688d28f6
NA
1207ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
1208 int skip_parent, int *errp)
1209{
139633c3 1210 ctf_dict_t *f;
688d28f6
NA
1211 ctf_next_t *i = *it;
1212 struct ctf_archive *arc;
1213 struct ctf_archive_modent *modent;
1214 const char *nametbl;
1215 const char *name_;
1216
1217 if (!i)
1218 {
1219 if ((i = ctf_next_create()) == NULL)
1220 {
1221 if (errp)
1222 *errp = ENOMEM;
1223 return NULL;
1224 }
1225 i->cu.ctn_arc = wrapper;
1226 i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
1227 *it = i;
1228 }
1229
1230 if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
1231 {
1232 if (errp)
1233 *errp = ECTF_NEXT_WRONGFUN;
1234 return NULL;
1235 }
1236
1237 if (wrapper != i->cu.ctn_arc)
1238 {
1239 if (errp)
1240 *errp = ECTF_NEXT_WRONGFP;
1241 return NULL;
1242 }
1243
139633c3 1244 /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
688d28f6
NA
1245 transparently wrapped in a single-member archive. These are parents: if
1246 skip_parent is on, they are skipped and the iterator terminates
1247 immediately. */
1248
1249 if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
1250 {
1251 i->ctn_n++;
1252 if (!skip_parent)
1253 {
139633c3 1254 wrapper->ctfi_dict->ctf_refcnt++;
eaa2913a
NA
1255 if (name)
1256 *name = _CTF_SECTION;
139633c3 1257 return wrapper->ctfi_dict;
688d28f6
NA
1258 }
1259 }
1260
1261 arc = wrapper->ctfi_archive;
1262
1263 /* The loop keeps going when skip_parent is on as long as the member we find
1264 is the parent (i.e. at most two iterations, but possibly an early return if
1265 *all* we have is a parent). */
1266
688d28f6
NA
1267 do
1268 {
139633c3 1269 if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
688d28f6
NA
1270 {
1271 ctf_next_destroy (i);
1272 *it = NULL;
1273 if (errp)
1274 *errp = ECTF_NEXT_END;
1275 return NULL;
1276 }
1277
688d28f6
NA
1278 modent = (ctf_archive_modent_t *) ((char *) arc
1279 + sizeof (struct ctf_archive));
1280 nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
1281
1282 name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
1283 i->ctn_n++;
eefe721e
NA
1284 }
1285 while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);
688d28f6
NA
1286
1287 if (name)
1288 *name = name_;
1289
2c78e925 1290 f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
688d28f6
NA
1291 return f;
1292}
1293
9402cc59
NA
1294#ifdef HAVE_MMAP
1295/* Map the header in. Only used on new, empty files. */
1296static void *arc_mmap_header (int fd, size_t headersz)
1297{
1298 void *hdr;
1299 if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
1300 0)) == MAP_FAILED)
1301 return NULL;
1302 return hdr;
1303}
1304
1305/* mmap() the whole file, for reading only. (Map it writably, but privately: we
1306 need to modify the region, but don't need anyone else to see the
1307 modifications.) */
1308static void *arc_mmap_file (int fd, size_t size)
1309{
1310 void *arc;
1311 if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
1312 fd, 0)) == MAP_FAILED)
1313 return NULL;
1314 return arc;
1315}
1316
1317/* Persist the header to disk. */
1318static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
1319 size_t headersz, const char **errmsg)
1320{
1321 if (msync (header, headersz, MS_ASYNC) < 0)
1322 {
1323 if (errmsg)
926c9e76
NA
1324 *errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
1325 "to %s: %s");
9402cc59
NA
1326 return -1;
1327 }
1328 return 0;
1329}
1330
1331/* Unmap the region. */
1332static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
1333{
1334 if (munmap (header, headersz) < 0)
1335 {
1336 if (errmsg)
926c9e76
NA
1337 *errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
1338 "to %s: %s");
9402cc59
NA
1339 return -1;
1340 }
1341 return 0;
1342}
1343#else
1344/* Map the header in. Only used on new, empty files. */
f5e73be1 1345static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
9402cc59
NA
1346{
1347 void *hdr;
1348 if ((hdr = malloc (headersz)) == NULL)
1349 return NULL;
1350 return hdr;
1351}
1352
1353/* Pull in the whole file, for reading only. We assume the current file
1354 position is at the start of the file. */
1355static void *arc_mmap_file (int fd, size_t size)
1356{
1357 char *data;
1358
1359 if ((data = malloc (size)) == NULL)
1360 return NULL;
1361
1362 if (ctf_pread (fd, data, size, 0) < 0)
1363 {
1364 free (data);
1365 return NULL;
1366 }
1367 return data;
1368}
1369
1370/* Persist the header to disk. */
1371static int arc_mmap_writeout (int fd, void *header, size_t headersz,
1372 const char **errmsg)
1373{
1374 ssize_t len;
9402cc59
NA
1375 char *data = (char *) header;
1376 ssize_t count = headersz;
1377
1378 if ((lseek (fd, 0, SEEK_SET)) < 0)
1379 {
1380 if (errmsg)
926c9e76
NA
1381 *errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
1382 "%s: %s");
9402cc59
NA
1383 return -1;
1384 }
1385
1386 while (headersz > 0)
1387 {
1388 if ((len = write (fd, data, count)) < 0)
1389 {
1390 if (errmsg)
926c9e76 1391 *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
9402cc59
NA
1392 return len;
1393 }
1394 if (len == EINTR)
1395 continue;
1396
9402cc59
NA
1397 if (len == 0) /* EOF. */
1398 break;
1399
1400 count -= len;
1401 data += len;
1402 }
1403 return 0;
1404}
1405
1406/* Unmap the region. */
1407static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
1408 const char **errmsg _libctf_unused_)
1409{
1410 free (header);
1411 return 0;
1412}
1413#endif