From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 85573 invoked by alias); 1 Jun 2015 20:55:54 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 85510 invoked by uid 89); 1 Jun 2015 20:55:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.7 required=5.0 tests=AWL,BAYES_05,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 01 Jun 2015 20:55:52 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id E0CD93702D6; Mon, 1 Jun 2015 20:50:19 +0000 (UTC) Received: from c64.redhat.com (vpn-230-103.phx2.redhat.com [10.3.230.103]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t51KoE5E030113; Mon, 1 Jun 2015 16:50:19 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org, binutils@sourceware.org Cc: David Malcolm Subject: [PATCH 07/16] binutils: bfd: Implement bfd_uninit Date: Mon, 01 Jun 2015 20:55:00 -0000 Message-Id: <1433192664-50156-8-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1433192664-50156-1-git-send-email-dmalcolm@redhat.com> References: <1433192664-50156-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg00017.txt.bz2 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