aboutsummaryrefslogtreecommitdiff
path: root/gas/output-file.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-07-04 12:45:47 +0930
committerAlan Modra <amodra@gmail.com>2022-07-04 22:51:56 +0930
commiteeeaf705fe1c94e9330fa222d7928a9d0f03832a (patch)
treeedbba8cbb9a0deedb2dda7a037511c9ef2031d1b /gas/output-file.c
parent0772daccb3ebaf513badf4266e1948454b4455c1 (diff)
downloadfsf-binutils-gdb-eeeaf705fe1c94e9330fa222d7928a9d0f03832a.zip
fsf-binutils-gdb-eeeaf705fe1c94e9330fa222d7928a9d0f03832a.tar.gz
fsf-binutils-gdb-eeeaf705fe1c94e9330fa222d7928a9d0f03832a.tar.bz2
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.
Diffstat (limited to 'gas/output-file.c')
-rw-r--r--gas/output-file.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/gas/output-file.c b/gas/output-file.c
index 9852a2e..95e21d2 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 ()));