This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 07/16] binutils: bfd: Implement bfd_uninit
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, binutils at sourceware dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Mon, 1 Jun 2015 17:04:15 -0400
- Subject: [PATCH 07/16] binutils: bfd: Implement bfd_uninit
- Authentication-results: sourceware.org; auth=none
- References: <1433192664-50156-1-git-send-email-dmalcolm at redhat dot com>
This patch adds a new API entrypoint to libbfd: bfd_uninit,
which resets global state within the library.
The patch (and subsequent ones) follow a pattern I used in gcc for
cleaning up global state: for each source file e.g. foo.c to have a
function:
extern void foo_c_finalize (void);
to explicitly reset all statically-allocated global data back to its
initial value.
Two warts: where should prototypes for internal functions be declared?
I need to put an:
extern void section_c_finalize (void);
into an internal header, but I don't want to expose that as API.
Similarly, is there a way to use a linker script to hide the function?
bfd/ChangeLog:
* bfd-in2.h: Regenerate.
* elflink.c (elf_flags_to_names): Make const.
* init.c (bfd_uninit): New function.
* section.c (reinit_BFD_FAKE_SECTION): New function.
(reinit_STD_SECTION): New function.
(section_c_finalize): New function.
---
bfd/bfd-in2.h | 2 ++
bfd/elflink.c | 2 +-
bfd/init.c | 20 ++++++++++++++++++++
bfd/section.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ade49ff..cba57b3 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1016,6 +1016,8 @@ extern bfd_boolean v850_elf_set_note
/* Extracted from init.c. */
void bfd_init (void);
+void bfd_uninit (void);
+
/* Extracted from opncls.c. */
/* Set to N to open the next N BFDs using an alternate id space. */
extern unsigned int bfd_use_reserved_id;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6efe1e4..d8c1171 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12639,7 +12639,7 @@ typedef struct
flagword flag_value;
} elf_flags_to_name_table;
-static elf_flags_to_name_table elf_flags_to_names [] =
+static const elf_flags_to_name_table elf_flags_to_names [] =
{
{ "SHF_WRITE", SHF_WRITE },
{ "SHF_ALLOC", SHF_ALLOC },
diff --git a/bfd/init.c b/bfd/init.c
index 323f0ac..e4fae11 100644
--- a/bfd/init.c
+++ b/bfd/init.c
@@ -52,3 +52,23 @@ void
bfd_init (void)
{
}
+
+/*
+FUNCTION
+ bfd_uninit
+
+SYNOPSIS
+ void bfd_uninit (void);
+
+DESCRIPTION
+ Purge internal state within the library.
+*/
+
+/* FIXME: where should prototypes for internal functions be declared? */
+extern void section_c_finalize (void);
+
+void
+bfd_uninit (void)
+{
+ section_c_finalize ();
+}
diff --git a/bfd/section.c b/bfd/section.c
index 24422bf..f1d445f 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -1666,3 +1666,56 @@ bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED,
{
return TRUE;
}
+
+/* Helper function for reinit_STD_SECTION
+ Reset the given section back to its initial state.
+ Based on macro BFD_FAKE_SECTION. */
+
+static void
+reinit_BFD_FAKE_SECTION (asection *sec,
+ int flags,
+ const struct bfd_symbol *sym,
+ const char *name,
+ int idx)
+{
+ /* Zero it. */
+ memset (sec, 0, sizeof (*sec));
+
+ /* Now fixup the things that BFD_FAKE_SECTION makes nonzero. */
+ sec->name = name;
+ sec->id = idx;
+ sec->flags = flags;
+ sec->gc_mark = 1;
+ sec->output_section = sec;
+ sec->symbol = (struct bfd_symbol *) sym; /* (cast away constness) */
+ sec->symbol_ptr_ptr = &sec->symbol;
+}
+
+/* Helper function for section_c_finalize.
+ Reset one of the global sections within _bfd_std_section back to its
+ initial state.
+ Based on macros STD_SECTION and BFD_FAKE_SECTION. */
+
+static void
+reinit_STD_SECTION (const char *name,
+ int idx,
+ int flags)
+{
+ asection *sec = &_bfd_std_section[idx];
+ reinit_BFD_FAKE_SECTION (sec, flags, &global_syms[idx], name, idx);
+}
+
+/* FIXME: where should prototypes for internal functions be declared? */
+extern void
+section_c_finalize (void);
+
+/* Reset global state within section.c back to its original state. */
+
+void
+section_c_finalize (void)
+{
+ reinit_STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON);
+ reinit_STD_SECTION (BFD_UND_SECTION_NAME, 1, 0);
+ reinit_STD_SECTION (BFD_ABS_SECTION_NAME, 2, 0);
+ reinit_STD_SECTION (BFD_IND_SECTION_NAME, 3, 0);
+}
--
1.8.5.3