This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 07/16] binutils: bfd: Implement bfd_uninit


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]