X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libctf%2Fctf-archive.c;h=ed1483ade75af7a87b24675e18efa1e2c9f70865;hb=955ff7fcf8ddc90200819a184380c64c27b76e91;hp=90cd020b781bdd23d43ebd8c721fce46db5e36bb;hpb=6b22174ff163b828a2069f22353018ca97fc0fb4;p=deliverable%2Fbinutils-gdb.git diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index 90cd020b78..ed1483ade7 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -47,17 +47,17 @@ static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg); /* bsearch() internal state. */ static __thread char *search_nametbl; -/* Write out a CTF archive. The entries in CTF_FILES are referenced by name: - the names are passed in the names array, which must have CTF_FILES entries. +/* Write out a CTF archive to the start of the file referenced by the passed-in + fd. The entries in CTF_FILES are referenced by name: the names are passed in + the names array, which must have CTF_FILES entries. Returns 0 on success, or an errno, or an ECTF_* value. */ int -ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, - const char **names, size_t threshold) +ctf_arc_write_fd (int fd, ctf_file_t **ctf_files, size_t ctf_file_cnt, + const char **names, size_t threshold) { const char *errmsg; struct ctf_archive *archdr; - int fd; size_t i; char dummy = 0; size_t headersz; @@ -68,13 +68,8 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, off_t nameoffs; struct ctf_archive_modent *modent; - ctf_dprintf ("Writing archive %s with %zi files\n", file, ctf_file_cnt); - - if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0) - { - errmsg = "ctf_arc_write(): cannot create %s: %s\n"; - goto err; - } + ctf_dprintf ("Writing CTF archive with %lu files\n", + (unsigned long) ctf_file_cnt); /* Figure out the size of the mmap()ed header, including the ctf_archive_modent array. We assume that all of this needs no @@ -82,7 +77,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, uint64_t's. */ headersz = sizeof (struct ctf_archive) + (ctf_file_cnt * sizeof (uint64_t) * 2); - ctf_dprintf ("headersz is %zi\n", headersz); + ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz); /* From now on we work in two pieces: an mmap()ed region from zero up to the headersz, and a region updated via write() starting after that, containing @@ -90,20 +85,20 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, ctf_startoffs = headersz; if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0) { - errmsg = "ctf_arc_write(): cannot extend file while writing %s: %s\n"; - goto err_close; + errmsg = "ctf_arc_write(): cannot extend file while writing: %s\n"; + goto err; } if (write (fd, &dummy, 1) < 0) { - errmsg = "ctf_arc_write(): cannot extend file while writing %s: %s\n"; - goto err_close; + errmsg = "ctf_arc_write(): cannot extend file while writing: %s\n"; + goto err; } if ((archdr = arc_mmap_header (fd, headersz)) == NULL) { - errmsg = "ctf_arc_write(): Cannot mmap() %s: %s\n"; - goto err_close; + errmsg = "ctf_arc_write(): Cannot mmap(): %s\n"; + goto err; } /* Fill in everything we can, which is everything other than the name @@ -136,7 +131,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, nametbl = malloc (namesz); if (nametbl == NULL) { - errmsg = "Error writing named CTF to %s: %s\n"; + errmsg = "Error writing named CTF to archive: %s\n"; goto err_unmap; } @@ -153,12 +148,12 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, if ((off < 0) && (off > -ECTF_BASE)) { errmsg = "ctf_arc_write(): Cannot determine file " - "position while writing %s: %s"; + "position while writing to archive: %s"; goto err_free; } if (off < 0) { - errmsg = "ctf_arc_write(): Cannot write CTF file to %s: %s\n"; + errmsg = "ctf_arc_write(): Cannot write CTF file to archive: %s\n"; errno = off * -1; goto err_free; } @@ -180,7 +175,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0) { errmsg = "ctf_arc_write(): Cannot get current file position " - "in %s: %s\n"; + "in archive: %s\n"; goto err_free; } archdr->ctfa_names = htole64 (nameoffs); @@ -190,7 +185,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, ssize_t len; if ((len = write (fd, np, namesz)) < 0) { - errmsg = "ctf_arc_write(): Cannot write name table in %s: %s\n"; + errmsg = "ctf_arc_write(): Cannot write name table to archive: %s\n"; goto err_free; } namesz -= len; @@ -201,29 +196,64 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0) goto err_unmap; if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0) - goto err_unlink; - if (close (fd) < 0) - { - errmsg = "ctf_arc_write(): Cannot close after writing to %s: %s\n"; - goto err_unlink; - } - + goto err; return 0; err_free: free (nametbl); err_unmap: arc_mmap_unmap (archdr, headersz, NULL); -err_close: - close (fd); -err_unlink: - unlink (file); err: - ctf_dprintf (errmsg, file, errno < ECTF_BASE ? strerror (errno) : + ctf_dprintf (errmsg, errno < ECTF_BASE ? strerror (errno) : ctf_errmsg (errno)); return errno; } +/* Write out a CTF archive. The entries in CTF_FILES are referenced by name: + the names are passed in the names array, which must have CTF_FILES entries. + + If the filename is NULL, create a temporary file and return a pointer to it. + + Returns 0 on success, or an errno, or an ECTF_* value. */ +int +ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, + const char **names, size_t threshold) +{ + int err; + int fd; + + if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0) + { + ctf_dprintf ("ctf_arc_write(): cannot create %s: %s\n", file, + strerror (errno)); + return errno; + } + + err = ctf_arc_write_fd (fd, ctf_files, ctf_file_cnt, names, threshold); + if (err) + goto err; + + if ((err = close (fd)) < 0) + { + ctf_dprintf ("ctf_arc_write(): Cannot close after writing to archive: " + "%s\n", strerror (errno)); + goto err_close; + } + + err: + close (fd); + if (err < 0) + unlink (file); + + return err; + + err_close: + if (err < 0) + unlink (file); + + return err; +} + /* Write one CTF file out. Return the file position of the written file (or rather, of the file-size uint64_t that precedes it): negative return is a negative errno or ctf_errno value. On error, the file position may no longer @@ -237,6 +267,9 @@ arc_write_one_ctf (ctf_file_t * f, int fd, size_t threshold) size_t ctfsz_len; int (*writefn) (ctf_file_t * fp, int fd); + if (ctf_serialize (f) < 0) + return f->ctf_errno * -1; + if ((off = lseek (fd, 0, SEEK_CUR)) < 0) return errno * -1; @@ -404,8 +437,10 @@ ctf_arc_close (ctf_archive_t *arc) else ctf_file_close (arc->ctfi_file); free ((void *) arc->ctfi_symsect.cts_data); - free ((void *) arc->ctfi_strsect.cts_data); + /* Do not free the ctfi_strsect: it is bound to the bfd. */ free (arc->ctfi_data); + if (arc->ctfi_bfd_close) + arc->ctfi_bfd_close (arc); free (arc); } @@ -510,7 +545,7 @@ ctf_arc_open_by_offset (const struct ctf_archive *arc, ctf_sect_t ctfsect; ctf_file_t *fp; - ctf_dprintf ("ctf_arc_open_by_offset(%zi): opening\n", offset); + ctf_dprintf ("ctf_arc_open_by_offset(%lu): opening\n", (unsigned long) offset); memset (&ctfsect, 0, sizeof (ctf_sect_t)); @@ -680,7 +715,7 @@ static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg) } #else /* Map the header in. Only used on new, empty files. */ -static void *arc_mmap_header (int fd, size_t headersz) +static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz) { void *hdr; if ((hdr = malloc (headersz)) == NULL)