/* subsegs.c - subsegments -
- Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
+ Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
"register",
"",
}; /* Used by error reporters, dumpers etc. */
+#else /* BFD_ASSEMBLER */
+
+/* Gas segment information for bfd_abs_section_ptr and
+ bfd_und_section_ptr. */
+static segment_info_type *abs_seg_info;
+static segment_info_type *und_seg_info;
+
#endif /* BFD_ASSEMBLER */
static void subseg_set_rest PARAMS ((segT, subsegT));
/* 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, SIZEOF_STRUCT_FRAG, 0);
+ memset (frag_now, 0, SIZEOF_STRUCT_FRAG);
#ifndef BFD_ASSEMBLER
/* This 1st frag will not be in any frchain.
if (! seginfo)
{
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
- if (! seginfo)
- abort ();
- seginfo->fix_root = 0;
- seginfo->fix_tail = 0;
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
seginfo->bfd_section = seg;
seginfo->sym = 0;
- bfd_set_section_userdata (stdoutput, seg, (char *) seginfo);
+ if (seg == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (seg == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
}
}
#else
* 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, sizeof (frchainS), 0);
+ 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. */
(frcP = newP)->frch_subseg = subseg;
newP->frch_seg = seg;
newP->frch_last = NULL;
+#ifdef BFD_ASSEMBLER
+ newP->fix_root = NULL;
+ newP->fix_tail = NULL;
+#endif
}
/*
* Here with frcP ->ing to the frchainS for subseg.
seginfo = seg_info (secptr);
if (! seginfo)
{
- secptr->output_section = secptr;
+ /* Check whether output_section is set first because secptr may
+ be bfd_abs_section_ptr. */
+ if (secptr->output_section != secptr)
+ secptr->output_section = secptr;
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
- seginfo->fix_root = 0;
- seginfo->fix_tail = 0;
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
seginfo->bfd_section = secptr;
- bfd_set_section_userdata (stdoutput, secptr, (char *) seginfo);
- seginfo->frchainP = 0;
- seginfo->lineno_list_head = seginfo->lineno_list_tail = 0;
- seginfo->sym = 0;
- seginfo->dot = 0;
- seginfo->hadone = 0;
- seginfo->user_stuff = 0;
- seginfo->stabu.stab_string_size = 0;
+ if (secptr == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (secptr == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
+ seginfo->frchainP = NULL;
+ seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
+ seginfo->sym = NULL;
+ seginfo->dot = NULL;
}
return secptr;
}
subseg_set_rest (secptr, subseg);
}
+#ifndef obj_sec_sym_ok_for_reloc
+#define obj_sec_sym_ok_for_reloc(SEC) 0
+#endif
+
+/* Get the gas information we are storing for a section. */
+
+segment_info_type *
+seg_info (sec)
+ segT sec;
+{
+ if (sec == bfd_abs_section_ptr)
+ return abs_seg_info;
+ else if (sec == bfd_und_section_ptr)
+ return und_seg_info;
+ else
+ return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
+}
+
symbolS *
section_symbol (sec)
segT sec;
{
segment_info_type *seginfo = seg_info (sec);
+ symbolS *s;
if (seginfo == 0)
abort ();
if (seginfo->sym)
return seginfo->sym;
- seginfo->sym = symbol_find (sec->name);
- if (!seginfo->sym)
+ s = symbol_find (sec->name);
+ if (!s)
{
- seginfo->sym = symbol_make (sec->name);
- seginfo->sym->bsym = sec->symbol;
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+ if (EMIT_SECTION_SYMBOLS
+#ifdef BFD_ASSEMBLER
+ && symbol_table_frozen
+#endif
+ )
+ s = symbol_new (sec->name, sec, 0, &zero_address_frag);
+ else
+ s = symbol_create (sec->name, sec, 0, &zero_address_frag);
+ S_CLEAR_EXTERNAL (s);
+
+ /* Use the BFD section symbol, if possible. */
+ if (obj_sec_sym_ok_for_reloc (sec))
+ s->bsym = sec->symbol;
}
- return seginfo->sym;
+ seginfo->sym = s;
+ return s;
}
#endif /* BFD_ASSEMBLER */