You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
* Segments & sub-segments.
frchainS *frchain_root, *frchain_now;
+static struct obstack frchains;
+
#ifndef BFD_ASSEMBLER
#ifdef MANY_SEGMENTS
segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
frchainS *data0_frchainP, *bss0_frchainP;
#endif /* MANY_SEGMENTS */
-char *const seg_name[] =
+char const *const seg_name[] =
{
"absolute",
#ifdef MANY_SEGMENTS
#endif /* BFD_ASSEMBLER */
static void subseg_set_rest PARAMS ((segT, subsegT));
+
+static fragS dummy_frag;
+
+static frchainS absolute_frchain;
\f
void
subsegs_begin ()
know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
#endif
- obstack_begin (&frags, 5000);
+ obstack_begin (&frchains, chunksize);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
+#endif
+
frchain_root = NULL;
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
- /* Fake up 1st frag. It won't be used=> is ok if obstack...
- pads the end of it for alignment. */
- frag_now = (fragS *) obstack_alloc (&frags, SIZEOF_STRUCT_FRAG);
- memset (frag_now, 0, SIZEOF_STRUCT_FRAG);
+
+ frag_now = &dummy_frag;
#ifndef BFD_ASSEMBLER
- /* This 1st frag will not be in any frchain.
- We simply give subseg_new somewhere to scribble. */
now_subseg = 42; /* Lie for 1st call to subseg_new. */
#ifdef MANY_SEGMENTS
{
#endif /* ! MANY_SEGMENTS */
#endif /* ! BFD_ASSEMBLER */
+ absolute_frchain.frch_seg = absolute_section;
+ absolute_frchain.frch_subseg = 0;
+ absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
+ absolute_frchain.frch_frag_now = &zero_address_frag;
+ absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
}
\f
/*
now_seg = seg;
now_subseg = subseg;
+ if (now_seg == absolute_section)
+ return;
+
#ifdef BFD_ASSEMBLER
{
segment_info_type *seginfo;
if (! seginfo)
{
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
- if (! seginfo)
- abort ();
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
seginfo->fix_root = NULL;
seginfo->fix_tail = NULL;
seginfo->bfd_section = seg;
register fragS *former_last_fragP;
register fragS *new_fragP;
- if (frag_now) /* If not bootstrapping. */
+ mri_common_symbol = NULL;
+
+ if (frag_now && frchain_now)
+ frchain_now->frch_frag_now = frag_now;
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || now_seg == absolute_section
+ || frchain_now->frch_last == frag_now);
+
+ subseg_change (seg, (int) subseg);
+
+ if (seg == absolute_section)
{
- frag_now->fr_fix = (char*) obstack_next_free (&frags) - frag_now->fr_literal;
- frag_wane (frag_now); /* Close off any frag in old subseg. */
+ frchain_now = &absolute_frchain;
+ frag_now = &zero_address_frag;
+ return;
}
- /*
- * It would be nice to keep an obstack for each subsegment, if we swap
- * subsegments a lot. Hence we would have much fewer frag_wanes().
- */
- {
- obstack_finish (&frags);
- /*
- * If we don't do the above, the next object we put on obstack frags
- * will appear to start at the fr_literal of the current frag.
- * Also, above ensures that the next object will begin on a
- * address that is aligned correctly for the engine that runs
- * this program.
- */
- }
- subseg_change (seg, (int) subseg);
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || frchain_now->frch_last == frag_now);
+
/*
* Attempt to find or make a frchain for that sub seg.
* Crawl along chain of frchainSs, begins @ frchain_root.
* position of chain rooted in frchain_root.
*/
for (frcP = *(lastPP = &frchain_root);
- frcP && (int) (frcP->frch_seg) <= (int) seg;
+ frcP && frcP->frch_seg <= seg;
frcP = *(lastPP = &frcP->frch_next))
{
- if ((int) (frcP->frch_seg) == (int) seg
+ if (frcP->frch_seg == seg
&& frcP->frch_subseg >= subseg)
{
break;
*
*/
if (!frcP
- || ((int) (frcP->frch_seg) > (int) seg
+ || (frcP->frch_seg > seg
|| frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
{
/*
* This should be the only code that creates a frchainS.
*/
- newP = (frchainS *) obstack_alloc (&frags, sizeof (frchainS));
- memset (newP, 0, sizeof (frchainS));
- /* This begines on a good boundary because a obstack_done()
- preceeded it. It implies an obstack_done(), so we expect
- the next object allocated to begin on a correct boundary. */
- *lastPP = newP;
- newP->frch_next = frcP; /* perhaps NULL */
- (frcP = newP)->frch_subseg = subseg;
+ extern fragS *frag_alloc ();
+ newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
+ newP->frch_subseg = subseg;
newP->frch_seg = seg;
- newP->frch_last = NULL;
#ifdef BFD_ASSEMBLER
newP->fix_root = NULL;
newP->fix_tail = NULL;
#endif
+ obstack_begin (&newP->frch_obstack, 5000);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
+#endif
+ newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
+ newP->frch_frag_now->fr_type = rs_fill;
+
+ newP->frch_root = newP->frch_last = newP->frch_frag_now;
+
+ *lastPP = newP;
+ newP->frch_next = frcP; /* perhaps NULL */
+ frcP = newP;
}
/*
- * Here with frcP ->ing to the frchainS for subseg.
+ * Here with frcP pointing to the frchainS for subseg.
*/
frchain_now = frcP;
- /*
- * Make a fresh frag for the subsegment.
- */
- /* We expect this to happen on a correct boundary since it was
- proceeded by a obstack_done(). */
- tmp = obstack_alignment_mask (&frags); /* JF disable alignment */
- obstack_alignment_mask (&frags) = 0;
- frag_now = (fragS *) obstack_alloc (&frags, SIZEOF_STRUCT_FRAG);
- memset (frag_now, 0, SIZEOF_STRUCT_FRAG);
- obstack_alignment_mask (&frags) = tmp;
- /* But we want any more chars to come immediately after the
- structure we just made. */
- new_fragP = frag_now;
- new_fragP->fr_next = NULL;
- /*
- * Append new frag to current frchain.
- */
- former_last_fragP = frcP->frch_last;
- if (former_last_fragP)
- {
- know (former_last_fragP->fr_next == NULL);
- know (frchain_now->frch_root);
- former_last_fragP->fr_next = new_fragP;
- }
- else
- {
- frcP->frch_root = new_fragP;
- }
- frcP->frch_last = new_fragP;
+ frag_now = frcP->frch_frag_now;
+
+ assert (frchain_now->frch_last == frag_now);
}
/*
register subsegT subseg;
{
#ifndef MANY_SEGMENTS
- know (seg == SEG_DATA || seg == SEG_TEXT || seg == SEG_BSS);
+ know (seg == SEG_DATA
+ || seg == SEG_TEXT
+ || seg == SEG_BSS
+ || seg == SEG_ABSOLUTE);
#endif
if (seg != now_seg || subseg != now_subseg)
{ /* we just changed sub-segments */
subseg_set_rest (seg, subseg);
}
+ mri_common_symbol = NULL;
}
#else /* BFD_ASSEMBLER */
if (secptr->output_section != secptr)
secptr->output_section = secptr;
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
- memset ((char *) seginfo, 0, sizeof(seginfo));
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
seginfo->fix_root = NULL;
seginfo->fix_tail = NULL;
seginfo->bfd_section = secptr;
{
if (! (secptr == now_seg && subseg == now_subseg))
subseg_set_rest (secptr, subseg);
+ mri_common_symbol = NULL;
}
#ifndef obj_sec_sym_ok_for_reloc
s = symbol_find (sec->name);
if (!s)
{
- s = symbol_new (sec->name, sec, 0, &zero_address_frag);
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+ if (! EMIT_SECTION_SYMBOLS
+#ifdef BFD_ASSEMBLER
+ && symbol_table_frozen
+#endif
+ )
+ /* Here we know it won't be going into the symbol table. */
+ s = symbol_create (sec->name, sec, 0, &zero_address_frag);
+ else
+ s = symbol_new (sec->name, sec, 0, &zero_address_frag);
S_CLEAR_EXTERNAL (s);
/* Use the BFD section symbol, if possible. */