diff options
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 12 | ||||
-rw-r--r-- | libctf/ctf-archive.c | 76 | ||||
-rw-r--r-- | libctf/ctf-impl.h | 6 | ||||
-rw-r--r-- | libctf/ctf-open-bfd.c | 68 | ||||
-rw-r--r-- | libctf/libctf.ver | 1 |
5 files changed, 88 insertions, 75 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 3ab0a6c..5e473a7 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,17 @@ 2020-06-26 Nick Alcock <nick.alcock@oracle.com> + * ctf-impl.h (ctf_new_archive_internal): Declare. + (ctf_arc_bufopen): Remove. + (ctf_archive_internal) <ctfi_free_symsect>: New. + * ctf-archive.c (ctf_arc_close): Use it. + (ctf_arc_bufopen): Fuse into... + (ctf_new_archive_internal): ... this, moved across from... + * ctf-open-bfd.c: ... here. + (ctf_bfdopen_ctfsect): Use ctf_arc_bufopen. + * libctf.ver: Add it. + +2020-06-26 Nick Alcock <nick.alcock@oracle.com> + * ctf-create.c (ctf_add_forward): Intern in the right namespace. (ctf_dtd_delete): Remove correspondingly. (ctf_rollback): Likewise. diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index 73d772f..d27b27e 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -343,21 +343,71 @@ search_modent_by_name (const void *key, const void *ent) return strcmp (k, &search_nametbl[le64toh (v->name_offset)]); } -/* A trivial wrapper: open a CTF archive, from data in a buffer (which the - caller must preserve until ctf_arc_close() time). Returns the archive, or - NULL and an error in *err (if not NULL). */ -struct ctf_archive * -ctf_arc_bufopen (const void *buf, size_t size _libctf_unused_, int *errp) +/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a + ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or + STRSECT, as needed, on close. */ + +struct ctf_archive_internal * +ctf_new_archive_internal (int is_archive, struct ctf_archive *arc, + ctf_file_t *fp, const ctf_sect_t *symsect, + const ctf_sect_t *strsect, + int *errp) { - struct ctf_archive *arc = (struct ctf_archive *) buf; + struct ctf_archive_internal *arci; - if (le64toh (arc->ctfa_magic) != CTFA_MAGIC) + if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL) { - if (errp) - *errp = ECTF_FMT; - return NULL; + if (is_archive) + ctf_arc_close_internal (arc); + else + ctf_file_close (fp); + return (ctf_set_open_errno (errp, errno)); } - return arc; + arci->ctfi_is_archive = is_archive; + if (is_archive) + arci->ctfi_archive = arc; + else + arci->ctfi_file = fp; + if (symsect) + memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect)); + if (strsect) + memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect)); + arci->ctfi_free_symsect = 0; + + return arci; +} + +/* Open a CTF archive or dictionary from data in a buffer (which the caller must + preserve until ctf_arc_close() time). Returns the archive, or NULL and an + error in *err (if not NULL). */ +ctf_archive_t * +ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, + const ctf_sect_t *strsect, int *errp) +{ + struct ctf_archive *arc = NULL; + int is_archive; + ctf_file_t *fp = NULL; + + if (ctfsect->cts_size > sizeof (uint64_t) && + ((*(uint64_t *) ctfsect->cts_data) == CTFA_MAGIC)) + { + /* The archive is mmappable, so this operation is trivial. */ + + is_archive = 1; + arc = (struct ctf_archive *) ctfsect->cts_data; + } + else + { + is_archive = 0; + if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL) + { + ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n", + ctf_errmsg (*errp)); + return NULL; + } + } + return ctf_new_archive_internal (is_archive, arc, fp, symsect, strsect, + errp); } /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if @@ -436,8 +486,8 @@ ctf_arc_close (ctf_archive_t *arc) ctf_arc_close_internal (arc->ctfi_archive); else ctf_file_close (arc->ctfi_file); - free ((void *) arc->ctfi_symsect.cts_data); - /* Do not free the ctfi_strsect: it is bound to the bfd. */ + if (arc->ctfi_free_symsect) + free ((void *) arc->ctfi_symsect.cts_data); free (arc->ctfi_data); if (arc->ctfi_bfd_close) arc->ctfi_bfd_close (arc); diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 56ef9a3..ade1a6e 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -309,6 +309,7 @@ struct ctf_archive_internal struct ctf_archive *ctfi_archive; ctf_sect_t ctfi_symsect; ctf_sect_t ctfi_strsect; + int ctfi_free_symsect; void *ctfi_data; bfd *ctfi_abfd; /* Optional source of section data. */ void (*ctfi_bfd_close) (struct ctf_archive_internal *); @@ -435,8 +436,11 @@ extern void ctf_str_rollback (ctf_file_t *, ctf_snapshot_id_t); extern void ctf_str_purge_refs (ctf_file_t *); extern ctf_strs_writable_t ctf_str_write_strtab (ctf_file_t *); +extern struct ctf_archive_internal *ctf_new_archive_internal + (int is_archive, struct ctf_archive *arc, + ctf_file_t *fp, const ctf_sect_t *symsect, + const ctf_sect_t *strsect, int *errp); extern struct ctf_archive *ctf_arc_open_internal (const char *, int *); -extern struct ctf_archive *ctf_arc_bufopen (const void *, size_t, int *); extern void ctf_arc_close_internal (struct ctf_archive *); extern void *ctf_set_open_errno (int *, int); extern unsigned long ctf_set_errno (ctf_file_t *, int); diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c index 24c0403..630a158 100644 --- a/libctf/ctf-open-bfd.c +++ b/libctf/ctf-open-bfd.c @@ -32,40 +32,6 @@ #include "elf-bfd.h" -/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a - ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or - STRSECT, as needed, on close (though the STRSECT interior is bound to the bfd - * and is not actually freed by this machinery). */ - -static struct ctf_archive_internal * -ctf_new_archive_internal (int is_archive, struct ctf_archive *arc, - ctf_file_t *fp, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, - int *errp) -{ - struct ctf_archive_internal *arci; - - if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL) - { - if (is_archive) - ctf_arc_close_internal (arc); - else - ctf_file_close (fp); - return (ctf_set_open_errno (errp, errno)); - } - arci->ctfi_is_archive = is_archive; - if (is_archive) - arci->ctfi_archive = arc; - else - arci->ctfi_file = fp; - if (symsect) - memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect)); - if (strsect) - memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect)); - - return arci; -} - /* Free the BFD bits of a CTF file on ctf_arc_close(). */ static void @@ -107,6 +73,7 @@ ctf_bfdopen (struct bfd *abfd, int *errp) if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL) { + /* This frees the cts_data later. */ arc->ctfi_data = (void *) ctfsect.cts_data; return arc; } @@ -116,20 +83,16 @@ ctf_bfdopen (struct bfd *abfd, int *errp) } /* Open a CTF file given the specified BFD and CTF section (which may contain a - CTF archive or a file). Takes ownership of the ctfsect, and frees it - later. */ + CTF archive or a file). */ ctf_archive_t * ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, const ctf_sect_t *ctfsect, int *errp) { - struct ctf_archive *arc = NULL; ctf_archive_t *arci; - ctf_file_t *fp = NULL; ctf_sect_t *symsectp = NULL; ctf_sect_t *strsectp = NULL; const char *bfderrstr = NULL; - int is_archive; #ifdef HAVE_BFD_ELF ctf_sect_t symsect, strsect; @@ -192,30 +155,13 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, } #endif - if (ctfsect->cts_size > sizeof (uint64_t) && - ((*(uint64_t *) ctfsect->cts_data) == CTFA_MAGIC)) - { - is_archive = 1; - if ((arc = ctf_arc_bufopen ((void *) ctfsect->cts_data, - ctfsect->cts_size, errp)) == NULL) - goto err_free_str; - } - else + arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp); + if (arci) { - is_archive = 0; - if ((fp = ctf_bufopen (ctfsect, symsectp, strsectp, errp)) == NULL) - { - ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n", - ctf_errmsg (*errp)); - goto err_free_str; - } + /* Request freeing of the symsect. */ + arci->ctfi_free_symsect = 1; + return arci; } - arci = ctf_new_archive_internal (is_archive, arc, fp, symsectp, strsectp, - errp); - - if (arci) - return arci; - err_free_str: ; #ifdef HAVE_BFD_ELF err_free_sym: free (symtab); diff --git a/libctf/libctf.ver b/libctf/libctf.ver index 14ca413..aad304b 100644 --- a/libctf/libctf.ver +++ b/libctf/libctf.ver @@ -128,6 +128,7 @@ LIBCTF_1.0 { ctf_arc_write; ctf_arc_write_fd; ctf_arc_open; + ctf_arc_bufopen; ctf_arc_close; ctf_arc_open_by_name; ctf_arc_open_by_name_sections; |