public inbox for binutils-cvs@sourceware.org
help / color / mirror / Atom feed
From: Alan Modra <amodra@sourceware.org>
To: bfd-cvs@sourceware.org
Subject: [binutils-gdb] alloc gas seginfo on notes obstack
Date: Mon,  4 Jul 2022 13:25:10 +0000 (GMT)	[thread overview]
Message-ID: <20220704132510.57AA1385E020@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=eeeaf705fe1c94e9330fa222d7928a9d0f03832a

commit eeeaf705fe1c94e9330fa222d7928a9d0f03832a
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jul 4 12:45:47 2022 +0930

    alloc gas seginfo on notes obstack
    
    Lots of memory used in gas should go on this obstack.  The patch also
    frees all the gas obstacks on exit, which isn't a completely trivial
    task.
    
            * subsegs.c (alloc_seginfo): New function.
            (subseg_change, subseg_get): Use it.
            (subsegs_end): New function.
            * as.h (subsegs_end): Declare.
            * output-file.c: Include subsegs.h
            (stash_frchain_obs): New function.
            (output_file_close): Save obstacks attached to output bfd before
            closing.  Call subsegs_end with the array of obstacks.

Diff:
---
 gas/as.h          |  1 +
 gas/output-file.c | 42 +++++++++++++++++++++++++++++++++++++-----
 gas/subsegs.c     | 37 ++++++++++++++++++++++++-------------
 3 files changed, 62 insertions(+), 18 deletions(-)

diff --git a/gas/as.h b/gas/as.h
index 470a2e52891..ec0c12afe23 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -476,6 +476,7 @@ void   input_scrub_end (void);
 void   new_logical_line (const char *, int);
 void   new_logical_line_flags (const char *, int, int);
 void   subsegs_begin (void);
+void   subsegs_end (struct obstack **);
 void   subseg_change (segT, int);
 segT   subseg_new (const char *, subsegT);
 segT   subseg_force_new (const char *, subsegT);
diff --git a/gas/output-file.c b/gas/output-file.c
index 9852a2ed456..95e21d23dc1 100644
--- a/gas/output-file.c
+++ b/gas/output-file.c
@@ -19,6 +19,7 @@
    02110-1301, USA.  */
 
 #include "as.h"
+#include "subsegs.h"
 #include "output-file.h"
 
 #ifndef TARGET_MACH
@@ -49,23 +50,54 @@ output_file_create (const char *name)
     stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
 }
 
+static void
+stash_frchain_obs (asection *sec)
+{
+  segment_info_type *info = seg_info (sec);
+  if (info)
+    {
+      struct frchain *frchp;
+      for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
+	obstack_ptr_grow (&notes, &frchp->frch_obstack);
+      info->frchainP = NULL;
+    }
+}
+
 void
 output_file_close (const char *filename)
 {
   bool res;
+  bfd *obfd = stdoutput;
+  struct obstack **obs;
+  asection *sec;
 
-  if (stdoutput == NULL)
+  if (obfd == NULL)
     return;
 
+  /* Prevent an infinite loop - if the close failed we will call as_fatal
+     which will call xexit() which may call this function again...  */
+  stdoutput = NULL;
+
+  /* We can't free obstacks attached to the output bfd sections before
+     closing the output bfd since data in those obstacks may need to
+     be accessed, but we can't access anything in the output bfd after
+     it is closed..  */
+  for (sec = obfd->sections; sec; sec = sec->next)
+    stash_frchain_obs (sec);
+  stash_frchain_obs (reg_section);
+  stash_frchain_obs (expr_section);
+  stash_frchain_obs (bfd_abs_section_ptr);
+  stash_frchain_obs (bfd_und_section_ptr);
+  obstack_ptr_grow (&notes, NULL);
+  obs = obstack_finish (&notes);
+
   /* Close the bfd.  */
   if (!flag_always_generate_output && had_errors ())
     res = bfd_cache_close_all ();
   else
-    res = bfd_close (stdoutput);
+    res = bfd_close (obfd);
 
-  /* Prevent an infinite loop - if the close failed we will call as_fatal
-     which will call xexit() which may call this function again...  */
-  stdoutput = NULL;
+  subsegs_end (obs);
 
   if (! res)
     as_fatal ("%s: %s", filename, bfd_errmsg (bfd_get_error ()));
diff --git a/gas/subsegs.c b/gas/subsegs.c
index cb598e84bef..1776511a9b8 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -43,7 +43,27 @@ subsegs_begin (void)
   frchain_now = NULL;		/* Warn new_subseg() that we are booting.  */
   frag_now = &dummy_frag;
 }
+
+void
+subsegs_end (struct obstack **obs)
+{
+  for (; *obs; obs++)
+    _obstack_free (*obs, NULL);
+  _obstack_free (&frchains, NULL);
+  _obstack_free (&cond_obstack, NULL);
+  _obstack_free (&notes, NULL);
+}
 \f
+static void
+alloc_seginfo (segT seg)
+{
+  segment_info_type *seginfo;
+
+  seginfo = obstack_alloc (&notes, sizeof (*seginfo));
+  memset (seginfo, 0, sizeof (*seginfo));
+  seginfo->bfd_section = seg;
+  bfd_set_section_userdata (seg, seginfo);
+}
 /*
  *			subseg_change()
  *
@@ -57,16 +77,11 @@ subsegs_begin (void)
 void
 subseg_change (segT seg, int subseg)
 {
-  segment_info_type *seginfo = seg_info (seg);
   now_seg = seg;
   now_subseg = subseg;
 
-  if (! seginfo)
-    {
-      seginfo = XCNEW (segment_info_type);
-      seginfo->bfd_section = seg;
-      bfd_set_section_userdata (seg, seginfo);
-    }
+  if (!seg_info (seg))
+    alloc_seginfo (seg);
 }
 \f
 static void
@@ -149,7 +164,6 @@ segT
 subseg_get (const char *segname, int force_new)
 {
   segT secptr;
-  segment_info_type *seginfo;
   const char *now_seg_name = now_seg ? bfd_section_name (now_seg) : 0;
 
   if (!force_new
@@ -163,13 +177,10 @@ subseg_get (const char *segname, int force_new)
   else
     secptr = bfd_make_section_anyway (stdoutput, segname);
 
-  seginfo = seg_info (secptr);
-  if (! seginfo)
+  if (!seg_info (secptr))
     {
       secptr->output_section = secptr;
-      seginfo = XCNEW (segment_info_type);
-      seginfo->bfd_section = secptr;
-      bfd_set_section_userdata (secptr, seginfo);
+      alloc_seginfo (secptr);
     }
   return secptr;
 }


                 reply	other threads:[~2022-07-04 13:25 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220704132510.57AA1385E020@sourceware.org \
    --to=amodra@sourceware.org \
    --cc=bfd-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).