diff options
author | Alan Modra <amodra@gmail.com> | 2022-07-04 12:45:47 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2022-07-04 22:51:56 +0930 |
commit | eeeaf705fe1c94e9330fa222d7928a9d0f03832a (patch) | |
tree | edbba8cbb9a0deedb2dda7a037511c9ef2031d1b /gas/output-file.c | |
parent | 0772daccb3ebaf513badf4266e1948454b4455c1 (diff) | |
download | fsf-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.c | 42 |
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 (¬es, &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 (¬es, NULL); + obs = obstack_finish (¬es); + /* 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 ())); |