aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1993-09-07 17:39:56 +0000
committerStan Shebs <shebs@codesourcery.com>1993-09-07 17:39:56 +0000
commit4064305ec08e84f8857e65e3281e389a3dffed45 (patch)
tree405eba3c65bc39c5789ce00caf92c9afe4049cb2 /gas
parentf3e8b15d8e4ac6ff46fefe7ae67dda956285f6cb (diff)
downloadgdb-4064305ec08e84f8857e65e3281e389a3dffed45.zip
gdb-4064305ec08e84f8857e65e3281e389a3dffed45.tar.gz
gdb-4064305ec08e84f8857e65e3281e389a3dffed45.tar.bz2
Changes to support stabs-in-coff
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/obj-coffbfd.c9
-rw-r--r--gas/config/obj-coffbfd.h26
-rw-r--r--gas/read.c456
-rw-r--r--gas/read.h127
-rw-r--r--gas/write.c2
6 files changed, 536 insertions, 95 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1594c4f..cc52c0c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,14 @@
+Tue Sep 7 10:22:52 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * read.c: (s_stab, s_xstab, s_desc): New functions to parse
+ various stab-related directives.
+ * read.h: (s_stab, s_xstab, s_desc): New function prototypes.
+ * write.c: (merge_data_into_text): Fix ifdef tangle.
+ * config/obj-coffbfd.c (current_stab_symbol): Fake symbol
+ for stab reader to use.
+ * config/obj-coffbfdh.h (obj_symbol_type): Added fields for
+ stab reader, macros to access.
+
Fri Sep 3 16:44:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
* config/obj-elf.h (elf_symbol): Fixed name of elf_symbol_type.
diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c
index 301806a..85414ca 100644
--- a/gas/config/obj-coffbfd.c
+++ b/gas/config/obj-coffbfd.c
@@ -31,7 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
Hacked for BFDness by steve chamberlain
- This object module now supports the Hitachi H8/{3|5}00 and the AMD 29k
+ This object module now supports everything but the i960 and i860.
sac@cygnus.com
*/
@@ -80,6 +80,12 @@ const short seg_N_TYPE[] =
int function_lineoff = -1; /* Offset in line#s where the last function
started (the odd entry for line #0) */
+/* This is used along with macros in the .h file to fake the .stabX
+ directive reader into thinking it's working on a real symbol, when
+ it's actually only a temporary that will get converted into a
+ stab-section symbol later. */
+
+symbolS current_stab_symbol;
static symbolS *last_line_symbol;
@@ -149,7 +155,6 @@ void EXFUN (obj_coff_section, (void));
static void EXFUN (tag_init, (void));
static void EXFUN (tag_insert, (char *name, symbolS * symbolP));
-
static struct hash_control *tag_hash;
static symbolS *def_symbol_in_progress = NULL;
diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h
index c96e6bf..9e75f7c 100644
--- a/gas/config/obj-coffbfd.h
+++ b/gas/config/obj-coffbfd.h
@@ -122,10 +122,28 @@ typedef struct
union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES]; /* Auxiliary entry. */
unsigned int ost_flags; /* obj_coff internal use only flags */
+
+ /* For stabs-in-coff. */
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+
}
obj_symbol_type;
+#define S_SET_OFFSET_2(S,V) ((S)->sy_symbol.n_strx = (V))
+#define S_SET_OTHER(S,V) ((S)->sy_symbol.n_other = (V))
+#define S_SET_TYPE(S,T) ((S)->sy_symbol.n_type = (T))
+#define S_SET_DESC(S,D) ((S)->sy_symbol.n_desc = (D))
+#define S_GET_OFFSET_2(S) ((S)->sy_symbol.n_strx)
+#define S_GET_OTHER(S) ((S)->sy_symbol.n_other)
+#define S_GET_TYPE(S) ((S)->sy_symbol.n_type)
+#define S_GET_DESC(S) ((S)->sy_symbol.n_desc)
+
+
#ifndef DO_NOT_STRIP
#define DO_NOT_STRIP 0
#define DO_STRIP 1
@@ -530,4 +548,12 @@ extern SCNHDR text_section_header;
? (S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol)), 0) \
: 0)
+#define SEPARATE_STAB_SECTIONS
+
+#define MAKE_STAB_SYMBOL(SYM, STR, SEC) \
+ { extern symbolS current_stab_symbol; \
+ (SYM) = &current_stab_symbol; \
+ (SYM)->sy_symbol.n_strx = get_stab_string_offset(STR, SEC); \
+ }
+
/* end of obj-coffbfd.h */
diff --git a/gas/read.c b/gas/read.c
index 08d9d81..d8e1206 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -40,13 +40,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h>
#include "as.h"
-#ifdef BFD_ASSEMBLER
#include "subsegs.h"
-#endif
#include "obstack.h"
#include "listing.h"
+/* We need this, despite the apparent object format dependency, since
+ it defines stab types, which all object formats can use now. */
+
+#include "aout/stab_gnu.h"
#ifndef TC_START_LABEL
#define TC_START_LABEL(x,y) (x==':')
@@ -203,6 +205,7 @@ static const pseudo_typeS potable[] =
{"byte", cons, 1},
{"comm", s_comm, 0},
{"data", s_data, 0},
+ {"desc", s_desc, 0},
/* dim */
{"double", float_cons, 'd'},
/* dsect */
@@ -250,6 +253,9 @@ static const pseudo_typeS potable[] =
{"single", float_cons, 'f'},
/* size */
{"space", s_space, 0},
+ {"stabd", s_stab, 'd'},
+ {"stabn", s_stab, 'n'},
+ {"stabs", s_stab, 's'},
{"string", stringer, 1},
/* tag */
{"text", s_text, 0},
@@ -257,6 +263,7 @@ static const pseudo_typeS potable[] =
/* type */
/* use */
/* val */
+ {"xstabs", s_xstab, 's'},
{"word", cons, 2},
{NULL} /* end sentinel */
};
@@ -435,7 +442,12 @@ read_a_source_file (name)
}
- else if (c == '=' || input_line_pointer[1] == '=')
+ else if (c == '='
+ || (input_line_pointer[1] == '='
+#ifdef TC_EQUAL_IN_INSN
+ && ! TC_EQUAL_IN_INSN (c, input_line_pointer)
+#endif
+ ))
{
equals (s);
demand_empty_rest_of_line ();
@@ -508,7 +520,11 @@ read_a_source_file (name)
/* WARNING: c has char, which may be end-of-line. */
/* Also: input_line_pointer->`\0` where c was. */
*input_line_pointer = c;
- while (!is_end_of_line[*input_line_pointer])
+ while (!is_end_of_line[*input_line_pointer]
+#ifdef TC_EOL_IN_INSN
+ || TC_EOL_IN_INSN (input_line_pointer)
+#endif
+ )
{
input_line_pointer++;
}
@@ -837,8 +853,8 @@ s_comm ()
S_SET_EXTERNAL (symbolP);
}
#ifdef OBJ_VMS
- if ( (!temp) || !flagseen['1'])
- S_GET_OTHER(symbolP) = const_flag;
+ if ( (!temp) || !flagseen['1'])
+ S_GET_OTHER(symbolP) = const_flag;
#endif /* not OBJ_VMS */
know (symbolP->sy_frag == &zero_address_frag);
demand_empty_rest_of_line ();
@@ -1701,11 +1717,15 @@ emit_expr (exp, nbytes)
defined, and otherwise uses 0. */
#ifdef BFD_ASSEMBLER
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
+#else
fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
/* @@ Should look at CPU word size. */
nbytes == 2 ? BFD_RELOC_16
: nbytes == 8 ? BFD_RELOC_64
: BFD_RELOC_32);
+#endif
#else
#ifdef TC_CONS_FIX_NEW
TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
@@ -2632,4 +2652,428 @@ s_ignore (arg)
return;
} /* s_ignore() */
+/*
+ * Handle .stabX directives, which used to be open-coded.
+ * So much creeping featurism overloaded the semantics that we decided
+ * to put all .stabX thinking in one place. Here.
+ *
+ * We try to make any .stabX directive legal. Other people's AS will often
+ * do assembly-time consistency checks: eg assigning meaning to n_type bits
+ * and "protecting" you from setting them to certain values. (They also zero
+ * certain bits before emitting symbols. Tut tut.)
+ *
+ * If an expression is not absolute we either gripe or use the relocation
+ * information. Other people's assemblers silently forget information they
+ * don't need and invent information they need that you didn't supply.
+ */
+
+void
+change_to_section (name, len, exp)
+ char *name;
+ unsigned int len;
+ unsigned int exp;
+{
+#ifndef BFD_ASSEMBLER
+ unsigned int i;
+ extern segment_info_type segment_info[];
+
+ /* Find out if we've already got a section of this name etc */
+ for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
+ {
+ if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
+ {
+ subseg_new (i, exp);
+ return;
+ }
+ }
+ /* No section, add one */
+ strncpy (segment_info[i].scnhdr.s_name, name, 8);
+ segment_info[i].scnhdr.s_flags = 0 /* STYP_NOLOAD */;
+ subseg_new (i, exp);
+#endif
+}
+
+/*
+ * Build a string dictionary entry for a .stabX symbol.
+ * The symbol is added to the .<secname>str section.
+ */
+
+static unsigned int
+get_stab_string_offset (string, secname)
+ char *string, *secname;
+{
+ segT save_seg;
+ segT seg;
+ subsegT save_subseg;
+ unsigned int length;
+ unsigned int old_gdb_string_index;
+ char *clengthP;
+ int i;
+ char c;
+ /* @@FIXME -- there should be no static data here!
+ This also has the effect of making all stab string tables large enough
+ to contain all the contents written to any of them. This only matters
+ with the Solaris native compiler for the moment, but it should be fixed
+ anyways. */
+ static unsigned int gdb_string_index = 0;
+
+ old_gdb_string_index = 0;
+ length = strlen (string);
+ clengthP = (char *) &length;
+ if (length > 0)
+ { /* Ordinary case. */
+ save_seg = now_seg;
+ save_subseg = now_subseg;
+
+ /* Create the stabstr sections, if they are not already created. */
+ {
+ char *newsecname = xmalloc (strlen (secname) + 4);
+ strcpy (newsecname, secname);
+ strcat (newsecname, "str");
+#ifdef BFD_ASSEMBLER
+ seg = bfd_get_section_by_name (stdoutput, newsecname);
+ if (seg == 0)
+ {
+ seg = bfd_make_section_old_way (stdoutput, newsecname);
+ bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC);
+ }
+#else
+ change_to_section(newsecname, strlen(newsecname), 0);
+#endif
+/* free (newsecname);*/
+ }
+#ifdef BFD_ASSEMBLER
+ subseg_new ((char *) seg->name, save_subseg);
+#else
+/* subseg_new (seg, save_subseg); */
+#endif
+ old_gdb_string_index = gdb_string_index;
+ i = 0;
+ while ((c = *string++))
+ {
+ i++;
+ gdb_string_index++;
+ FRAG_APPEND_1_CHAR (c);
+ }
+ {
+ FRAG_APPEND_1_CHAR ((char) 0);
+ i++;
+ gdb_string_index++;
+ }
+ while (i % 4 != 0)
+ {
+ FRAG_APPEND_1_CHAR ((char) 0);
+ i++;
+ gdb_string_index++;
+ }
+#ifdef BFD_ASSEMBLER
+ subseg_new ((char *) save_seg->name, save_subseg);
+#else
+/* subseg_new (save_seg, save_subseg); */
+#endif
+ }
+ return old_gdb_string_index;
+}
+
+/* This can handle different kinds of stabs (s,n,d) and different
+ kinds of stab sections. */
+
+static void
+s_stab_generic (what, secname)
+ int what;
+ char *secname;
+{
+ extern int listing;
+
+ symbolS *symbol;
+ char *string;
+ int saved_type = 0;
+ int length;
+ int goof = 0;
+ int seg_is_new = 0;
+ long longint;
+ segT saved_seg = now_seg;
+ segT seg;
+ subsegT saved_subseg = now_subseg;
+ subsegT subseg;
+ int offset;
+ int valu;
+ char *toP;
+
+ valu = ((char *) obstack_next_free (&frags)) - frag_now->fr_literal;
+
+#ifdef SEPARATE_STAB_SECTIONS
+#ifdef BFD_ASSEMBLER
+ seg = bfd_get_section_by_name (stdoutput, secname);
+ if (seg == 0)
+ {
+ seg = subseg_new (secname, 0);
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_READONLY | SEC_ALLOC | SEC_RELOC);
+ subseg_set (saved_seg, subseg);
+ seg_is_new = 1;
+ }
+#else
+ change_to_section (secname, strlen(secname), 0);
+#endif
+#endif /* SEPARATE_STAB_SECTIONS */
+
+ /*
+ * Enter with input_line_pointer pointing past .stabX and any following
+ * whitespace.
+ */
+ if (what == 's')
+ {
+ string = demand_copy_C_string (&length);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_bad ("I need a comma after symbol's name");
+ goof = 1;
+ }
+ }
+ else
+ string = "";
+
+ /*
+ * Input_line_pointer->after ','. String->symbol name.
+ */
+ if (!goof)
+ {
+#ifdef MAKE_STAB_SYMBOL
+ MAKE_STAB_SYMBOL(symbol, string, secname);
+#else
+ symbol = symbol_new (string, undefined_section, 0, (struct frag *) 0);
+#endif
+ /* Make sure that the rest of this is going to work. */
+ if (symbol == NULL)
+ as_fatal ("no stab symbol created");
+
+ switch (what)
+ {
+ case 'd':
+ S_SET_NAME (symbol, NULL); /* .stabd feature. */
+#ifdef STAB_SYMBOL_SET_VALUE
+ STAB_SYMBOL_SET_VALUE (symbol, valu);
+#else
+ S_SET_VALUE (symbol, valu);
+#endif
+#if STAB_SYMBOL_SET_SEGMENT
+#else
+ S_SET_SEGMENT (symbol, now_seg);
+#endif
+ symbol->sy_frag = frag_now;
+ break;
+
+ case 'n':
+ symbol->sy_frag = &zero_address_frag;
+ break;
+
+ case 's':
+ symbol->sy_frag = &zero_address_frag;
+ break;
+
+ default:
+ BAD_CASE (what);
+ break;
+ }
+
+ if (get_absolute_expression_and_terminator (&longint) == ',')
+ {
+ saved_type = longint;
+ S_SET_TYPE (symbol, saved_type);
+ }
+ else
+ {
+ as_bad ("I want a comma after the n_type expression");
+ goof = 1;
+ input_line_pointer--; /* Backup over a non-',' char. */
+ }
+ }
+
+ if (!goof)
+ {
+ if (get_absolute_expression_and_terminator (&longint) == ',')
+ S_SET_OTHER (symbol, longint);
+ else
+ {
+ as_bad ("I want a comma after the n_other expression");
+ goof = 1;
+ input_line_pointer--; /* Backup over a non-',' char. */
+ }
+ }
+
+ if (!goof)
+ {
+ S_SET_DESC (symbol, get_absolute_expression ());
+ if (what == 's' || what == 'n')
+ {
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("I want a comma after the n_desc expression");
+ goof = 1;
+ }
+ else
+ {
+ input_line_pointer++;
+ }
+ }
+ }
+
+ /* Line is messed up - ignore it and get out of here. */
+ if (goof)
+ {
+ ignore_rest_of_line ();
+ subseg_new (saved_seg, saved_subseg);
+ return;
+ }
+
+#ifdef BFD_ASSEMBLER
+ subseg_new ((char *) seg->name, subseg);
+#endif
+
+#if 0 /* needed for elf only? */
+ if (seg_is_new)
+ /* allocate and discard -- filled in later */
+ (void) frag_more (12);
+#endif
+
+#ifdef SEPARATE_STAB_SECTIONS
+ change_to_section(secname, strlen(secname), 0);
+ toP = frag_more (8);
+ /* the string index portion of the stab */
+ md_number_to_chars (toP, (valueT) S_GET_OFFSET_2(symbol), 4);
+ md_number_to_chars (toP + 4, (valueT) S_GET_TYPE(symbol), 1);
+ md_number_to_chars (toP + 5, (valueT) S_GET_OTHER(symbol), 1);
+ md_number_to_chars (toP + 6, (valueT) S_GET_DESC(symbol), 2);
+#endif
+
+#ifdef SEPARATE_STAB_SECTIONS
+ if (what == 's' || what == 'n')
+ {
+ cons (4);
+ input_line_pointer--;
+ }
+ else
+ {
+ char *p = frag_more (4);
+ md_number_to_chars (p, 0, 4);
+ }
+#ifdef BFD_ASSEMBLER
+ subseg_new ((char *) saved_seg->name, subseg);
+#else
+/* subseg_new (saved_seg, subseg); */
+#endif
+#else
+ if (what == 's' || what == 'n')
+ {
+ pseudo_set (symbol);
+ S_SET_TYPE (symbol, saved_type);
+ }
+#endif
+
+#if 0 /* for elf only? */
+ if (what == 's' && S_GET_TYPE (symbol) == N_SO)
+ {
+ fragS *fragp = seg_info (seg)->frchainP->frch_root;
+ while (fragp
+ && fragp->fr_address + fragp->fr_fix < 12)
+ fragp = fragp->fr_next;
+ assert (fragp != 0);
+ assert (fragp->fr_type == rs_fill);
+ assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
+ md_number_to_chars (fragp->fr_literal, (valueT) symbol->sy_name_offset,
+ 4);
+ }
+#endif
+
+#ifndef NO_LISTING
+ if (listing)
+ switch (S_GET_TYPE (symbol))
+ {
+ case N_SLINE:
+ listing_source_line (S_GET_DESC (symbol));
+ break;
+ case N_SO:
+ case N_SOL:
+ listing_source_file (string);
+ break;
+ }
+#endif /* !NO_LISTING */
+
+#ifdef SEPARATE_STAB_SECTIONS
+ subseg_new (saved_seg, saved_subseg);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Regular stab directive. */
+
+void
+s_stab (what)
+ int what;
+{
+ s_stab_generic (what, ".stab");
+}
+
+/* "Extended stabs", used in Solaris only now. */
+
+void
+s_xstab (what)
+ int what;
+{
+ int length;
+ char *secname;
+
+ secname = demand_copy_C_string (&length);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_bad ("comma missing in .xstabs");
+ ignore_rest_of_line ();
+ return;
+ }
+ s_stab_generic (what, secname);
+}
+
+/* Frob invented at RMS' request. Set the n_desc of a symbol. */
+
+void
+s_desc ()
+{
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad ("Expected comma after name \"%s\"", name);
+ *p = c;
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ S_SET_DESC (symbolP, temp);
+ }
+ demand_empty_rest_of_line ();
+} /* s_desc() */
+
/* end of read.c */
diff --git a/gas/read.h b/gas/read.h
index d625b2d..604ee4c 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -53,91 +53,46 @@ extern const char comment_chars[];
extern const char line_comment_chars[];
extern const char line_separator_chars[];
-#if __STDC__ == 1
-
-char *demand_copy_C_string (int *len_pointer);
-char get_absolute_expression_and_terminator (long *val_pointer);
-long get_absolute_expression (void);
-void add_include_dir (char *path);
-void big_cons (int nbytes);
-void cons (unsigned int nbytes);
-void demand_empty_rest_of_line (void);
-void equals (char *sym_name);
-void float_cons (int float_type);
-void ignore_rest_of_line (void);
-void pseudo_set (symbolS * symbolP);
-void read_a_source_file (char *name);
-void read_begin (void);
-void s_abort (void);
-void s_align_bytes (int arg);
-void s_align_ptwo (void);
-void s_app_file (void);
-/* void s_bss(void); -- unneeded; always static when used */
-void s_comm (void);
-void s_data (void);
-void s_else (int arg);
-void s_end (int arg);
-void s_endif (int arg);
-void s_fill (void);
-void s_globl (void);
-void s_if (int arg);
-void s_ifdef (int arg);
-void s_ifeqs (int arg);
-void s_ignore (int arg);
-void s_include (int arg);
-void s_lcomm (int needs_align);
-void s_lsym (void);
-void s_org (void);
-void s_set (void);
-void s_space (int mult);
-void s_text (void);
-
-#else /* not __STDC__ */
-
-char *demand_copy_C_string ();
-char get_absolute_expression_and_terminator ();
-long get_absolute_expression ();
-void add_include_dir ();
-void big_cons ();
-void cons ();
-void demand_empty_rest_of_line ();
-void equals ();
-void float_cons ();
-void ignore_rest_of_line ();
-void pseudo_set ();
-void read_a_source_file ();
-void read_begin ();
-void s_abort ();
-void s_align_bytes ();
-void s_align_ptwo ();
-void s_app_file ();
-/* void s_bss(); -- unneeded; always static when used */
-void s_comm ();
-void s_data ();
-void s_else ();
-void s_end ();
-void s_endif ();
-void s_fill ();
-void s_globl ();
-void s_if ();
-void s_ifdef ();
-void s_ifeqs ();
-void s_ignore ();
-void s_include ();
-void s_lcomm ();
-void s_lsym ();
-void s_org ();
-void s_set ();
-void s_space ();
-void s_text ();
-
-#endif /* not __STDC__ */
-
-/*
- * Local Variables:
- * comment-column: 0
- * fill-column: 131
- * End:
- */
+char *demand_copy_C_string PARAMS ((int *len_pointer));
+char get_absolute_expression_and_terminator PARAMS ((long *val_pointer));
+long get_absolute_expression PARAMS ((void));
+void add_include_dir PARAMS ((char *path));
+void big_cons PARAMS ((int nbytes));
+void cons PARAMS ((unsigned int nbytes));
+void demand_empty_rest_of_line PARAMS ((void));
+void emit_expr PARAMS ((expressionS *exp, unsigned int nbytes));
+void equals PARAMS ((char *sym_name));
+void float_cons PARAMS ((int float_type));
+void ignore_rest_of_line PARAMS ((void));
+void pseudo_set PARAMS ((symbolS * symbolP));
+void read_a_source_file PARAMS ((char *name));
+void read_begin PARAMS ((void));
+void s_abort PARAMS ((void));
+void s_align_bytes PARAMS ((int arg));
+void s_align_ptwo PARAMS ((void));
+void s_app_file PARAMS ((int));
+void s_app_line PARAMS ((void));
+void s_comm PARAMS ((void));
+void s_data PARAMS ((void));
+void s_desc PARAMS ((void));
+void s_else PARAMS ((int arg));
+void s_end PARAMS ((int arg));
+void s_endif PARAMS ((int arg));
+void s_fill PARAMS ((void));
+void s_globl PARAMS ((void));
+void s_if PARAMS ((int arg));
+void s_ifdef PARAMS ((int arg));
+void s_ifeqs PARAMS ((int arg));
+void s_ignore PARAMS ((int arg));
+void s_include PARAMS ((int arg));
+void s_lcomm PARAMS ((int needs_align));
+void s_lsym PARAMS ((void));
+void s_org PARAMS ((void));
+void s_set PARAMS ((void));
+void s_space PARAMS ((int mult));
+void s_stab PARAMS ((int what));
+void s_text PARAMS ((void));
+void stringer PARAMS ((int append_zero));
+void s_xstab PARAMS ((int what));
/* end of read.h */
diff --git a/gas/write.c b/gas/write.c
index 953e613..2e7ae83 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -750,7 +750,7 @@ write_contents (abfd, sec, xxx)
static void
merge_data_into_text ()
{
-#ifdef BFD_ASSEMBLER
+#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)
seg_info (text_section)->frchainP->frch_last->fr_next =
seg_info (data_section)->frchainP->frch_root;
seg_info (text_section)->frchainP->frch_last =