mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 23:23:09 +00:00
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.
This commit is contained in:
1
gas/as.h
1
gas/as.h
@@ -476,6 +476,7 @@ void input_scrub_end (void);
|
|||||||
void new_logical_line (const char *, int);
|
void new_logical_line (const char *, int);
|
||||||
void new_logical_line_flags (const char *, int, int);
|
void new_logical_line_flags (const char *, int, int);
|
||||||
void subsegs_begin (void);
|
void subsegs_begin (void);
|
||||||
|
void subsegs_end (struct obstack **);
|
||||||
void subseg_change (segT, int);
|
void subseg_change (segT, int);
|
||||||
segT subseg_new (const char *, subsegT);
|
segT subseg_new (const char *, subsegT);
|
||||||
segT subseg_force_new (const char *, subsegT);
|
segT subseg_force_new (const char *, subsegT);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
02110-1301, USA. */
|
02110-1301, USA. */
|
||||||
|
|
||||||
#include "as.h"
|
#include "as.h"
|
||||||
|
#include "subsegs.h"
|
||||||
#include "output-file.h"
|
#include "output-file.h"
|
||||||
|
|
||||||
#ifndef TARGET_MACH
|
#ifndef TARGET_MACH
|
||||||
@@ -49,24 +50,55 @@ output_file_create (const char *name)
|
|||||||
stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
|
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
|
void
|
||||||
output_file_close (const char *filename)
|
output_file_close (const char *filename)
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
|
bfd *obfd = stdoutput;
|
||||||
|
struct obstack **obs;
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
if (stdoutput == NULL)
|
if (obfd == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Close the bfd. */
|
|
||||||
if (!flag_always_generate_output && had_errors ())
|
|
||||||
res = bfd_cache_close_all ();
|
|
||||||
else
|
|
||||||
res = bfd_close (stdoutput);
|
|
||||||
|
|
||||||
/* Prevent an infinite loop - if the close failed we will call as_fatal
|
/* Prevent an infinite loop - if the close failed we will call as_fatal
|
||||||
which will call xexit() which may call this function again... */
|
which will call xexit() which may call this function again... */
|
||||||
stdoutput = NULL;
|
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 (obfd);
|
||||||
|
|
||||||
|
subsegs_end (obs);
|
||||||
|
|
||||||
if (! res)
|
if (! res)
|
||||||
as_fatal ("%s: %s", filename, bfd_errmsg (bfd_get_error ()));
|
as_fatal ("%s: %s", filename, bfd_errmsg (bfd_get_error ()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,27 @@ subsegs_begin (void)
|
|||||||
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
|
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
|
||||||
frag_now = &dummy_frag;
|
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 (¬es, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
alloc_seginfo (segT seg)
|
||||||
|
{
|
||||||
|
segment_info_type *seginfo;
|
||||||
|
|
||||||
|
seginfo = obstack_alloc (¬es, sizeof (*seginfo));
|
||||||
|
memset (seginfo, 0, sizeof (*seginfo));
|
||||||
|
seginfo->bfd_section = seg;
|
||||||
|
bfd_set_section_userdata (seg, seginfo);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* subseg_change()
|
* subseg_change()
|
||||||
*
|
*
|
||||||
@@ -57,16 +77,11 @@ subsegs_begin (void)
|
|||||||
void
|
void
|
||||||
subseg_change (segT seg, int subseg)
|
subseg_change (segT seg, int subseg)
|
||||||
{
|
{
|
||||||
segment_info_type *seginfo = seg_info (seg);
|
|
||||||
now_seg = seg;
|
now_seg = seg;
|
||||||
now_subseg = subseg;
|
now_subseg = subseg;
|
||||||
|
|
||||||
if (! seginfo)
|
if (!seg_info (seg))
|
||||||
{
|
alloc_seginfo (seg);
|
||||||
seginfo = XCNEW (segment_info_type);
|
|
||||||
seginfo->bfd_section = seg;
|
|
||||||
bfd_set_section_userdata (seg, seginfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -149,7 +164,6 @@ segT
|
|||||||
subseg_get (const char *segname, int force_new)
|
subseg_get (const char *segname, int force_new)
|
||||||
{
|
{
|
||||||
segT secptr;
|
segT secptr;
|
||||||
segment_info_type *seginfo;
|
|
||||||
const char *now_seg_name = now_seg ? bfd_section_name (now_seg) : 0;
|
const char *now_seg_name = now_seg ? bfd_section_name (now_seg) : 0;
|
||||||
|
|
||||||
if (!force_new
|
if (!force_new
|
||||||
@@ -163,13 +177,10 @@ subseg_get (const char *segname, int force_new)
|
|||||||
else
|
else
|
||||||
secptr = bfd_make_section_anyway (stdoutput, segname);
|
secptr = bfd_make_section_anyway (stdoutput, segname);
|
||||||
|
|
||||||
seginfo = seg_info (secptr);
|
if (!seg_info (secptr))
|
||||||
if (! seginfo)
|
|
||||||
{
|
{
|
||||||
secptr->output_section = secptr;
|
secptr->output_section = secptr;
|
||||||
seginfo = XCNEW (segment_info_type);
|
alloc_seginfo (secptr);
|
||||||
seginfo->bfd_section = secptr;
|
|
||||||
bfd_set_section_userdata (secptr, seginfo);
|
|
||||||
}
|
}
|
||||||
return secptr;
|
return secptr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user