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_file_t
* f
, int fd
, size_t threshold
);
36 static 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
);
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_FILES are referenced by name: the names are passed in
49 the names array, which must have CTF_FILES entries.
51 Returns 0 on success, or an errno, or an ECTF_* value. */
53 ctf_arc_write_fd (int fd
, ctf_file_t
**ctf_files
, size_t ctf_file_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_file_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_file_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
= "ctf_arc_write(): cannot extend file while writing: %s\n";
89 if (write (fd
, &dummy
, 1) < 0)
91 errmsg
= "ctf_arc_write(): cannot extend file while writing: %s\n";
95 if ((archdr
= arc_mmap_header (fd
, headersz
)) == NULL
)
97 errmsg
= "ctf_arc_write(): Cannot mmap(): %s\n";
101 /* Fill in everything we can, which is everything other than the name
103 archdr
->ctfa_magic
= htole64 (CTFA_MAGIC
);
104 archdr
->ctfa_nfiles
= htole64 (ctf_file_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_file_cnt
> 0)
116 archdr
->ctfa_model
= htole64 (ctf_getmodel (ctf_files
[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_nfiles
); i
++)
126 namesz
+= strlen (names
[i
]) + 1;
128 nametbl
= malloc (namesz
);
131 errmsg
= "Error writing named CTF to archive: %s\n";
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
++)
142 strcpy (&nametbl
[namesz
], names
[i
]);
144 off
= arc_write_one_ctf (ctf_files
[i
], fd
, threshold
);
145 if ((off
< 0) && (off
> -ECTF_BASE
))
147 errmsg
= "ctf_arc_write(): Cannot determine file "
148 "position while writing to archive: %s";
153 errmsg
= "ctf_arc_write(): Cannot write CTF file to archive: %s\n";
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_nfiles
),
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
= "ctf_arc_write(): Cannot get current file position "
178 archdr
->ctfa_names
= htole64 (nameoffs
);
183 if ((len
= write (fd
, np
, namesz
)) < 0)
185 errmsg
= "ctf_arc_write(): Cannot write name table to archive: %s\n";
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 ctf_dprintf (errmsg
, errno
< ECTF_BASE
? strerror (errno
) :
209 /* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
210 the names are passed in the names array, which must have CTF_FILES entries.
212 If the filename is NULL, create a temporary file and return a pointer to it.
214 Returns 0 on success, or an errno, or an ECTF_* value. */
216 ctf_arc_write (const char *file
, ctf_file_t
** ctf_files
, size_t ctf_file_cnt
,
217 const char **names
, size_t threshold
)
222 if ((fd
= open (file
, O_RDWR
| O_CREAT
| O_TRUNC
| O_CLOEXEC
, 0666)) < 0)
224 ctf_dprintf ("ctf_arc_write(): cannot create %s: %s\n", file
,
229 err
= ctf_arc_write_fd (fd
, ctf_files
, ctf_file_cnt
, names
, threshold
);
233 if ((err
= close (fd
)) < 0)
234 ctf_dprintf ("ctf_arc_write(): Cannot close after writing to archive: "
235 "%s\n", strerror (errno
));
247 /* Write one CTF file out. Return the file position of the written file (or
248 rather, of the file-size uint64_t that precedes it): negative return is a
249 negative errno or ctf_errno value. On error, the file position may no longer
250 be at the end of the file. */
252 arc_write_one_ctf (ctf_file_t
* f
, int fd
, size_t threshold
)
258 int (*writefn
) (ctf_file_t
* fp
, int fd
);
260 if (ctf_serialize (f
) < 0)
261 return f
->ctf_errno
* -1;
263 if ((off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
266 if (f
->ctf_size
> threshold
)
267 writefn
= ctf_compress_write
;
271 /* This zero-write turns into the size in a moment. */
272 ctfsz_len
= sizeof (ctfsz
);
273 ctfszp
= (char *) &ctfsz
;
274 while (ctfsz_len
> 0)
276 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
279 ctfsz_len
-= writelen
;
283 if (writefn (f
, fd
) != 0)
284 return f
->ctf_errno
* -1;
286 if ((end_off
= lseek (fd
, 0, SEEK_CUR
)) < 0)
288 ctfsz
= htole64 (end_off
- off
);
290 if ((lseek (fd
, off
, SEEK_SET
)) < 0)
294 ctfsz_len
= sizeof (ctfsz
);
295 ctfszp
= (char *) &ctfsz
;
296 while (ctfsz_len
> 0)
298 ssize_t writelen
= write (fd
, ctfszp
, ctfsz_len
);
301 ctfsz_len
-= writelen
;
305 end_off
= LCTF_ALIGN_OFFS (end_off
, 8);
306 if ((lseek (fd
, end_off
, SEEK_SET
)) < 0)
312 /* qsort() function to sort the array of struct ctf_archive_modents into
313 ascending name order. */
315 sort_modent_by_name (const void *one
, const void *two
, void *n
)
317 const struct ctf_archive_modent
*a
= one
;
318 const struct ctf_archive_modent
*b
= two
;
321 return strcmp (&nametbl
[le64toh (a
->name_offset
)],
322 &nametbl
[le64toh (b
->name_offset
)]);
325 /* bsearch_r() function to search for a given name in the sorted array of struct
326 ctf_archive_modents. */
328 search_modent_by_name (const void *key
, const void *ent
, void *arg
)
331 const struct ctf_archive_modent
*v
= ent
;
332 const char *search_nametbl
= arg
;
334 return strcmp (k
, &search_nametbl
[le64toh (v
->name_offset
)]);
337 /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
338 ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
339 STRSECT, as needed, on close. Possibly do not unmap on close. */
341 struct ctf_archive_internal
*
342 ctf_new_archive_internal (int is_archive
, int unmap_on_close
,
343 struct ctf_archive
*arc
,
344 ctf_file_t
*fp
, const ctf_sect_t
*symsect
,
345 const ctf_sect_t
*strsect
,
348 struct ctf_archive_internal
*arci
;
350 if ((arci
= calloc (1, sizeof (struct ctf_archive_internal
))) == NULL
)
355 ctf_arc_close_internal (arc
);
359 return (ctf_set_open_errno (errp
, errno
));
361 arci
->ctfi_is_archive
= is_archive
;
363 arci
->ctfi_archive
= arc
;
365 arci
->ctfi_file
= fp
;
367 memcpy (&arci
->ctfi_symsect
, symsect
, sizeof (struct ctf_sect
));
369 memcpy (&arci
->ctfi_strsect
, strsect
, sizeof (struct ctf_sect
));
370 arci
->ctfi_free_symsect
= 0;
371 arci
->ctfi_unmap_on_close
= unmap_on_close
;
376 /* Open a CTF archive or dictionary from data in a buffer (which the caller must
377 preserve until ctf_arc_close() time). Returns the archive, or NULL and an
378 error in *err (if not NULL). */
380 ctf_arc_bufopen (const ctf_sect_t
*ctfsect
, const ctf_sect_t
*symsect
,
381 const ctf_sect_t
*strsect
, int *errp
)
383 struct ctf_archive
*arc
= NULL
;
385 ctf_file_t
*fp
= NULL
;
387 if (ctfsect
->cts_size
> sizeof (uint64_t) &&
388 ((*(uint64_t *) ctfsect
->cts_data
) == CTFA_MAGIC
))
390 /* The archive is mmappable, so this operation is trivial.
392 This buffer is nonmodifiable, so the trick involving mmapping only part
393 of it and storing the length in the magic number is not applicable: so
394 record this fact in the archive-wrapper header. (We cannot record it
395 in the archive, because the archive may very well be a read-only
399 arc
= (struct ctf_archive
*) ctfsect
->cts_data
;
404 if ((fp
= ctf_bufopen (ctfsect
, symsect
, strsect
, errp
)) == NULL
)
406 ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n",
411 return ctf_new_archive_internal (is_archive
, 0, arc
, fp
, symsect
, strsect
,
415 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
418 ctf_arc_open_internal (const char *filename
, int *errp
)
423 struct ctf_archive
*arc
; /* (Actually the whole file.) */
426 if ((fd
= open (filename
, O_RDONLY
)) < 0)
428 errmsg
= "ctf_arc_open(): cannot open %s: %s\n";
431 if (fstat (fd
, &s
) < 0)
433 errmsg
= "ctf_arc_open(): cannot stat %s: %s\n";
437 if ((arc
= arc_mmap_file (fd
, s
.st_size
)) == NULL
)
439 errmsg
= "ctf_arc_open(): Cannot read in %s: %s\n";
443 if (le64toh (arc
->ctfa_magic
) != CTFA_MAGIC
)
445 errmsg
= "ctf_arc_open(): Invalid magic number";
450 /* This horrible hack lets us know how much to unmap when the file is
451 closed. (We no longer need the magic number, and the mapping
453 arc
->ctfa_magic
= s
.st_size
;
458 arc_mmap_unmap (arc
, s
.st_size
, NULL
);
464 ctf_dprintf (errmsg
, filename
, errno
< ECTF_BASE
? strerror (errno
) :
469 /* Close an archive. */
471 ctf_arc_close_internal (struct ctf_archive
*arc
)
476 /* See the comment in ctf_arc_open(). */
477 arc_mmap_unmap (arc
, arc
->ctfa_magic
, NULL
);
480 /* Public entry point: close an archive, or CTF file. */
482 ctf_arc_close (ctf_archive_t
*arc
)
487 if (arc
->ctfi_is_archive
)
489 if (arc
->ctfi_unmap_on_close
)
490 ctf_arc_close_internal (arc
->ctfi_archive
);
493 ctf_file_close (arc
->ctfi_file
);
494 if (arc
->ctfi_free_symsect
)
495 free ((void *) arc
->ctfi_symsect
.cts_data
);
496 free (arc
->ctfi_data
);
497 if (arc
->ctfi_bfd_close
)
498 arc
->ctfi_bfd_close (arc
);
502 /* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
503 non-NULL. A name of NULL means to open the default file. */
505 ctf_arc_open_by_name_internal (const struct ctf_archive
*arc
,
506 const ctf_sect_t
*symsect
,
507 const ctf_sect_t
*strsect
,
508 const char *name
, int *errp
)
510 struct ctf_archive_modent
*modent
;
511 const char *search_nametbl
;
514 name
= _CTF_SECTION
; /* The default name. */
516 ctf_dprintf ("ctf_arc_open_by_name(%s): opening\n", name
);
518 modent
= (ctf_archive_modent_t
*) ((char *) arc
519 + sizeof (struct ctf_archive
));
521 search_nametbl
= (const char *) arc
+ le64toh (arc
->ctfa_names
);
522 modent
= bsearch_r (name
, modent
, le64toh (arc
->ctfa_nfiles
),
523 sizeof (struct ctf_archive_modent
),
524 search_modent_by_name
, (void *) search_nametbl
);
526 /* This is actually a common case and normal operation: no error
531 *errp
= ECTF_ARNNAME
;
535 return ctf_arc_open_by_offset (arc
, symsect
, strsect
,
536 le64toh (modent
->ctf_offset
), errp
);
539 /* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
540 non-NULL. A name of NULL means to open the default file.
542 Use the specified string and symbol table sections.
544 Public entry point. */
546 ctf_arc_open_by_name_sections (const ctf_archive_t
*arc
,
547 const ctf_sect_t
*symsect
,
548 const ctf_sect_t
*strsect
,
552 if (arc
->ctfi_is_archive
)
555 ret
= ctf_arc_open_by_name_internal (arc
->ctfi_archive
, symsect
, strsect
,
558 ret
->ctf_archive
= (ctf_archive_t
*) arc
;
562 if ((name
!= NULL
) && (strcmp (name
, _CTF_SECTION
) != 0))
565 *errp
= ECTF_ARNNAME
;
568 arc
->ctfi_file
->ctf_archive
= (ctf_archive_t
*) arc
;
570 /* Bump the refcount so that the user can ctf_file_close() it. */
571 arc
->ctfi_file
->ctf_refcnt
++;
572 return arc
->ctfi_file
;
575 /* Return the ctf_file_t with the given name, or NULL if none, setting 'err' if
576 non-NULL. A name of NULL means to open the default file.
578 Public entry point. */
580 ctf_arc_open_by_name (const ctf_archive_t
*arc
, const char *name
, int *errp
)
582 const ctf_sect_t
*symsect
= &arc
->ctfi_symsect
;
583 const ctf_sect_t
*strsect
= &arc
->ctfi_strsect
;
585 if (symsect
->cts_name
== NULL
)
587 if (strsect
->cts_name
== NULL
)
590 return ctf_arc_open_by_name_sections (arc
, symsect
, strsect
, name
, errp
);
593 /* Return the ctf_file_t at the given ctfa_ctfs-relative offset, or NULL if
594 none, setting 'err' if non-NULL. */
596 ctf_arc_open_by_offset (const struct ctf_archive
*arc
,
597 const ctf_sect_t
*symsect
,
598 const ctf_sect_t
*strsect
, size_t offset
,
604 ctf_dprintf ("ctf_arc_open_by_offset(%lu): opening\n", (unsigned long) offset
);
606 memset (&ctfsect
, 0, sizeof (ctf_sect_t
));
608 offset
+= le64toh (arc
->ctfa_ctfs
);
610 ctfsect
.cts_name
= _CTF_SECTION
;
611 ctfsect
.cts_size
= le64toh (*((uint64_t *) ((char *) arc
+ offset
)));
612 ctfsect
.cts_entsize
= 1;
613 ctfsect
.cts_data
= (void *) ((char *) arc
+ offset
+ sizeof (uint64_t));
614 fp
= ctf_bufopen (&ctfsect
, symsect
, strsect
, errp
);
616 ctf_setmodel (fp
, le64toh (arc
->ctfa_model
));
620 /* Return the number of members in an archive. */
622 ctf_archive_count (const ctf_archive_t
*wrapper
)
624 if (!wrapper
->ctfi_is_archive
)
627 return wrapper
->ctfi_archive
->ctfa_nfiles
;
630 /* Raw iteration over all CTF files in an archive. We pass the raw data for all
631 CTF files in turn to the specified callback function. */
633 ctf_archive_raw_iter_internal (const struct ctf_archive
*arc
,
634 ctf_archive_raw_member_f
*func
, void *data
)
638 struct ctf_archive_modent
*modent
;
641 modent
= (ctf_archive_modent_t
*) ((char *) arc
642 + sizeof (struct ctf_archive
));
643 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
645 for (i
= 0; i
< le64toh (arc
->ctfa_nfiles
); i
++)
650 name
= &nametbl
[le64toh (modent
[i
].name_offset
)];
651 fp
= ((char *) arc
+ le64toh (arc
->ctfa_ctfs
)
652 + le64toh (modent
[i
].ctf_offset
));
654 if ((rc
= func (name
, (void *) (fp
+ sizeof (uint64_t)),
655 le64toh (*((uint64_t *) fp
)), data
)) != 0)
661 /* Raw iteration over all CTF files in an archive: public entry point.
663 Returns -EINVAL if not supported for this sort of archive. */
665 ctf_archive_raw_iter (const ctf_archive_t
*arc
,
666 ctf_archive_raw_member_f
* func
, void *data
)
668 if (arc
->ctfi_is_archive
)
669 return ctf_archive_raw_iter_internal (arc
->ctfi_archive
, func
, data
);
671 return -EINVAL
; /* Not supported. */
674 /* Iterate over all CTF files in an archive. We pass all CTF files in turn to
675 the specified callback function. */
677 ctf_archive_iter_internal (const ctf_archive_t
*wrapper
,
678 const struct ctf_archive
*arc
,
679 const ctf_sect_t
*symsect
,
680 const ctf_sect_t
*strsect
,
681 ctf_archive_member_f
*func
, void *data
)
686 struct ctf_archive_modent
*modent
;
689 modent
= (ctf_archive_modent_t
*) ((char *) arc
690 + sizeof (struct ctf_archive
));
691 nametbl
= (((const char *) arc
) + le64toh (arc
->ctfa_names
));
693 for (i
= 0; i
< le64toh (arc
->ctfa_nfiles
); i
++)
697 name
= &nametbl
[le64toh (modent
[i
].name_offset
)];
698 if ((f
= ctf_arc_open_by_name_internal (arc
, symsect
, strsect
,
702 f
->ctf_archive
= (ctf_archive_t
*) wrapper
;
703 if ((rc
= func (f
, name
, data
)) != 0)
714 /* Iterate over all CTF files in an archive: public entry point. We pass all
715 CTF files in turn to the specified callback function. */
717 ctf_archive_iter (const ctf_archive_t
*arc
, ctf_archive_member_f
*func
,
720 const ctf_sect_t
*symsect
= &arc
->ctfi_symsect
;
721 const ctf_sect_t
*strsect
= &arc
->ctfi_strsect
;
723 if (symsect
->cts_name
== NULL
)
725 if (strsect
->cts_name
== NULL
)
728 if (arc
->ctfi_is_archive
)
729 return ctf_archive_iter_internal (arc
, arc
->ctfi_archive
, symsect
, strsect
,
732 return func (arc
->ctfi_file
, _CTF_SECTION
, data
);
736 /* Map the header in. Only used on new, empty files. */
737 static void *arc_mmap_header (int fd
, size_t headersz
)
740 if ((hdr
= mmap (NULL
, headersz
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
,
746 /* mmap() the whole file, for reading only. (Map it writably, but privately: we
747 need to modify the region, but don't need anyone else to see the
749 static void *arc_mmap_file (int fd
, size_t size
)
752 if ((arc
= mmap (NULL
, size
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
,
753 fd
, 0)) == MAP_FAILED
)
758 /* Persist the header to disk. */
759 static int arc_mmap_writeout (int fd _libctf_unused_
, void *header
,
760 size_t headersz
, const char **errmsg
)
762 if (msync (header
, headersz
, MS_ASYNC
) < 0)
765 *errmsg
= "arc_mmap_writeout(): Cannot sync after writing to %s: %s\n";
771 /* Unmap the region. */
772 static int arc_mmap_unmap (void *header
, size_t headersz
, const char **errmsg
)
774 if (munmap (header
, headersz
) < 0)
777 *errmsg
= "arc_mmap_munmap(): Cannot unmap after writing to %s: %s\n";
783 /* Map the header in. Only used on new, empty files. */
784 static void *arc_mmap_header (int fd _libctf_unused_
, size_t headersz
)
787 if ((hdr
= malloc (headersz
)) == NULL
)
792 /* Pull in the whole file, for reading only. We assume the current file
793 position is at the start of the file. */
794 static void *arc_mmap_file (int fd
, size_t size
)
798 if ((data
= malloc (size
)) == NULL
)
801 if (ctf_pread (fd
, data
, size
, 0) < 0)
809 /* Persist the header to disk. */
810 static int arc_mmap_writeout (int fd
, void *header
, size_t headersz
,
815 char *data
= (char *) header
;
816 ssize_t count
= headersz
;
818 if ((lseek (fd
, 0, SEEK_SET
)) < 0)
821 *errmsg
= "arc_mmap_writeout(): Cannot seek while writing header to "
828 if ((len
= write (fd
, data
, count
)) < 0)
831 *errmsg
= "arc_mmap_writeout(): Cannot write header to %s: %s\n";
838 if (len
== 0) /* EOF. */
847 /* Unmap the region. */
848 static int arc_mmap_unmap (void *header
, size_t headersz _libctf_unused_
,
849 const char **errmsg _libctf_unused_
)