aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
Diffstat (limited to 'libctf')
-rw-r--r--libctf/ChangeLog12
-rw-r--r--libctf/ctf-archive.c76
-rw-r--r--libctf/ctf-impl.h6
-rw-r--r--libctf/ctf-open-bfd.c68
-rw-r--r--libctf/libctf.ver1
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;