2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
21 #include <sys/types.h>
24 #include "ctf-endian.h"
35 static off_t
arc_write_one_ctf (ctf_dict_t
* f
, int fd
, size_t threshold
);
36 static ctf_dict_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
);
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
,
45 static int arc_mmap_unmap (void *header
, size_t headersz
, const char **errmsg
);
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.
51 Returns 0 on success, or an errno, or an ECTF_* value. */
53 ctf_arc_write_fd (int fd
, ctf_dict_t
**ctf_dicts
, size_t ctf_dict_cnt
,
54 const char **names
, size_t threshold
)
57 struct ctf_archive
*archdr
;
62 size_t ctf_startoffs
; /* Start of the section we are working over. */
63 char *nametbl
= NULL
; /* The name table. */
66 struct ctf_archive_modent
*modent
;
68 ctf_dprintf ("Writing CTF archive with %lu files\n",
69 (unsigned long) ctf_dict_cnt
);
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
75 headersz
= sizeof (struct ctf_archive
)
76 + (ctf_dict_cnt
* sizeof (uint64_t) * 2);
77 ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz
);
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)
85 errmsg
= N_("ctf_arc_write(): cannot extend file while writing");
89 if (write (fd
, &dummy
, 1) < 0)
91 errmsg
= N_("ctf_arc_write(): cannot extend file while writing");
95 if ((archdr
= arc_mmap_header (fd
, headersz
)) == NULL
)
97 errmsg
= N_("ctf_arc_write(): cannot mmap");
101 /* Fill in everything we can, which is everything other than the name
103 archdr
->ctfa_magic
= htole64 (CTFA_MAGIC
);
104 archdr
->ctfa_ndicts
= htole64 (ctf_dict_cnt
);
105 archdr
->ctfa_ctfs
= htole64 (ctf_startoffs
);
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
115 if (ctf_dict_cnt
> 0)
116 archdr
->ctfa_model
= htole64 (ctf_getmodel (ctf_dicts
[0]));
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.
123 The name table is not sorted. */
125 for (i
= 0, namesz
= 0; i
< le64toh (archdr
->ctfa_ndicts
); i
++)
126 namesz
+= strlen (names
[i
]) + 1;
128 nametbl
= malloc (namesz
);
131 errmsg
= N_("ctf_arc_write(): error writing named CTF to archive");
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
++)
142 strcpy (&nametbl
[namesz
], names
[i
]);
144 off
= arc_write_one_ctf (ctf_dicts
[i
], fd
, threshold
);
145 if ((off
< 0) && (off
> -ECTF_BASE
))
147 errmsg
= N_("ctf_arc_write(): cannot determine file "
148 "position while writing to archive");
153 errmsg
= N_("ctf_arc_write(): cannot write CTF file to archive");
158 modent
->name_offset
= htole64 (namesz
);
159 modent
->ctf_offset
= htole64 (off
- ctf_startoffs
);
160 namesz
+= strlen (names
[i
]) + 1;
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
,
170 /* Now the name table. */
172 if ((nameoffs
= lseek (fd
, 0, SEEK_CUR
)) < 0)
174 errmsg
= N_("ctf_arc_write(): cannot get current file position "
178 archdr
->ctfa_names
= htole64 (nameoffs
);
183 if ((len
= write (fd
, np
, namesz
)) < 0)
185 errmsg
= N_("ctf_arc_write(): cannot write name table to archive");
193 if (arc_mmap_writeout (fd
, archdr
, headersz
, &errmsg
) < 0)
195 if (arc_mmap_unmap (archdr
, headersz
, &errmsg
) < 0)
202 arc_mmap_unmap (archdr
, headersz
, NULL
);
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",
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.
215 If the filename is NULL, create a temporary file and return a pointer to it.
217 Returns 0 on success, or an errno, or an ECTF_* value. */
219 ctf_arc_write (const char *file
, ctf_dict_t
**ctf_dicts
, size_t ctf_dict_cnt
,
220 const char **names
, size_t threshold
)
225 if ((fd
= open (file
, O_RDWR
| O_CREAT
| O_TRUNC
| O_CLOEXEC
, 0666)) < 0)
227 ctf_err_warn (ctf_dict_cnt
> 0 ? ctf_dicts
[0] : NULL
, 0, errno
,
228 _("ctf_arc_write(): cannot create %s"), file
);
232 err
= ctf_arc_write_fd (fd
, ctf_dicts
, ctf_dict_cnt
, names
, threshold
);
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"));
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. */
255 arc_write_one_ctf (ctf_dict_t
* f
, int fd
, size_t threshold
)
261 int (*writefn
) (ctf_dict_t
* fp
, int fd
);
263 if (ctf_serialize (f
) < 0)
264 return f
->ctf_errno
* -1;
266 if ((off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
269 if (f
->ctf_size
> threshold
)
270 writefn
= ctf_compress_write
;
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)
279 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
282 ctfsz_len
-= writelen
;
286 if (writefn (f
, fd
) != 0)
287 return f
->ctf_errno
* -1;
289 if ((end_off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
291 ctfsz
= htole64 (end_off
- off
);
293 if ((lseek (fd
, off
, SEEK_SET
)) < 0)
297 ctfsz_len
= sizeof (ctfsz
);
298 ctfszp
= (char *) &ctfsz
;
299 while (ctfsz_len
> 0)
301 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
304 ctfsz_len
-= writelen
;
308 end_off
= LCTF_ALIGN_OFFS (end_off
, 8);
309 if ((lseek (fd
, end_off
, SEEK_SET
)) < 0)
315 /* qsort() function to sort the array of struct ctf_archive_modents into
316 ascending name order. */
318 sort_modent_by_name (const void *one
, const void *two
, void *n
)
320 const struct ctf_archive_modent
*a
= one
;
321 const struct ctf_archive_modent
*b
= two
;
324 return strcmp (&nametbl
[le64toh (a
->name_offset
)],
325 &nametbl
[le64toh (b
->name_offset
)]);
328 /* bsearch_r() function to search for a given name in the sorted array of struct
329 ctf_archive_modents. */
331 search_modent_by_name (const void *key
, const void *ent
, void *arg
)
334 const struct ctf_archive_modent
*v
= ent
;
335 const char *search_nametbl
= arg
;
337 return strcmp (k
, &search_nametbl
[le64toh (v
->name_offset
)]);
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. */
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
,
351 struct ctf_archive_internal
*arci
;
353 if ((arci
= calloc (1, sizeof (struct ctf_archive_internal
))) == NULL
)
358 ctf_arc_close_internal (arc
);
362 return (ctf_set_open_errno (errp
, errno
));
364 arci
->ctfi_is_archive
= is_archive
;
366 arci
->ctfi_archive
= arc
;
368 arci
->ctfi_dict
= fp
;
370 memcpy (&arci
->ctfi_symsect
, symsect
, sizeof (struct ctf_sect
));
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
;
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). */
384 ctf_arc_bufopen (const ctf_sect_t
*ctfsect
, const ctf_sect_t
*symsect
,
385 const ctf_sect_t
*strsect
, int *errp
)
387 struct ctf_archive
*arc
= NULL
;
389 ctf_dict_t
*fp
= NULL
;
391 if (ctfsect
->cts_size
> sizeof (uint64_t) &&
392 (le64toh ((*(uint64_t *) ctfsect
->cts_data
)) == CTFA_MAGIC
))
394 /* The archive is mmappable, so this operation is trivial.
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
403 arc
= (struct ctf_archive
*) ctfsect
->cts_data
;
408 if ((fp
= ctf_bufopen (ctfsect
, symsect
, strsect
, errp
)) == NULL
)
410 ctf_err_warn (NULL
, 0, *errp
, _("ctf_arc_bufopen(): cannot open CTF"));
414 return ctf_new_archive_internal (is_archive
, 0, arc
, fp
, symsect
, strsect
,
418 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
421 ctf_arc_open_internal (const char *filename
, int *errp
)
426 struct ctf_archive
*arc
; /* (Actually the whole file.) */
429 if ((fd
= open (filename
, O_RDONLY
)) < 0)
431 errmsg
= N_("ctf_arc_open(): cannot open %s");
434 if (fstat (fd
, &s
) < 0)
436 errmsg
= N_("ctf_arc_open(): cannot stat %s");
440 if ((arc
= arc_mmap_file (fd
, s
.st_size
)) == NULL
)
442 errmsg
= N_("ctf_arc_open(): cannot read in %s");
446 if (le64toh (arc
->ctfa_magic
) != CTFA_MAGIC
)
448 errmsg
= N_("ctf_arc_open(): %s: invalid magic number");
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
456 arc
->ctfa_magic
= s
.st_size
;
461 arc_mmap_unmap (arc
, s
.st_size
, NULL
);
467 ctf_err_warn (NULL
, 0, errno
, gettext (errmsg
), filename
);
471 /* Close an archive. */
473 ctf_arc_close_internal (struct ctf_archive
*arc
)
478 /* See the comment in ctf_arc_open(). */
479 arc_mmap_unmap (arc
, arc
->ctfa_magic
, NULL
);
482 /* Public entry point: close an archive, or CTF file. */
484 ctf_arc_close (ctf_archive_t
*arc
)
489 if (arc
->ctfi_is_archive
)
491 if (arc
->ctfi_unmap_on_close
)
492 ctf_arc_close_internal (arc
->ctfi_archive
);
495 ctf_dict_close (arc
->ctfi_dict
);
496 if (arc
->ctfi_free_symsect
)
497 free ((void *) arc
->ctfi_symsect
.cts_data
);
498 if (arc
->ctfi_free_strsect
)
499 free ((void *) arc
->ctfi_strsect
.cts_data
);
500 free (arc
->ctfi_data
);
501 if (arc
->ctfi_bfd_close
)
502 arc
->ctfi_bfd_close (arc
);
506 /* Return the ctf_dict_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. */
509 ctf_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
)
514 struct ctf_archive_modent
*modent
;
515 const char *search_nametbl
;
518 name
= _CTF_SECTION
; /* The default name. */
520 ctf_dprintf ("ctf_arc_open_by_name(%s): opening\n", name
);
522 modent
= (ctf_archive_modent_t
*) ((char *) arc
523 + sizeof (struct ctf_archive
));
525 search_nametbl
= (const char *) arc
+ le64toh (arc
->ctfa_names
);
526 modent
= bsearch_r (name
, modent
, le64toh (arc
->ctfa_ndicts
),
527 sizeof (struct ctf_archive_modent
),
528 search_modent_by_name
, (void *) search_nametbl
);
530 /* This is actually a common case and normal operation: no error
535 *errp
= ECTF_ARNNAME
;
539 return ctf_arc_open_by_offset (arc
, symsect
, strsect
,
540 le64toh (modent
->ctf_offset
), errp
);
543 /* Return the ctf_dict_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.
546 Use the specified string and symbol table sections.
548 Public entry point. */
550 ctf_arc_open_by_name_sections (const ctf_archive_t
*arc
,
551 const ctf_sect_t
*symsect
,
552 const ctf_sect_t
*strsect
,
556 if (arc
->ctfi_is_archive
)
559 ret
= ctf_arc_open_by_name_internal (arc
->ctfi_archive
, symsect
, strsect
,
562 ret
->ctf_archive
= (ctf_archive_t
*) arc
;
566 if ((name
!= NULL
) && (strcmp (name
, _CTF_SECTION
) != 0))
569 *errp
= ECTF_ARNNAME
;
572 arc
->ctfi_dict
->ctf_archive
= (ctf_archive_t
*) arc
;
574 /* Bump the refcount so that the user can ctf_dict_close() it. */
575 arc
->ctfi_dict
->ctf_refcnt
++;
576 return arc
->ctfi_dict
;
579 /* Return the ctf_dict_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.
582 Public entry point. */
584 ctf_arc_open_by_name (const ctf_archive_t
*arc
, const char *name
, int *errp
)
586 const ctf_sect_t
*symsect
= &arc
->ctfi_symsect
;
587 const ctf_sect_t
*strsect
= &arc
->ctfi_strsect
;
589 if (symsect
->cts_name
== NULL
)
591 if (strsect
->cts_name
== NULL
)
594 return ctf_arc_open_by_name_sections (arc
, symsect
, strsect
, name
, errp
);
597 /* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
598 none, setting 'err' if non-NULL. */
600 ctf_arc_open_by_offset (const struct ctf_archive
*arc
,
601 const ctf_sect_t
*symsect
,
602 const ctf_sect_t
*strsect
, size_t offset
,
608 ctf_dprintf ("ctf_arc_open_by_offset(%lu): opening\n", (unsigned long) offset
);
610 memset (&ctfsect
, 0, sizeof (ctf_sect_t
));
612 offset
+= le64toh (arc
->ctfa_ctfs
);
614 ctfsect
.cts_name
= _CTF_SECTION
;
615 ctfsect
.cts_size
= le64toh (*((uint64_t *) ((char *) arc
+ offset
)));
616 ctfsect
.cts_entsize
= 1;
617 ctfsect
.cts_data
= (void *) ((char *) arc
+ offset
+ sizeof (uint64_t));
618 fp
= ctf_bufopen (&ctfsect
, symsect
, strsect
, errp
);
620 ctf_setmodel (fp
, le64toh (arc
->ctfa_model
));
624 /* Return the number of members in an archive. */
626 ctf_archive_count (const ctf_archive_t
*wrapper
)
628 if (!wrapper
->ctfi_is_archive
)
631 return wrapper
->ctfi_archive
->ctfa_ndicts
;
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. */
637 ctf_archive_raw_iter_internal (const struct ctf_archive
*arc
,
638 ctf_archive_raw_member_f
*func
, void *data
)
642 struct ctf_archive_modent
*modent
;
645 modent
= (ctf_archive_modent_t
*) ((char *) arc
646 + sizeof (struct ctf_archive
));
647 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
649 for (i
= 0; i
< le64toh (arc
->ctfa_ndicts
); i
++)
654 name
= &nametbl
[le64toh (modent
[i
].name_offset
)];
655 fp
= ((char *) arc
+ le64toh (arc
->ctfa_ctfs
)
656 + le64toh (modent
[i
].ctf_offset
));
658 if ((rc
= func (name
, (void *) (fp
+ sizeof (uint64_t)),
659 le64toh (*((uint64_t *) fp
)), data
)) != 0)
665 /* Raw iteration over all CTF files in an archive: public entry point.
667 Returns -EINVAL if not supported for this sort of archive. */
669 ctf_archive_raw_iter (const ctf_archive_t
*arc
,
670 ctf_archive_raw_member_f
* func
, void *data
)
672 if (arc
->ctfi_is_archive
)
673 return ctf_archive_raw_iter_internal (arc
->ctfi_archive
, func
, data
);
675 return -EINVAL
; /* Not supported. */
678 /* Iterate over all CTF files in an archive. We pass all CTF files in turn to
679 the specified callback function. */
681 ctf_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
)
690 struct ctf_archive_modent
*modent
;
693 modent
= (ctf_archive_modent_t
*) ((char *) arc
694 + sizeof (struct ctf_archive
));
695 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
697 for (i
= 0; i
< le64toh (arc
->ctfa_ndicts
); i
++)
701 name
= &nametbl
[le64toh (modent
[i
].name_offset
)];
702 if ((f
= ctf_arc_open_by_name_internal (arc
, symsect
, strsect
,
706 f
->ctf_archive
= (ctf_archive_t
*) wrapper
;
707 if ((rc
= func (f
, name
, data
)) != 0)
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. */
721 ctf_archive_iter (const ctf_archive_t
*arc
, ctf_archive_member_f
*func
,
724 const ctf_sect_t
*symsect
= &arc
->ctfi_symsect
;
725 const ctf_sect_t
*strsect
= &arc
->ctfi_strsect
;
727 if (symsect
->cts_name
== NULL
)
729 if (strsect
->cts_name
== NULL
)
732 if (arc
->ctfi_is_archive
)
733 return ctf_archive_iter_internal (arc
, arc
->ctfi_archive
, symsect
, strsect
,
736 return func (arc
->ctfi_dict
, _CTF_SECTION
, data
);
739 /* Iterate over all CTF files in an archive, returning each dict in turn as a
740 ctf_dict_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
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. */
749 ctf_archive_next (const ctf_archive_t
*wrapper
, ctf_next_t
**it
, const char **name
,
750 int skip_parent
, int *errp
)
754 struct ctf_archive
*arc
;
755 struct ctf_archive_modent
*modent
;
761 if ((i
= ctf_next_create()) == NULL
)
767 i
->cu
.ctn_arc
= wrapper
;
768 i
->ctn_iter_fun
= (void (*) (void)) ctf_archive_next
;
772 if ((void (*) (void)) ctf_archive_next
!= i
->ctn_iter_fun
)
775 *errp
= ECTF_NEXT_WRONGFUN
;
779 if (wrapper
!= i
->cu
.ctn_arc
)
782 *errp
= ECTF_NEXT_WRONGFP
;
786 /* Iteration is made a bit more complex by the need to handle ctf_dict_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
791 if (!wrapper
->ctfi_is_archive
&& i
->ctn_n
== 0)
796 wrapper
->ctfi_dict
->ctf_refcnt
++;
797 return wrapper
->ctfi_dict
;
801 arc
= wrapper
->ctfi_archive
;
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). */
807 const ctf_sect_t
*symsect
;
808 const ctf_sect_t
*strsect
;
812 if ((!wrapper
->ctfi_is_archive
) || (i
->ctn_n
>= le64toh (arc
->ctfa_ndicts
)))
814 ctf_next_destroy (i
);
817 *errp
= ECTF_NEXT_END
;
821 symsect
= &wrapper
->ctfi_symsect
;
822 strsect
= &wrapper
->ctfi_strsect
;
824 if (symsect
->cts_name
== NULL
)
826 if (strsect
->cts_name
== NULL
)
829 modent
= (ctf_archive_modent_t
*) ((char *) arc
830 + sizeof (struct ctf_archive
));
831 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
833 name_
= &nametbl
[le64toh (modent
[i
->ctn_n
].name_offset
)];
835 } while (skip_parent
&& strcmp (name_
, _CTF_SECTION
) == 0);
840 f
= ctf_arc_open_by_name_internal (arc
, symsect
, strsect
,
842 f
->ctf_archive
= (ctf_archive_t
*) wrapper
;
847 /* Map the header in. Only used on new, empty files. */
848 static void *arc_mmap_header (int fd
, size_t headersz
)
851 if ((hdr
= mmap (NULL
, headersz
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
,
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
860 static void *arc_mmap_file (int fd
, size_t size
)
863 if ((arc
= mmap (NULL
, size
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
,
864 fd
, 0)) == MAP_FAILED
)
869 /* Persist the header to disk. */
870 static int arc_mmap_writeout (int fd _libctf_unused_
, void *header
,
871 size_t headersz
, const char **errmsg
)
873 if (msync (header
, headersz
, MS_ASYNC
) < 0)
876 *errmsg
= N_("arc_mmap_writeout(): cannot sync after writing "
883 /* Unmap the region. */
884 static int arc_mmap_unmap (void *header
, size_t headersz
, const char **errmsg
)
886 if (munmap (header
, headersz
) < 0)
889 *errmsg
= N_("arc_mmap_munmap(): cannot unmap after writing "
896 /* Map the header in. Only used on new, empty files. */
897 static void *arc_mmap_header (int fd _libctf_unused_
, size_t headersz
)
900 if ((hdr
= malloc (headersz
)) == NULL
)
905 /* Pull in the whole file, for reading only. We assume the current file
906 position is at the start of the file. */
907 static void *arc_mmap_file (int fd
, size_t size
)
911 if ((data
= malloc (size
)) == NULL
)
914 if (ctf_pread (fd
, data
, size
, 0) < 0)
922 /* Persist the header to disk. */
923 static int arc_mmap_writeout (int fd
, void *header
, size_t headersz
,
928 char *data
= (char *) header
;
929 ssize_t count
= headersz
;
931 if ((lseek (fd
, 0, SEEK_SET
)) < 0)
934 *errmsg
= N_("arc_mmap_writeout(): cannot seek while writing header to "
941 if ((len
= write (fd
, data
, count
)) < 0)
944 *errmsg
= N_("arc_mmap_writeout(): cannot write header to %s: %s");
951 if (len
== 0) /* EOF. */
960 /* Unmap the region. */
961 static int arc_mmap_unmap (void *header
, size_t headersz _libctf_unused_
,
962 const char **errmsg _libctf_unused_
)